]> git.saurik.com Git - apple/configd.git/commitdiff
configd-596.12.tar.gz os-x-109 os-x-1091 v596.12
authorApple <opensource@apple.com>
Tue, 29 Oct 2013 00:03:35 +0000 (00:03 +0000)
committerApple <opensource@apple.com>
Tue, 29 Oct 2013 00:03:35 +0000 (00:03 +0000)
171 files changed:
IPMonitorLogging.mobileconfig [new file with mode: 0644]
Makefile
Plugins/IPMonitor/Info.plist
Plugins/IPMonitor/Makefile
Plugins/IPMonitor/com.apple.networking.IPMonitor [new file with mode: 0644]
Plugins/IPMonitor/dns-configuration.c
Plugins/IPMonitor/dns-configuration.h
Plugins/IPMonitor/ip_plugin.c
Plugins/IPMonitor/ip_plugin.h [new file with mode: 0644]
Plugins/IPMonitor/proxy-configuration.c
Plugins/IPMonitor/proxy-configuration.h
Plugins/IPMonitor/set-hostname.c
Plugins/IPMonitor/set-hostname.h
Plugins/IPMonitor/smb-configuration.c
Plugins/IPMonitor/smb-configuration.h
Plugins/IPMonitor/test_ipv4_routelist_filter.sh
Plugins/IPMonitor/test_ipv4_routelist_reference.txt
Plugins/IPMonitor/test_reference.sh
Plugins/InterfaceNamer/Info.plist
Plugins/InterfaceNamer/ifnamer.c
Plugins/KernelEventMonitor/Info.plist
Plugins/KernelEventMonitor/ev_dlil.c
Plugins/KernelEventMonitor/ev_dlil.h
Plugins/KernelEventMonitor/ev_ipv4.h
Plugins/KernelEventMonitor/ev_ipv6.c
Plugins/KernelEventMonitor/ev_ipv6.h
Plugins/KernelEventMonitor/eventmon.c
Plugins/KernelEventMonitor/eventmon.h
Plugins/LinkConfiguration/Info.plist
Plugins/LinkConfiguration/linkconfig.c
Plugins/Logger/Info-Embedded.plist
Plugins/Logger/Info.plist
Plugins/Logger/logger.c
Plugins/PreferencesMonitor/Info.plist
Plugins/PreferencesMonitor/prefsmon.c
Plugins/SCNetworkReachability/Info.plist
Plugins/SimulatorSupport/Info.plist [new file with mode: 0644]
Plugins/SimulatorSupport/simulator_support.c [new file with mode: 0644]
Plugins/common/IPMonitorControlPrefs.c [new file with mode: 0644]
Plugins/common/IPMonitorControlPrefs.h [new file with mode: 0644]
SCMonitor/Info.plist
SCMonitor/monitor.c
SystemConfiguration.fproj/BondConfiguration.c
SystemConfiguration.fproj/BridgeConfiguration.c
SystemConfiguration.fproj/CaptiveNetwork.c
SystemConfiguration.fproj/CaptiveNetwork.h
SystemConfiguration.fproj/English.lproj/NetworkInterface.strings
SystemConfiguration.fproj/Info-Embedded.plist
SystemConfiguration.fproj/Info.plist
SystemConfiguration.fproj/LinkConfiguration.c
SystemConfiguration.fproj/LinkConfiguration.h [deleted file]
SystemConfiguration.fproj/SCD.c
SystemConfiguration.fproj/SCDNotifierInformViaCallback.c
SystemConfiguration.fproj/SCDOpen.c
SystemConfiguration.fproj/SCDPlugin.c
SystemConfiguration.fproj/SCDPrivate.c
SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h
SystemConfiguration.fproj/SCDynamicStoreInternal.h
SystemConfiguration.fproj/SCDynamicStorePrivate.h
SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
SystemConfiguration.fproj/SCNetworkConnection.c
SystemConfiguration.fproj/SCNetworkConnectionInternal.h [new file with mode: 0644]
SystemConfiguration.fproj/SCNetworkConnectionPrivate.c
SystemConfiguration.fproj/SCNetworkConnectionPrivate.h
SystemConfiguration.fproj/SCNetworkInterface.c
SystemConfiguration.fproj/SCNetworkReachability.c
SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
SystemConfiguration.fproj/SCNetworkService.c
SystemConfiguration.fproj/SCNetworkSet.c
SystemConfiguration.fproj/SCNetworkSignature.c
SystemConfiguration.fproj/SCNetworkSignature.h
SystemConfiguration.fproj/SCNetworkSignaturePrivate.h
SystemConfiguration.fproj/SCPCommit.c
SystemConfiguration.fproj/SCPOpen.c
SystemConfiguration.fproj/SCPPath.c
SystemConfiguration.fproj/SCPreferencesInternal.h
SystemConfiguration.fproj/SCPreferencesPrivate.h
SystemConfiguration.fproj/SCPrivate.h
SystemConfiguration.fproj/SCProxies.c
SystemConfiguration.fproj/SCSchemaDefinitions.c
SystemConfiguration.fproj/SCSchemaDefinitions.h
SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h
SystemConfiguration.fproj/SNHelper.c [new file with mode: 0644]
SystemConfiguration.fproj/SNHelperPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/SystemConfiguration.h
SystemConfiguration.fproj/VLANConfiguration.c
SystemConfiguration.fproj/VPNAppLayer.c [new file with mode: 0644]
SystemConfiguration.fproj/VPNAppLayerPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/VPNConfiguration.c
SystemConfiguration.fproj/VPNConfiguration.h
SystemConfiguration.fproj/VPNFlow.c [new file with mode: 0644]
SystemConfiguration.fproj/VPNFlow.h [new file with mode: 0644]
SystemConfiguration.fproj/VPNFlowPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/VPNPrivate.c
SystemConfiguration.fproj/VPNService.c [new file with mode: 0644]
SystemConfiguration.fproj/VPNTunnel.c
SystemConfiguration.fproj/VPNTunnel.h
SystemConfiguration.fproj/VPNTunnelPrivate.h
SystemConfiguration.fproj/config_types.h
SystemConfiguration.fproj/dy_framework.c
SystemConfiguration.fproj/dy_framework.h
SystemConfiguration.fproj/genSCPreferences.c
SystemConfiguration.fproj/helper/SCHelper_server.c
SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist
SystemConfiguration.fproj/helper/com.apple.SCHelper.plist
SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_client.c
SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_server.c
SystemConfiguration.fproj/reachability/rb.c [deleted file]
SystemConfiguration.fproj/reachability/rb.h [deleted file]
SystemConfiguration.fproj/scprefs_observer.c [new file with mode: 0644]
SystemConfiguration.fproj/scprefs_observer.h [new file with mode: 0644]
SystemConfiguration.fproj/update-headers
configd.tproj/_SCD.c
configd.tproj/_configadd.c
configd.tproj/_configclose.c
configd.tproj/_confignotify.c
configd.tproj/_configremove.c
configd.tproj/_configset.c
configd.tproj/_notifyremove.c
configd.tproj/com.apple.configd.plist
configd.tproj/com.apple.configd_sim.plist [new file with mode: 0644]
configd.tproj/configd.8
configd.tproj/configd.m
configd.tproj/configd_server.c
configd.tproj/entitlements.plist
configd.tproj/pattern.c
configd.tproj/pattern.h
configd.tproj/plugin_support.c
configd.tproj/session.c
configd.tproj/session.h
configd.xcodeproj/project.pbxproj
dnsinfo/dnsinfo.h
dnsinfo/dnsinfo_copy.c
dnsinfo/dnsinfo_create.c
dnsinfo/dnsinfo_create.h
dnsinfo/dnsinfo_flatfile.c
dnsinfo/dnsinfo_internal.h [new file with mode: 0644]
dnsinfo/dnsinfo_private.c [deleted file]
dnsinfo/dnsinfo_private.h
dnsinfo/dnsinfo_server.c
dnsinfo/dnsinfo_server.h
dnsinfo/shared_dns_info.defs [deleted file]
dnsinfo/shared_dns_info_types.h [deleted file]
get-mobility-info
libSystemConfiguration/libSystemConfiguration_client.c [new file with mode: 0644]
libSystemConfiguration/libSystemConfiguration_client.h [new file with mode: 0644]
libSystemConfiguration/libSystemConfiguration_server.c [new file with mode: 0644]
libSystemConfiguration/libSystemConfiguration_server.h [new file with mode: 0644]
nwi/network_information.c
nwi/network_information.h
nwi/network_information_priv.c
nwi/network_information_priv.h
nwi/network_information_server.c [new file with mode: 0644]
nwi/network_information_server.h [new file with mode: 0644]
scselect.tproj/scselect.c
scutil.tproj/cache.c
scutil.tproj/nc.c
scutil.tproj/net_interface.c
scutil.tproj/net_set.c
scutil.tproj/notifications.c
scutil.tproj/prefs.c
scutil.tproj/prefs.h
scutil.tproj/scutil.8
scutil.tproj/scutil.c
scutil.tproj/scutil.h
scutil.tproj/tests.c
scutil.tproj/tests.h
tests/Makefile [new file with mode: 0644]
tests/ReachabilityTester.c [new file with mode: 0644]

diff --git a/IPMonitorLogging.mobileconfig b/IPMonitorLogging.mobileconfig
new file mode 100644 (file)
index 0000000..6599da7
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>PayloadContent</key>
+       <array>
+               <dict>
+                       <key>PayloadDescription</key>
+                       <string>Enables IPMonitor verbose logging.</string>
+                       <key>PayloadDisplayName</key>
+                       <string>IPMonitor Logging</string>
+                       <key>PayloadIdentifier</key>
+                       <string>com.apple.defaults.managed.IPMonitor.control</string>
+                       <key>PayloadOrganization</key>
+                       <string>Apple, Inc</string>
+                       <key>PayloadType</key>
+                       <string>com.apple.defaults.managed</string>
+                       <key>PayloadUUID</key>
+                       <string>CA2DD325-2123-487C-BF89-170AF64FD8C0</string>
+                       <key>PayloadVersion</key>
+                       <integer>1</integer>
+                       <key>PayloadContent</key>
+                       <array>
+                               <dict>
+                                       <key>DefaultsDomainName</key>
+                                       <string>com.apple.IPMonitor.control</string>
+                                       <key>DefaultsData</key>
+                                       <dict>
+                                               <key>Verbose</key>
+                                               <true/>
+                                       </dict>
+                               </dict>
+                       </array>
+               </dict>
+       </array>
+       <key>PayloadDescription</key>
+       <string>Enables IPMonitor verbose logging.</string>
+       <key>PayloadDisplayName</key>
+       <string>IPMonitor Logging</string>
+       <key>PayloadIdentifier</key>
+       <string>com.apple.IPMonitor.control</string>
+       <key>PayloadOrganization</key>
+       <string>Apple, Inc</string>
+       <key>PayloadType</key>
+       <string>Configuration</string>
+       <key>PayloadUUID</key>
+       <string>CA2DD325-2123-487C-BF89-170AF64FD8C0</string>
+       <key>PayloadVersion</key>
+       <integer>1</integer>
+</dict>
+</plist>
index af81588b7b52bc164ebd8520d91e9bff4b43f65a..79147d2e00ac266f5efef7d21d906e64a9bc3efa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -43,6 +43,8 @@ LION_CFLAGS+=-D__MAC_10_8=1070
 LION_CFLAGS+=-D__AVAILABILITY_INTERNAL__MAC_10_8=__attribute__((visibility(\\\"default\\\")))
 LION_CFLAGS+=-DHAVE_REACHABILITY_SERVER=YES
 
 LION_CFLAGS+=-D__AVAILABILITY_INTERNAL__MAC_10_8=__attribute__((visibility(\\\"default\\\")))
 LION_CFLAGS+=-DHAVE_REACHABILITY_SERVER=YES
 
+LION_SDKROOT=$(shell xcodebuild -version -sdk macosx10.7internal Path)
+
 lion :
        /usr/local/bin/buildit .                                \
          -noinstallsrc -noinstallhdrs -noverify -nosum         \
 lion :
        /usr/local/bin/buildit .                                \
          -noinstallsrc -noinstallhdrs -noverify -nosum         \
@@ -52,4 +54,6 @@ lion :
          -configuration Debug                                  \
          -release $(shell cat /usr/share/buildit/.releaseName) \
          -othercflags "$(LION_CFLAGS)"                         \
          -configuration Debug                                  \
          -release $(shell cat /usr/share/buildit/.releaseName) \
          -othercflags "$(LION_CFLAGS)"                         \
+         --                                                    \
+         SDKROOT=$(LION_SDKROOT)                               \
 
 
index 09072ba96636eac58767c20203bd318e180bd6ee..91375dbac8e7857de55475fc4f20e1c844ba11ee 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.IPConfiguration</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.IPConfiguration</string>
index 5b0750cf85c6dadb77b7d4e77e374280938762a5..41bb9103663dd576fcb05c717cca00c68dc5ade3 100644 (file)
@@ -1,58 +1,78 @@
 EXTRA_CFLAGS=
 
 EXTRA_CFLAGS=
 
-all: test_proxy
+TEST_INCLUDE=-I. -I../common -I../../dnsinfo -I../../nwi -I../../libSystemConfiguration -I../../SystemConfiguration.fproj
 
 
-# ----------
-
-shared_dns_info.h shared_dns_infoUser.c: ../../dnsinfo/shared_dns_info.defs
-       mig ../../dnsinfo/shared_dns_info.defs
+all: test_ipv4_routelist
 
 
-shared_dns_infoUser.o: shared_dns_info.h shared_dns_infoUser.c
-       cc -I../../dnsinfo -Wall -O0 -g -c shared_dns_infoUser.c
+# ----------
 
 
-dnsinfo_create.o: shared_dns_info.h ../../dnsinfo/dnsinfo_create.h ../../dnsinfo/dnsinfo_create.c
-       cc -I. -I../../dnsinfo -I../../nwi -Wall -O0 -g -c ../../dnsinfo/dnsinfo_create.c
+dnsinfo_create.o: ../../dnsinfo/dnsinfo_create.h ../../dnsinfo/dnsinfo_create.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../dnsinfo/dnsinfo_create.c
 
 
-dnsinfo_flatfile.o: ../../dnsinfo/dnsinfo_copy.c ../../dnsinfo/dnsinfo_flatfile.c shared_dns_info.h
-       cc -I../../dnsinfo -I../../nwi -D_PATH_RESOLVER_DIR='"/var/tmp/resolver"' -Wall -O0 -g -c ../../dnsinfo/dnsinfo_flatfile.c
+dnsinfo_flatfile.o: ../../dnsinfo/dnsinfo_copy.c ../../dnsinfo/dnsinfo_flatfile.c
+       cc ${TEST_INCLUDE} -D_PATH_RESOLVER_DIR='"/var/tmp/resolver"' -Wall -O0 -g -c ../../dnsinfo/dnsinfo_flatfile.c
 
 
-dnsinfo_private.o: ../../dnsinfo/dnsinfo_private.h ../../dnsinfo/dnsinfo_private.c
-       cc -I../../dnsinfo -Wall -O0 -g -c ../../dnsinfo/dnsinfo_private.c
+dnsinfo_server.o: ../../dnsinfo/dnsinfo_copy.c ../../dnsinfo/dnsinfo_server.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../dnsinfo/dnsinfo_server.c
 
 dns-configuration.o: dns-configuration.h dns-configuration.c dnsinfo_create.o
 
 dns-configuration.o: dns-configuration.h dns-configuration.c dnsinfo_create.o
-       cc -I. -I../../dnsinfo -I../../nwi -DMAIN -Wall -O0 -g -c dns-configuration.c
+       cc ${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
 
 network_information_priv.o: ../../nwi/network_information_priv.h ../../nwi/network_information_priv.c
-       cc -I. -I../../dnsinfo -I../../nwi -DMAIN -Wall -O0 -g -c ../../nwi/network_information_priv.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../nwi/network_information_priv.c
+
+network_information_server.o: ../../nwi/network_information_server.h ../../nwi/network_information_server.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../nwi/network_information_server.c
 
 proxy-configuration.o: proxy-configuration.h proxy-configuration.c
 
 proxy-configuration.o: proxy-configuration.h proxy-configuration.c
-       cc -I. -Wall -O0 -g -c proxy-configuration.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c proxy-configuration.c
+
+set-hostname.o: set-hostname.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c set-hostname.c
 
 smb-configuration.o: smb-configuration.c
 
 smb-configuration.o: smb-configuration.c
-       cc -I. -Wall -O0 -g -c smb-configuration.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c smb-configuration.c
+
+libSystemConfiguration_client.o: ../../libSystemConfiguration/libSystemConfiguration_client.h ../../libSystemConfiguration/libSystemConfiguration_client.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../libSystemConfiguration/libSystemConfiguration_client.c
+
+libSystemConfiguration_server.o: ../../libSystemConfiguration/libSystemConfiguration_server.h ../../libSystemConfiguration/libSystemConfiguration_server.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../../libSystemConfiguration/libSystemConfiguration_server.c
+
+IPMonitorControlPrefs.o: ../common/IPMonitorControlPrefs.h ../common/IPMonitorControlPrefs.c
+       cc ${TEST_INCLUDE} -Wall -O0 -g -c ../common/IPMonitorControlPrefs.c
 
 # ----------
 
 
 # ----------
 
-test_dns: Makefile dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o shared_dns_infoUser.o dns-configuration.o
-       cc -o test_dns dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o shared_dns_infoUser.o dns-configuration.o ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
+dns-configurationX.o: dns-configuration.h dns-configuration.c dnsinfo_create.o
+       cc -DMAIN ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o dns-configurationX.o dns-configuration.c
+
+ip_pluginX.o: ip_plugin.c
+       cc ${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
+       cc -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 ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
 
 # ----------
 
 test_proxy: Makefile proxy-configuration.h proxy-configuration.c
 
 # ----------
 
 test_proxy: Makefile proxy-configuration.h proxy-configuration.c
-       cc -Wall -O0 -g -o test_proxy -DMAIN -DDEBUG proxy-configuration.c ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
+       cc -DMAIN -DDEBUG -Wall -O0 -g -o test_proxy proxy-configuration.c ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
 
 # ----------
 
 
 # ----------
 
-test_smb: Makefile smb-configuration.h smb-configuration.c
-       cc -Wall -O0 -g -o test_smb -DMAIN -DDEBUG smb-configuration.c ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
+smb-configurationX.o: smb-configuration.h smb-configuration.c
+       cc -DMAIN ${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
+       cc -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 ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
 
 # ----------
 
 test_ipv4_routelist.o: ip_plugin.c
 
 # ----------
 
 test_ipv4_routelist.o: ip_plugin.c
-       cc -I. -I../../dnsinfo -I../../nwi -DTEST_IPV4_ROUTELIST -Wall -O0 -g -c -o test_ipv4_routelist.o ip_plugin.c
+       cc -DTEST_IPV4_ROUTELIST ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o test_ipv4_routelist.o ip_plugin.c
 
 
-test_ipv4_routelist: test_ipv4_routelist.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o shared_dns_infoUser.o network_information_priv.o smb-configuration.o proxy-configuration.o
-       cc -Wall -O0 -g -o test_ipv4_routelist test_ipv4_routelist.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o network_information_priv.o shared_dns_infoUser.o smb-configuration.o proxy-configuration.o -framework SystemConfiguration -framework CoreFoundation
+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
+       cc -Wall -O0 -g -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 ${EXTRA_CFLAGS} -framework SystemConfiguration -framework CoreFoundation
 
 test_ipv4_routelist_reference.txt: test_ipv4_routelist
        sh test_reference.sh create test_ipv4_routelist test_ipv4_routelist_reference.txt test_ipv4_routelist_filter.sh
 
 test_ipv4_routelist_reference.txt: test_ipv4_routelist
        sh test_reference.sh create test_ipv4_routelist test_ipv4_routelist_reference.txt test_ipv4_routelist_filter.sh
@@ -63,16 +83,15 @@ test_ipv4_routelist_test: test_ipv4_routelist
 # ----------
 
 IPMonitor.o: ip_plugin.c
 # ----------
 
 IPMonitor.o: ip_plugin.c
-       cc -I. -I../../dnsinfo -I../../nwi -DTEST_IPMONITOR -Wall -O0 -g -c -o IPMonitor.o ip_plugin.c
+       cc -DTEST_IPMONITOR ${TEST_INCLUDE} ${EXTRA_CFLAGS} -Wall -O0 -g -c -o IPMonitor.o ip_plugin.c
 
 
-IPMonitor: IPMonitor.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o shared_dns_infoUser.o smb-configuration.o
-       cc -Wall -O0 -g -o IPMonitor IPMonitor.o dnsinfo_create.o dnsinfo_flatfile.o dnsinfo_private.o shared_dns_infoUser.o smb-configuration.o -framework SystemConfiguration -framework CoreFoundation
+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 -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
 
 # ----------
 
 clean:
        rm -rf  *.o                                                             \
 
 # ----------
 
 clean:
        rm -rf  *.o                                                             \
-               shared_dns_info.h shared_dns_infoServer.c shared_dns_infoUser.c \
                test_dns test_dns.dSYM                                          \
                test_proxy test_proxy.dSYM                                      \
                test_smb test_smb.dSYM                                          \
                test_dns test_dns.dSYM                                          \
                test_proxy test_proxy.dSYM                                      \
                test_smb test_smb.dSYM                                          \
diff --git a/Plugins/IPMonitor/com.apple.networking.IPMonitor b/Plugins/IPMonitor/com.apple.networking.IPMonitor
new file mode 100644 (file)
index 0000000..2f4a10a
--- /dev/null
@@ -0,0 +1 @@
+? [= 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)
index bd20b75b326d984fadb6173c1aaddcfba4d6745e..5815609c8387fbdac6955f583507fd4274e5cd10 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -51,16 +51,20 @@ extern uint32_t notify_monitor_file(int token, const char *name, int flags);
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
+#include "ip_plugin.h"
 
 #include "dns-configuration.h"
 
 #include <dnsinfo.h>
 
 #include "dns-configuration.h"
 
 #include <dnsinfo.h>
-#include <dnsinfo_create.h>
+#include "dnsinfo_create.h"
+#include "dnsinfo_server.h"
 
 #ifdef MAIN
 #undef MAIN
 #include "dnsinfo_copy.c"
 
 #ifdef MAIN
 #undef MAIN
 #include "dnsinfo_copy.c"
+#include "dnsinfo_internal.h"
 #define        MAIN
 #define        MAIN
+#define        DNS_CONFIGURATION_DEBUG
 #endif // MAIN
 
 #include <dns_sd.h>
 #endif // MAIN
 
 #include <dns_sd.h>
@@ -82,6 +86,119 @@ static      CFNumberRef     S_mdns_timeout  = NULL;
 static CFNumberRef     S_pdns_timeout  = NULL;
 
 
 static CFNumberRef     S_pdns_timeout  = NULL;
 
 
+#pragma mark -
+#pragma mark DNS resolver flags
+
+
+static __inline__ boolean_t
+dns_resolver_flags_all_queries(uint32_t query_flags)
+{
+       return ((query_flags & DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS) == DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS);
+}
+
+
+
+
+static void
+add_dns_query_flags(const void *key, const void *value, void *context)
+{
+       CFDictionaryRef service         = value;
+       uint32_t        *query_flags    = context;
+
+
+       // check if the service has v4 or v6 configured
+
+       if ((*query_flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) == 0) {
+               CFDictionaryRef v4_dict;
+
+               v4_dict = CFDictionaryGetValue(service, kSCEntNetIPv4);
+               if (v4_dict != NULL) {
+                       CFDictionaryRef v4_service;
+
+                       v4_service = CFDictionaryGetValue(v4_dict, kIPv4DictService);
+                       if (isA_CFDictionary(v4_service)) {
+                               CFArrayRef      if_addrs;
+                               CFBooleanRef    is_null;
+
+                               is_null = CFDictionaryGetValue(v4_service, kIsNULL);
+                               if_addrs = CFDictionaryGetValue(v4_service, kSCPropNetIPv4Addresses);
+                               if (isA_CFBoolean(is_null) != NULL && CFBooleanGetValue(is_null)) {
+                                       // ignore this service
+                               }
+                               else if (isA_CFArray(if_addrs) != NULL) {
+                                       int     i;
+                                       int     count;
+
+                                       count = CFArrayGetCount(if_addrs);
+                                       for (i = 0; i < count; i++) {
+                                               CFStringRef     if_addr;
+                                               struct in_addr  v4_addr;
+
+                                               if_addr = CFArrayGetValueAtIndex(if_addrs, i);
+                                               if (isA_CFString(if_addr) == NULL) {
+                                                       continue;
+                                               }
+
+                                               cfstring_to_ip(if_addr, &v4_addr);
+                                               if (!IN_LINKLOCAL(ntohl(v4_addr.s_addr))) {
+                                                       // set the request v4 dns record bit
+                                                       *query_flags |= DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if ((*query_flags & DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) == 0) {
+               CFDictionaryRef v6_dict;
+
+               v6_dict = CFDictionaryGetValue(service, kSCEntNetIPv6);
+               if (isA_CFDictionary(v6_dict) != NULL) {
+                       CFArrayRef      if_addrs6;
+                       CFBooleanRef    is_null;
+
+                       is_null = CFDictionaryGetValue(v6_dict, kIsNULL);
+                       if_addrs6 = CFDictionaryGetValue(v6_dict, kSCPropNetIPv6Addresses);
+                       if (isA_CFBoolean(is_null) != NULL && CFBooleanGetValue(is_null)) {
+                               // ignore this service
+                       }
+                       else if (isA_CFArray(if_addrs6) != NULL) {
+                               int     i;
+                               int     count;
+
+                               count = CFArrayGetCount(if_addrs6);
+                               for (i = 0; i < count; i++) {
+                                       CFStringRef     if_addr6;
+                                       struct in6_addr v6_addr;
+
+                                       if_addr6 = CFArrayGetValueAtIndex(if_addrs6, i);
+                                       if (isA_CFString(if_addr6) == NULL) {
+                                               continue;
+                                       }
+
+                                       cfstring_to_ip6(if_addr6, &v6_addr);
+                                       if (!IN6_IS_ADDR_LINKLOCAL(&v6_addr)
+                                           && !IN6_IS_ADDR_MC_LINKLOCAL(&v6_addr)) {
+                                               // set the request v6 dns record bit
+                                               *query_flags |= DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+
+       return;
+}
+
+
+#pragma mark -
+#pragma mark DNS resolver configuration
+
+
 static void
 add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver)
 {
 static void
 add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver)
 {
@@ -93,7 +210,7 @@ add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver)
 
        order = CFDictionaryGetValue(resolver, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(order) ||
 
        order = CFDictionaryGetValue(resolver, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(order) ||
-           !CFNumberGetValue(order, kCFNumberIntType, &order_val)) {
+           !CFNumberGetValue(order, kCFNumberSInt32Type, &order_val)) {
                order     = NULL;
                order_val = 0;
        }
                order     = NULL;
                order_val = 0;
        }
@@ -123,7 +240,7 @@ add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver)
                                // if only the search order's are different
                                match_order = CFDictionaryGetValue(match_resolver, kSCPropNetDNSSearchOrder);
                                if (!isA_CFNumber(match_order) ||
                                // if only the search order's are different
                                match_order = CFDictionaryGetValue(match_resolver, kSCPropNetDNSSearchOrder);
                                if (!isA_CFNumber(match_order) ||
-                                   !CFNumberGetValue(match_order, kCFNumberIntType, &match_order_val)) {
+                                   !CFNumberGetValue(match_order, kCFNumberSInt32Type, &match_order_val)) {
                                        match_order_val = 0;
                                }
 
                                        match_order_val = 0;
                                }
 
@@ -142,7 +259,7 @@ add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver)
        CFRelease(order);
 
        interface = CFDictionaryGetValue(resolver, kSCPropInterfaceName);
        CFRelease(order);
 
        interface = CFDictionaryGetValue(resolver, kSCPropInterfaceName);
-       if (interface != NULL) {
+       if ((interface != NULL) && !CFEqual(interface, CFSTR("*"))) {
                uint32_t        flags;
                unsigned int    if_index                = 0;
                char            if_name[IF_NAMESIZE];
                uint32_t        flags;
                unsigned int    if_index                = 0;
                char            if_name[IF_NAMESIZE];
@@ -258,7 +375,11 @@ add_supplemental(CFMutableArrayRef resolvers, CFDictionaryRef dns, uint32_t defa
 
 
 static void
 
 
 static void
-add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services, CFArrayRef service_order)
+add_supplemental_resolvers(CFMutableArrayRef   resolvers,
+                          CFDictionaryRef      services,
+                          CFArrayRef           service_order,
+                          CFStringRef          scoped_interface,
+                          CFDictionaryRef      scoped_service)
 {
        const void *            keys_q[N_QUICK];
        const void **           keys    = keys_q;
 {
        const void *            keys_q[N_QUICK];
        const void **           keys    = keys_q;
@@ -282,19 +403,59 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services
 
        CFDictionaryGetKeysAndValues(services, keys, vals);
        for (i = 0; i < n_services; i++) {
 
        CFDictionaryGetKeysAndValues(services, keys, vals);
        for (i = 0; i < n_services; i++) {
-               uint32_t        defaultOrder;
-               CFDictionaryRef dns;
-               CFDictionaryRef service = (CFDictionaryRef)vals[i];
+               uint32_t                defaultOrder;
+               CFDictionaryRef         dns;
+               CFStringRef             interface;
+               uint32_t                interface_flags;
+               CFMutableDictionaryRef  newDNS          = NULL;
+               CFDictionaryRef         service         = (CFDictionaryRef)vals[i];
 
                if (!isA_CFDictionary(service)) {
                        continue;
                }
 
                dns = CFDictionaryGetValue(service, kSCEntNetDNS);
 
                if (!isA_CFDictionary(service)) {
                        continue;
                }
 
                dns = CFDictionaryGetValue(service, kSCEntNetDNS);
-               if (!isA_CFDictionary(dns)) {
+               dns = isA_CFDictionary(dns);
+               if (dns == NULL) {
                        continue;
                }
 
                        continue;
                }
 
+               interface = CFDictionaryGetValue(dns, kSCPropInterfaceName);
+
+               if (scoped_interface != NULL) {
+                       //
+                       // we only want to add split/supplemental configurations
+                       // for queries scoped to an interface if they are NOT
+                       // associated with a "real" service
+                       //
+                       if (CFDictionaryContainsKey(service, kSCEntNetIPv4) ||
+                           CFDictionaryContainsKey(service, kSCEntNetIPv6)) {
+                               continue;
+                       }
+
+                       //
+                       // in addition, we don't want to add split/supplemental
+                       // configurations for queries scoped to an interface if
+                       // the configuration does not apply to all interfaces and
+                       // the configuration is explicitly NOT for this interface
+                       //
+                       if (!_SC_CFEqual(interface, CFSTR("*")) &&
+                           !_SC_CFEqual(interface, scoped_interface)) {
+                               continue;
+                       }
+
+                       //
+                       // lastly, check if A/AAAA queries should be issued (based
+                       // on the IP[v6] addresses).  If we would not be issuing a
+                       // query then don't bother adding the configuration.
+                       //
+                       interface_flags = 0;
+                       add_dns_query_flags(NULL, scoped_service, &interface_flags);
+                       if (interface_flags == 0) {
+                               continue;
+                       }
+               }
+
                defaultOrder = DEFAULT_SEARCH_ORDER
                               - (DEFAULT_SEARCH_ORDER / 2)
                               + ((DEFAULT_SEARCH_ORDER / 1000) * i);
                defaultOrder = DEFAULT_SEARCH_ORDER
                               - (DEFAULT_SEARCH_ORDER / 2)
                               + ((DEFAULT_SEARCH_ORDER / 1000) * i);
@@ -304,7 +465,52 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services
                        defaultOrder += (DEFAULT_SEARCH_ORDER / 1000) * n_services;
                }
 
                        defaultOrder += (DEFAULT_SEARCH_ORDER / 1000) * n_services;
                }
 
-               add_supplemental(resolvers, dns, defaultOrder);
+               /*
+                * Ensure that we have the correct InterfaceName in the DNS configuration
+                *
+                * scoped_interface     [supplemental] interface        DNS interface
+                * ================     ========================        =================
+                * NULL                 NULL                            NULL (No change)
+                * NULL                 en0                             NULL
+                * NULL                 *                               NULL
+                * en0                  NULL                            "en0"
+                * en0                  en0                             "en0" (now mutable)
+                * en0                  *                               "en0"
+                */
+               if ((scoped_interface == NULL) && (interface == NULL)) {
+                       newDNS = (CFMutableDictionaryRef)CFRetain(dns);
+               } else {
+                       newDNS = CFDictionaryCreateMutableCopy(NULL, 0, dns);
+                       if (scoped_interface != NULL) {
+                               CFDictionarySetValue(newDNS, kSCPropInterfaceName, scoped_interface);
+                       } else {
+                               CFDictionaryRemoveValue(newDNS, kSCPropInterfaceName);
+                       }
+               }
+
+               if (scoped_interface != NULL) {
+                       uint32_t        flags;
+                       CFNumberRef     num;
+
+                       // set "scoped" configuration flag(s)
+                       if (!CFDictionaryGetValueIfPresent(newDNS, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) ||
+                           !isA_CFNumber(num) ||
+                           !CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
+                               flags = 0;
+                       }
+                       flags |= DNS_RESOLVER_FLAGS_SCOPED;
+
+                       // add A/AAAA query flag(s)
+                       flags |= interface_flags;
+
+                       num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
+                       CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
+                       CFRelease(num);
+               }
+
+               // add [scoped] resolver entry
+               add_supplemental(resolvers, newDNS, defaultOrder);
+               CFRelease(newDNS);
        }
 
        if (keys != keys_q) {
        }
 
        if (keys != keys_q) {
@@ -416,13 +622,13 @@ compareBySearchOrder(const void *val1, const void *val2, void *context)
 
        num1 = CFDictionaryGetValue(dns1, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(num1) ||
 
        num1 = CFDictionaryGetValue(dns1, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(num1) ||
-           !CFNumberGetValue(num1, kCFNumberIntType, &order1)) {
+           !CFNumberGetValue(num1, kCFNumberSInt32Type, &order1)) {
                order1 = DEFAULT_SEARCH_ORDER;
        }
 
        num2 = CFDictionaryGetValue(dns2, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(num2) ||
                order1 = DEFAULT_SEARCH_ORDER;
        }
 
        num2 = CFDictionaryGetValue(dns2, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(num2) ||
-           !CFNumberGetValue(num2, kCFNumberIntType, &order2)) {
+           !CFNumberGetValue(num2, kCFNumberSInt32Type, &order2)) {
                order2 = DEFAULT_SEARCH_ORDER;
        }
 
                order2 = DEFAULT_SEARCH_ORDER;
        }
 
@@ -432,8 +638,8 @@ compareBySearchOrder(const void *val1, const void *val2, void *context)
                    CFDictionaryGetValueIfPresent(dns2, DNS_CONFIGURATION_ORDER_KEY, (const void **)&num2) &&
                    isA_CFNumber(num1) &&
                    isA_CFNumber(num2) &&
                    CFDictionaryGetValueIfPresent(dns2, DNS_CONFIGURATION_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 {
                        if (order1 == order2) {
                                return kCFCompareEqualTo;
                        } else {
@@ -467,7 +673,7 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme
 
                num = CFDictionaryGetValue(defaultDomain, kSCPropNetDNSSearchOrder);
                if (!isA_CFNumber(num) ||
 
                num = CFDictionaryGetValue(defaultDomain, kSCPropNetDNSSearchOrder);
                if (!isA_CFNumber(num) ||
-                   !CFNumberGetValue(num, kCFNumberIntType, &defaultOrder)) {
+                   !CFNumberGetValue(num, kCFNumberSInt32Type, &defaultOrder)) {
                        defaultOrder = DEFAULT_SEARCH_ORDER;
                }
 
                        defaultOrder = DEFAULT_SEARCH_ORDER;
                }
 
@@ -578,6 +784,7 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme
        for (i = 0; i < n_supplemental; i++) {
                CFDictionaryRef dns;
                CFIndex         domainIndex;
        for (i = 0; i < n_supplemental; i++) {
                CFDictionaryRef dns;
                CFIndex         domainIndex;
+               int             noSearch;
                CFNumberRef     num;
                CFStringRef     options;
                CFStringRef     supplementalDomain;
                CFNumberRef     num;
                CFStringRef     options;
                CFStringRef     supplementalDomain;
@@ -607,6 +814,14 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme
                        continue;
                }
 
                        continue;
                }
 
+               num = CFDictionaryGetValue(dns, kSCPropNetDNSSupplementalMatchDomainsNoSearch);
+               if (isA_CFNumber(num) &&
+                   CFNumberGetValue(num, kCFNumberIntType, &noSearch) &&
+                   (noSearch != 0)) {
+                       CFRelease(supplementalDomain);
+                       continue;
+               }
+
                if (CFStringHasSuffix(supplementalDomain, CFSTR(".in-addr.arpa")) ||
                    CFStringHasSuffix(supplementalDomain, CFSTR(".ip6.arpa"    ))) {
                        CFRelease(supplementalDomain);
                if (CFStringHasSuffix(supplementalDomain, CFSTR(".in-addr.arpa")) ||
                    CFStringHasSuffix(supplementalDomain, CFSTR(".ip6.arpa"    ))) {
                        CFRelease(supplementalDomain);
@@ -619,7 +834,7 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme
 
                num = CFDictionaryGetValue(dns, kSCPropNetDNSSearchOrder);
                if (!isA_CFNumber(num) ||
 
                num = CFDictionaryGetValue(dns, kSCPropNetDNSSearchOrder);
                if (!isA_CFNumber(num) ||
-                   !CFNumberGetValue(num, kCFNumberIntType, &supplementalOrder)) {
+                   !CFNumberGetValue(num, kCFNumberSInt32Type, &supplementalOrder)) {
                        supplementalOrder = DEFAULT_SEARCH_ORDER;
                }
 
                        supplementalOrder = DEFAULT_SEARCH_ORDER;
                }
 
@@ -681,7 +896,7 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
        n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;
        if (n_order > 0) {
                order = CFArrayCreateMutableCopy(NULL, 0, service_order);
        n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;
        if (n_order > 0) {
                order = CFArrayCreateMutableCopy(NULL, 0, service_order);
-       } else{
+       } else {
                order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
 
                order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
 
@@ -714,6 +929,7 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
                CFArrayRef              searchDomains;
                CFDictionaryRef         service;
                CFStringRef             serviceID;
                CFArrayRef              searchDomains;
                CFDictionaryRef         service;
                CFStringRef             serviceID;
+               uint32_t                these_flags;
 
                serviceID = CFArrayGetValueAtIndex(order, i);
                service = CFDictionaryGetValue(services, serviceID);
 
                serviceID = CFArrayGetValueAtIndex(order, i);
                service = CFDictionaryGetValue(services, serviceID);
@@ -729,10 +945,16 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
                }
 
                interface = CFDictionaryGetValue(dns, kSCPropInterfaceName);
                }
 
                interface = CFDictionaryGetValue(dns, kSCPropInterfaceName);
-               if (interface == NULL) {
-                       // if no [scoped] interface
+               if ((interface == NULL) || CFEqual(interface, CFSTR("*"))) {
+                       // if no [scoped] interface or supplemental configuration w/match-all
+                       continue;
+               }
+
+               if (CFDictionaryContainsKey(dns, kSCPropNetDNSServiceIdentifier)) {
+                       // if this is a service-specific resolver
                        continue;
                }
                        continue;
                }
+
                if (CFSetContainsValue(seen, interface)) {
                        // if we've already processed this [scoped] interface
                        continue;
                if (CFSetContainsValue(seen, interface)) {
                        // if we've already processed this [scoped] interface
                        continue;
@@ -765,6 +987,14 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
                        flags = 0;
                }
                flags |= DNS_RESOLVER_FLAGS_SCOPED;
                        flags = 0;
                }
                flags |= DNS_RESOLVER_FLAGS_SCOPED;
+
+               these_flags = 0;
+               add_dns_query_flags(serviceID, service, &these_flags);
+               if (these_flags == 0) {
+                   goto skip;
+               }
+               flags |= these_flags;
+
                num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
                CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
                CFRelease(num);
                num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
                CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
                CFRelease(num);
@@ -773,7 +1003,13 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
                CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains);
                CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchOrders);
 
                CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains);
                CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchOrders);
 
+               // add the [scoped] resolver
                add_resolver(scoped, newDNS);
                add_resolver(scoped, newDNS);
+
+               // add any supplemental resolver configurations for this interface
+               add_supplemental_resolvers(scoped, services, service_order, interface, service);
+
+       skip:
                CFRelease(newDNS);
        }
 
                CFRelease(newDNS);
        }
 
@@ -783,6 +1019,74 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray
 }
 
 
 }
 
 
+static void
+add_service_specific_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services)
+{
+       CFIndex services_count  = (isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0);
+
+       if (services_count > 0) {
+               CFIndex                 key_idx;
+               CFStringRef             keys_q[N_QUICK];
+               CFStringRef             *keys   = keys_q;
+               CFMutableSetRef         seen    = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+
+               if (services_count > (CFIndex)(sizeof(keys_q) / sizeof(keys_q[0]))) {
+                       keys = CFAllocatorAllocate(kCFAllocatorDefault, services_count * sizeof(keys[0]), 0);
+               }
+
+               CFDictionaryGetKeysAndValues(services, (const void **)keys, NULL);
+
+               for (key_idx = 0; key_idx < services_count; key_idx++) {
+                       CFDictionaryRef service = CFDictionaryGetValue(services, keys[key_idx]);
+                       CFDictionaryRef dns     = CFDictionaryGetValue(service, kSCEntNetDNS);
+
+                       if (isA_CFDictionary(dns)) {
+                               CFNumberRef     service_identifier      = CFDictionaryGetValue(dns, kSCPropNetDNSServiceIdentifier);
+
+                               if (isA_CFNumber(service_identifier)) {
+                                       if (!CFSetContainsValue(seen, service_identifier)) {
+                                               CFMutableDictionaryRef  new_resolver    = CFDictionaryCreateMutableCopy(NULL, 0, dns);
+                                               CFNumberRef             flags_num;
+                                               int32_t                 flags           = 0;
+
+                                               CFSetSetValue(seen, service_identifier);
+
+                                               if (!CFDictionaryGetValueIfPresent(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&flags_num) ||
+                                                   !isA_CFNumber(flags_num) ||
+                                                   !CFNumberGetValue(flags_num, kCFNumberSInt32Type, &flags)) {
+                                                       flags = 0;
+                                               }
+
+                                               flags |= DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC | DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS;
+
+                                               flags_num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
+                                               CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, flags_num);
+                                               CFRelease(flags_num);
+
+                                               if (CFDictionaryContainsKey(new_resolver, kSCPropInterfaceName)) {
+                                                       CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_SCOPED_QUERY_KEY, kCFBooleanTrue);
+                                               }
+
+                                               CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchDomains);
+                                               CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchOrders);
+
+                                               add_resolver(resolvers, new_resolver);
+                                               CFRelease(new_resolver);
+                                       } else {
+                                               my_log(LOG_ERR, "add_service_specific_resolvers: got a resolver with a duplicate service identifier, skipping");
+                                       }
+                               }
+                       }
+               }
+
+               if (keys != keys_q) {
+                       CFAllocatorDeallocate(kCFAllocatorDefault, keys);
+               }
+               CFRelease(seen);
+       }
+}
+
+
 static void
 add_default_resolver(CFMutableArrayRef resolvers,
                     CFDictionaryRef    defaultResolver,
 static void
 add_default_resolver(CFMutableArrayRef resolvers,
                     CFDictionaryRef    defaultResolver,
@@ -801,12 +1105,13 @@ add_default_resolver(CFMutableArrayRef   resolvers,
        } else {
                myDefault = CFDictionaryCreateMutableCopy(NULL, 0, defaultResolver);
        }
        } else {
                myDefault = CFDictionaryCreateMutableCopy(NULL, 0, defaultResolver);
        }
+       assert(myDefault != NULL);
 
        // ensure that the default resolver has a search order
 
        order = CFDictionaryGetValue(myDefault, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(order) ||
 
        // ensure that the default resolver has a search order
 
        order = CFDictionaryGetValue(myDefault, kSCPropNetDNSSearchOrder);
        if (!isA_CFNumber(order) ||
-           !CFNumberGetValue(order, kCFNumberIntType, &myOrder)) {
+           !CFNumberGetValue(order, kCFNumberSInt32Type, &myOrder)) {
                myOrder = DEFAULT_SEARCH_ORDER;
                order = CFNumberCreate(NULL, kCFNumberIntType, &myOrder);
                CFDictionarySetValue(myDefault, kSCPropNetDNSSearchOrder, order);
                myOrder = DEFAULT_SEARCH_ORDER;
                order = CFNumberCreate(NULL, kCFNumberIntType, &myOrder);
                CFDictionarySetValue(myDefault, kSCPropNetDNSSearchOrder, order);
@@ -827,23 +1132,6 @@ add_default_resolver(CFMutableArrayRef    resolvers,
 }
 
 
 }
 
 
-/*
- * 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 dns_create_resolver_t
 create_resolver(CFDictionaryRef dns)
 {
 static dns_create_resolver_t
 create_resolver(CFDictionaryRef dns)
 {
@@ -851,7 +1139,6 @@ create_resolver(CFDictionaryRef dns)
        CFNumberRef             num;
        dns_create_resolver_t   _resolver;
        CFStringRef             str;
        CFNumberRef             num;
        dns_create_resolver_t   _resolver;
        CFStringRef             str;
-       CFMutableArrayRef       serverAddresses         = NULL;
        CFStringRef             targetInterface         = NULL;
        unsigned int            targetInterfaceIndex    = 0;
 
        CFStringRef             targetInterface         = NULL;
        unsigned int            targetInterfaceIndex    = 0;
 
@@ -906,14 +1193,23 @@ create_resolver(CFDictionaryRef dns)
                }
        }
 
                }
        }
 
+       // process flags
+       num = CFDictionaryGetValue(dns, DNS_CONFIGURATION_FLAGS_KEY);
+       if (isA_CFNumber(num)) {
+               uint32_t        flags;
+
+               if (CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
+                       _dns_resolver_set_flags(&_resolver, flags);
+               }
+       }
+
        // process nameserver addresses
        // process nameserver addresses
+       // Note: the flags may be overwritten if the resolver has LOOPBACK addresses
        list = CFDictionaryGetValue(dns, kSCPropNetDNSServerAddresses);
        if (isA_CFArray(list)) {
                CFIndex i;
                CFIndex n       = CFArrayGetCount(list);
 
        list = CFDictionaryGetValue(dns, kSCPropNetDNSServerAddresses);
        if (isA_CFArray(list)) {
                CFIndex i;
                CFIndex n       = CFArrayGetCount(list);
 
-               serverAddresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
                for (i = 0; i < n; i++) {
                        union {
                                struct sockaddr         sa;
                for (i = 0; i < n; i++) {
                        union {
                                struct sockaddr         sa;
@@ -921,7 +1217,6 @@ create_resolver(CFDictionaryRef dns)
                                struct sockaddr_in6     sin6;
                        } addr;
                        char                            buf[64];
                                struct sockaddr_in6     sin6;
                        } addr;
                        char                            buf[64];
-                       CFDataRef                       serverAddress;
 
                        str = CFArrayGetValueAtIndex(list, i);
                        if (!isA_CFString(str)) {
 
                        str = CFArrayGetValueAtIndex(list, i);
                        if (!isA_CFString(str)) {
@@ -948,10 +1243,6 @@ create_resolver(CFDictionaryRef dns)
                        }
 
                        _dns_resolver_add_nameserver(&_resolver, &addr.sa);
                        }
 
                        _dns_resolver_add_nameserver(&_resolver, &addr.sa);
-
-                       serverAddress = CFDataCreate(NULL, (const void *)&addr.sa, addr.sa.sa_len);
-                       CFArrayAppendValue(serverAddresses, serverAddress);
-                       CFRelease(serverAddress);
                }
        }
 
                }
        }
 
@@ -960,7 +1251,7 @@ create_resolver(CFDictionaryRef dns)
        if (isA_CFNumber(num)) {
                uint32_t        order;
 
        if (isA_CFNumber(num)) {
                uint32_t        order;
 
-               if (CFNumberGetValue(num, kCFNumberIntType, &order)) {
+               if (CFNumberGetValue(num, kCFNumberSInt32Type, &order)) {
                        _dns_resolver_set_order(&_resolver, order);
                }
        }
                        _dns_resolver_set_order(&_resolver, order);
                }
        }
@@ -1055,82 +1346,15 @@ create_resolver(CFDictionaryRef dns)
                }
        }
 
                }
        }
 
-       // process flags
-       num = CFDictionaryGetValue(dns, DNS_CONFIGURATION_FLAGS_KEY);
+       num = CFDictionaryGetValue(dns, kSCPropNetDNSServiceIdentifier);
        if (isA_CFNumber(num)) {
        if (isA_CFNumber(num)) {
-               uint32_t        flags;
+               int     service_identifier;
 
 
-               if (CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
-                       _dns_resolver_set_flags(&_resolver, flags);
+               if (CFNumberGetValue(num, kCFNumberIntType, &service_identifier)) {
+                       _dns_resolver_set_service_identifier(&_resolver, (uint32_t)service_identifier);
                }
        }
 
                }
        }
 
-       if (serverAddresses != NULL) {
-               SCNetworkReachabilityFlags      flags           = kSCNetworkReachabilityFlagsReachable;
-               CFIndex                         i;
-               CFIndex                         n               = CFArrayGetCount(serverAddresses);
-               CFMutableDictionaryRef          targetOptions;
-
-               targetOptions = CFDictionaryCreateMutable(NULL,
-                                                         0,
-                                                         &kCFTypeDictionaryKeyCallBacks,
-                                                         &kCFTypeDictionaryValueCallBacks);
-               CFDictionarySetValue(targetOptions,
-                                    kSCNetworkReachabilityOptionServerBypass,
-                                    kCFBooleanTrue);
-               if (targetInterface != NULL) {
-                       CFDictionarySetValue(targetOptions,
-                                            kSCNetworkReachabilityOptionInterface,
-                                            targetInterface);
-               }
-
-               for (i = 0; i < n; i++) {
-                       SCNetworkReachabilityFlags      ns_flags;
-                       Boolean                         ok;
-                       CFDataRef                       serverAddress;
-                       SCNetworkReachabilityRef        target;
-
-                       serverAddress = CFArrayGetValueAtIndex(serverAddresses, i);
-                       CFDictionarySetValue(targetOptions,
-                                            kSCNetworkReachabilityOptionRemoteAddress,
-                                            serverAddress);
-                       target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions);
-                       if (target == NULL) {
-                               CFDictionaryRemoveValue(targetOptions, kSCNetworkReachabilityOptionInterface);
-                               target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions);
-                               if (target != NULL) {
-                                       // if interface name not (no longer) valid
-                                       CFRelease(target);
-                                       flags = 0;
-                                       break;
-                               }
-
-                               // address not valid?
-                               SCLog(TRUE, LOG_ERR,
-                                     CFSTR("create_resolver SCNetworkReachabilityCreateWithOptions() failed:\n  options = %@"),
-                                     targetOptions);
-                               break;
-                       }
-
-                       ok = SCNetworkReachabilityGetFlags(target, &ns_flags);
-                       CFRelease(target);
-                       if (!ok) {
-                               break;
-                       }
-
-                       if ((i == 0) ||
-                           (rankReachability(ns_flags) < rankReachability(flags))) {
-                               /* return the worst case result */
-                               flags = ns_flags;
-                       }
-               }
-
-               _dns_resolver_set_reach_flags(&_resolver, flags);
-
-               CFRelease(targetOptions);
-               CFRelease(serverAddresses);
-       }
-
        if (targetInterface != NULL) {
                CFRelease(targetInterface);
        }
        if (targetInterface != NULL) {
                CFRelease(targetInterface);
        }
@@ -1157,6 +1381,25 @@ isScopedConfiguration(CFDictionaryRef dns)
 }
 
 
 }
 
 
+static __inline__ Boolean
+isServiceSpecificConfiguration(CFDictionaryRef dns)
+{
+       uint32_t        flags;
+       CFNumberRef     num;
+
+       if (dns != NULL &&
+           CFDictionaryGetValueIfPresent(dns, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) &&
+           num != NULL &&
+           CFNumberGetValue(num, kCFNumberSInt32Type, &flags) &&
+           (flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC))
+       {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+
 static CFComparisonResult
 compareDomain(const void *val1, const void *val2, void *context)
 {
 static CFComparisonResult
 compareDomain(const void *val1, const void *val2, void *context)
 {
@@ -1256,11 +1499,12 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
                      CFArrayRef        privateResolvers)
 {
        dns_create_config_t     _config;
                      CFArrayRef        privateResolvers)
 {
        dns_create_config_t     _config;
-       Boolean                 changed         = FALSE;
+       Boolean                 changed                 = FALSE;
+       uint32_t                dns_resolver_flags      = 0;
        CFIndex                 i;
        CFMutableDictionaryRef  myDefault;
        CFIndex                 i;
        CFMutableDictionaryRef  myDefault;
-       Boolean                 myOrderAdded    = FALSE;
-       CFArrayRef              mySearchDomains = NULL;
+       Boolean                 myOrderAdded            = FALSE;
+       CFArrayRef              mySearchDomains         = NULL;
        CFIndex                 n_resolvers;
        CFMutableArrayRef       resolvers;
        unsigned char           signature[CC_SHA1_DIGEST_LENGTH];
        CFIndex                 n_resolvers;
        CFMutableArrayRef       resolvers;
        unsigned char           signature[CC_SHA1_DIGEST_LENGTH];
@@ -1269,10 +1513,11 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
        // establish list of resolvers
 
        resolvers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        // establish list of resolvers
 
        resolvers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       assert(resolvers != NULL);
 
        // collect (and add) any "supplemental" resolver configurations
 
 
        // collect (and add) any "supplemental" resolver configurations
 
-       add_supplemental_resolvers(resolvers, services, serviceOrder);
+       add_supplemental_resolvers(resolvers, services, serviceOrder, NULL, NULL);
 
        // collect (and add) any "private" resolver configurations
 
 
        // collect (and add) any "private" resolver configurations
 
@@ -1290,6 +1535,10 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
 
        add_scoped_resolvers(resolvers, services, serviceOrder);
 
 
        add_scoped_resolvers(resolvers, services, serviceOrder);
 
+       // collect (and add) any "service-specific" resolver configurations
+
+       add_service_specific_resolvers(resolvers, services);
+
        // sort resolvers
 
        n_resolvers = CFArrayGetCount(resolvers);
        // sort resolvers
 
        n_resolvers = CFArrayGetCount(resolvers);
@@ -1349,36 +1598,80 @@ dns_configuration_set(CFDictionaryRef   defaultResolver,
                 */
                _config = _dns_configuration_create();
 
                 */
                _config = _dns_configuration_create();
 
-               // add resolvers
+               CFDictionaryApplyFunction(services, add_dns_query_flags , &dns_resolver_flags);
 
                for (i = 0; i < n_resolvers; i++) {
 
                for (i = 0; i < n_resolvers; i++) {
+                       boolean_t               is_default_resolver;
                        CFDictionaryRef         resolver;
                        dns_create_resolver_t   _resolver;
 
                        resolver = CFArrayGetValueAtIndex(resolvers, i);
                        CFDictionaryRef         resolver;
                        dns_create_resolver_t   _resolver;
 
                        resolver = CFArrayGetValueAtIndex(resolvers, i);
+
+                       is_default_resolver = (!isScopedConfiguration(resolver) && !isServiceSpecificConfiguration(resolver));
+                       if (is_default_resolver) {
+                               CFMutableDictionaryRef  new_resolver;
+                               CFNumberRef             num;
+
+                               new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, resolver);
+
+                               num = CFNumberCreate(NULL, kCFNumberSInt32Type, &dns_resolver_flags);
+                               CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, num);
+                               CFRelease(num);
+
+                               resolver = new_resolver;
+                       }
+
                        _resolver = create_resolver(resolver);
                        _dns_configuration_add_resolver(&_config, _resolver);
                        _dns_resolver_free(&_resolver);
                        _resolver = create_resolver(resolver);
                        _dns_configuration_add_resolver(&_config, _resolver);
                        _dns_resolver_free(&_resolver);
+
+                       if (is_default_resolver) {
+                               CFRelease(resolver);
+                       }
                }
 
 #if    !TARGET_OS_IPHONE
                // add flatfile resolvers
 
                }
 
 #if    !TARGET_OS_IPHONE
                // add flatfile resolvers
 
+               _dnsinfo_flatfile_set_flags(dns_resolver_flags);
                _dnsinfo_flatfile_add_resolvers(&_config);
 #endif // !TARGET_OS_IPHONE
        }
 
                _dnsinfo_flatfile_add_resolvers(&_config);
 #endif // !TARGET_OS_IPHONE
        }
 
+#ifdef DNS_CONFIGURATION_DEBUG
+       {
+               uint8_t                 *buf;
+               dns_config_t            *config;
+               _dns_config_buf_t       *config_buf;
+               uint32_t                n_config;
+               uint32_t                n_padding;
+
+               config_buf = (_dns_config_buf_t *)_config;
+               n_config  = sizeof(_dns_config_buf_t) + ntohl(config_buf->n_attribute);
+               n_padding = ntohl(config_buf->n_padding);
+               buf = malloc(n_config + n_padding);
+               bcopy((void *)config_buf, buf, n_config);
+               bzero(&buf[n_config], n_padding);
+               config = expand_config((_dns_config_buf_t *)buf);
+               _dns_configuration_print(config);
+               free(buf);
+       }
+#endif // DNS_CONFIGURATION_DEBUG
+
        // check if the configuration changed
        _dns_configuration_signature(&_config, signature, sizeof(signature));
        if (bcmp(signature, signature_last, sizeof(signature)) != 0) {
        // check if the configuration changed
        _dns_configuration_signature(&_config, signature, sizeof(signature));
        if (bcmp(signature, signature_last, sizeof(signature)) != 0) {
+               // save [new] signature
+               bcopy(signature, signature_last, sizeof(signature));
+
+               // save [new] configuration
+               if (!_dns_configuration_store(&_config)) {
+                       my_log(LOG_ERR, "dns_configuration_set: could not store configuration");
+               }
+
                changed = TRUE;
        }
                changed = TRUE;
        }
-       bcopy(signature, signature_last, sizeof(signature));
 
 
-       // save configuration
-       if (!_dns_configuration_store(&_config)) {
-               SCLog(TRUE, LOG_ERR, CFSTR("dns_configuration_set: could not store configuration"));
-       }
        if (_config != NULL) _dns_configuration_free(&_config);
 
        CFRelease(resolvers);
        if (_config != NULL) _dns_configuration_free(&_config);
 
        CFRelease(resolvers);
@@ -1408,7 +1701,7 @@ dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *inf
        }
        resolvers_save = resolvers_now;
 
        }
        resolvers_save = resolvers_now;
 
-       SCLog(TRUE, LOG_DEBUG, CFSTR(_PATH_RESOLVER_DIR " changed"));
+       my_log(LOG_DEBUG, _PATH_RESOLVER_DIR " changed");
 
        // fake a "DNS" change
        keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
 
        // fake a "DNS" change
        keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
@@ -1433,13 +1726,13 @@ dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callou
 
        status = notify_register_mach_port(_PATH_RESOLVER_DIR, &notify_port, 0, &notify_token);
        if (status != NOTIFY_STATUS_OK) {
 
        status = notify_register_mach_port(_PATH_RESOLVER_DIR, &notify_port, 0, &notify_token);
        if (status != NOTIFY_STATUS_OK) {
-               SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
+               my_log(LOG_ERR, "notify_register_mach_port() failed");
                return;
        }
 
        status = notify_monitor_file(notify_token, "/private" _PATH_RESOLVER_DIR, 0);
        if (status != NOTIFY_STATUS_OK) {
                return;
        }
 
        status = notify_monitor_file(notify_token, "/private" _PATH_RESOLVER_DIR, 0);
        if (status != NOTIFY_STATUS_OK) {
-               SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_monitor_file() failed"));
+               my_log(LOG_ERR, "notify_monitor_file() failed");
                (void)notify_cancel(notify_token);
                return;
        }
                (void)notify_cancel(notify_token);
                return;
        }
@@ -1451,7 +1744,7 @@ dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callou
 
        rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
        if (rls == NULL) {
 
        rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
        if (rls == NULL) {
-               SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
+               my_log(LOG_ERR, "SCDynamicStoreCreateRunLoopSource() failed");
                CFRelease(mp);
                (void)notify_cancel(notify_token);
                return;
                CFRelease(mp);
                (void)notify_cancel(notify_token);
                return;
@@ -1513,7 +1806,21 @@ split(const void * key, const void * value, void * context)
 
        if (CFEqual(entity_id, kSCEntNetIPv4) ||
            CFEqual(entity_id, kSCEntNetIPv6)) {
 
        if (CFEqual(entity_id, kSCEntNetIPv4) ||
            CFEqual(entity_id, kSCEntNetIPv6)) {
-               CFStringRef     interface;
+               CFStringRef             interface;
+
+               if (CFEqual(entity_id, kSCEntNetIPv4)) {
+                       CFMutableDictionaryRef  ipv4_dict;
+
+                       ipv4_dict = CFDictionaryCreateMutable(NULL,
+                                                             0,
+                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                             &kCFTypeDictionaryValueCallBacks);
+                       CFDictionarySetValue(ipv4_dict, kIPv4DictService, (CFDictionaryRef)value);
+                       CFDictionarySetValue(state_dict, entity_id, ipv4_dict);
+                       CFRelease(ipv4_dict);
+               } else {
+                       CFDictionarySetValue(state_dict, entity_id, (CFDictionaryRef)value);
+               }
 
                interface = CFDictionaryGetValue((CFDictionaryRef)value, kSCPropInterfaceName);
                if (interface != NULL) {
 
                interface = CFDictionaryGetValue((CFDictionaryRef)value, kSCPropInterfaceName);
                if (interface != NULL) {
@@ -1525,9 +1832,9 @@ split(const void * key, const void * value, void * context)
                                new_dns = CFDictionaryCreateMutableCopy(NULL, 0, dns);
                        } else {
                                new_dns = CFDictionaryCreateMutable(NULL,
                                new_dns = CFDictionaryCreateMutableCopy(NULL, 0, dns);
                        } else {
                                new_dns = CFDictionaryCreateMutable(NULL,
-                                                               0,
-                                                               &kCFTypeDictionaryKeyCallBacks,
-                                                               &kCFTypeDictionaryValueCallBacks);
+                                                                   0,
+                                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                                   &kCFTypeDictionaryValueCallBacks);
                        }
                        CFDictionarySetValue(new_dns, kSCPropInterfaceName, interface);
                        CFDictionarySetValue(state_dict, kSCEntNetDNS, new_dns);
                        }
                        CFDictionarySetValue(new_dns, kSCPropInterfaceName, interface);
                        CFDictionarySetValue(state_dict, kSCEntNetDNS, new_dns);
index 08dc9e10f171ea55fbcdf458d11f90ce4ee2882c..b218d3a4f5b4e3f2e839d9504ad4dfb0488a178d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   dns_configuration_init          (CFBundleRef            bundle);
 
 
 #if    !TARGET_OS_IPHONE
 void   dns_configuration_init          (CFBundleRef            bundle);
 
 
 #if    !TARGET_OS_IPHONE
-__private_extern__
 void   dns_configuration_monitor       (SCDynamicStoreRef      store,
                                         SCDynamicStoreCallBack callout);
 #endif // !TARGET_OS_IPHONE
 
 void   dns_configuration_monitor       (SCDynamicStoreRef      store,
                                         SCDynamicStoreCallBack callout);
 #endif // !TARGET_OS_IPHONE
 
-__private_extern__
 Boolean        dns_configuration_set           (CFDictionaryRef        defaultResolver,
                                         CFDictionaryRef        services,
                                         CFArrayRef             serviceOrder,
 Boolean        dns_configuration_set           (CFDictionaryRef        defaultResolver,
                                         CFDictionaryRef        services,
                                         CFArrayRef             serviceOrder,
index cb683f422b4179feee7cde7d3066973557e9d9d6..328ceb98a81f35feee4f7dc5f7a1e4d2cdf38947 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2013 Apple Inc.  All Rights Reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <limits.h>
 #include <notify.h>
 #include <mach/mach_time.h>
 #include <limits.h>
 #include <notify.h>
 #include <mach/mach_time.h>
+#include <dispatch/dispatch.h>
+#include <CommonCrypto/CommonDigest.h>
 
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
 #include <SystemConfiguration/SCValidation.h>
 
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
 #include <SystemConfiguration/SCValidation.h>
+#include <SystemConfiguration/scprefs_observer.h>
 #include <SystemConfiguration/SCPrivate.h>     /* for SCLog() */
 #include <SystemConfiguration/SCPrivate.h>     /* for SCLog() */
+#include "SCNetworkReachabilityInternal.h"
+#include "SCNetworkSignaturePrivate.h"
 #include <dnsinfo.h>
 #include <dnsinfo.h>
-#if    !TARGET_OS_IPHONE
-#include <dnsinfo_create.h>
-#endif /* !TARGET_OS_IPHONE */
+#include "dnsinfo_server.h"
+
+#if    defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS)
+#include <ppp/PPPControllerPriv.h>
+#endif // !defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS)
 
 #include <dns_sd.h>
 #ifndef        kDNSServiceCompMulticastDNS
 
 #include <dns_sd.h>
 #ifndef        kDNSServiceCompMulticastDNS
 #endif
 #include <network_information.h>
 #include "network_information_priv.h"
 #endif
 #include <network_information.h>
 #include "network_information_priv.h"
+#include "network_information_server.h"
+#include <ppp/ppp_msg.h>
 
 enum {
     kProtocolFlagsNone         = 0x0,
 
 enum {
     kProtocolFlagsNone         = 0x0,
@@ -130,19 +139,43 @@ enum {
 #define ROUTELIST_DEBUG(a, f)
 #endif
 
 #define ROUTELIST_DEBUG(a, f)
 #endif
 
+#if    !TARGET_IPHONE_SIMULATOR
 #include "set-hostname.h"
 #include "set-hostname.h"
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
 #include "dns-configuration.h"
 #include "proxy-configuration.h"
 #include "dns-configuration.h"
 #include "proxy-configuration.h"
+
 #if    !TARGET_OS_IPHONE
 #include "smb-configuration.h"
 #endif /* !TARGET_OS_IPHONE */
 
 #if    !TARGET_OS_IPHONE
 #include "smb-configuration.h"
 #endif /* !TARGET_OS_IPHONE */
 
+/*
+ * Property: kIPIsCoupled
+ * Purpose:
+ *   Used to indicate that the IPv4 and IPv6 services are coupled.
+ *   Neither the IPv4 part nor the IPv6 part of a coupled service
+ *   may become primary if IPv4 or IPv6 is primary for another interface.
+ *
+ *   For example, if the service over en3 is "coupled" and has IPv6,
+ *   and en0 is primary for just IPv4, IPv6 over en3 is not eligible
+ *   to become primary for IPv6.
+ */
+#define kIPIsCoupled   CFSTR("IPIsCoupled")
+
 #define PPP_PREFIX     "ppp"
 
 #define IP_FORMAT      "%d.%d.%d.%d"
 #define IP_CH(ip)      ((u_char *)(ip))
 #define IP_LIST(ip)    IP_CH(ip)[0],IP_CH(ip)[1],IP_CH(ip)[2],IP_CH(ip)[3]
 
 #define PPP_PREFIX     "ppp"
 
 #define IP_FORMAT      "%d.%d.%d.%d"
 #define IP_CH(ip)      ((u_char *)(ip))
 #define IP_LIST(ip)    IP_CH(ip)[0],IP_CH(ip)[1],IP_CH(ip)[2],IP_CH(ip)[3]
 
+#include "ip_plugin.h"
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+static SCLoggerRef     S_IPMonitor_logger;
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+static boolean_t       S_bundle_logging_verbose;
+
 /*
  * IPv4 Route management
  */
 /*
  * IPv4 Route management
  */
@@ -153,6 +186,7 @@ enum {
     kRouteIsDirectToInterfaceFlag      = 0x00000001,
     kRouteIsNotSubnetLocalFlag         = 0x00000002,
     kRouteIsScopedFlag                 = 0x00000004,
     kRouteIsDirectToInterfaceFlag      = 0x00000001,
     kRouteIsNotSubnetLocalFlag         = 0x00000002,
     kRouteIsScopedFlag                 = 0x00000004,
+    kRouteIsNULLFlag                   = 0x00000008
 };
 
 typedef struct {
 };
 
 typedef struct {
@@ -169,6 +203,7 @@ typedef struct {
 typedef struct {
     int                        count;
     int                        size;
 typedef struct {
     int                        count;
     int                        size;
+    boolean_t          exclude_from_nwi;
     IPv4Route          list[1];        /* variable length */
 } IPv4RouteList, *IPv4RouteListRef;
 
     IPv4Route          list[1];        /* variable length */
 } IPv4RouteList, *IPv4RouteListRef;
 
@@ -177,27 +212,49 @@ enum {
     kIPv4RouteListRemoveRouteCommand
 };
 
     kIPv4RouteListRemoveRouteCommand
 };
 
-typedef struct {
-    char               ifname[IFNAMSIZ];
-    uint32_t           flags;
-    Rank               rank;
-    struct in6_addr    iaddr6;
-} IPv6RankedE, *IPv6RankedERef;
+/*
+ * Election Information
+ * - information about the current best services
+ */
+typedef struct Candidate {
+    CFStringRef                serviceID;
+    CFStringRef                if_name;
+    union {
+       struct in_addr  v4;
+       struct in6_addr v6;
+    } addr;
+    Rank                               rank;
+    boolean_t                          ip_is_coupled;
+    SCNetworkReachabilityFlags         reachability_flags;
+    union {
+       struct sockaddr_in vpn_server_addr4;
+       struct sockaddr_in6 vpn_server_addr6;
+    } vpn_server_addr;
+    CFStringRef                                signature;
+} Candidate, * CandidateRef;
 
 
-typedef struct {
+typedef struct ElectionResults {
     int                        count;
     int                        size;
     int                        count;
     int                        size;
-    IPv6RankedE                elem[1];
-} IPv6RankedList, *IPv6RankedListRef;
+    Candidate          candidates[1];
+} ElectionResults, * ElectionResultsRef;
+
+static __inline__ unsigned int
+ElectionResultsComputeSize(unsigned int n)
+{
+    return (offsetof(ElectionResults, candidates[n]));
+}
 
 /*
  * Type: Rank
  * Purpose:
  *   A 32-bit value to encode the relative rank of a service.
  *
 
 /*
  * Type: Rank
  * Purpose:
  *   A 32-bit value to encode the relative rank of a service.
  *
- *   The top 8 bits are used to hold the rank assertion (first, last, never, default),
- *   the bottom 24 bits are used to store the service index i.e. the position within
- *   the service order array.
+ *   The top 8 bits are used to hold the rank assertion (first, last
+ *   never, default).
+ *
+ *   The bottom 24 bits are used to store the service index (i.e. the
+ *   position within the service order array).
  */
 #define RANK_ASSERTION_MAKE(r)         ((Rank)(r) << 24)
 #define kRankAssertionFirst            RANK_ASSERTION_MAKE(0)
  */
 #define RANK_ASSERTION_MAKE(r)         ((Rank)(r) << 24)
 #define kRankAssertionFirst            RANK_ASSERTION_MAKE(0)
@@ -241,6 +298,7 @@ static SCDynamicStoreRef    S_session = NULL;
 
 /* debug output flags */
 static uint32_t                        S_IPMonitor_debug = 0;
 
 /* debug output flags */
 static uint32_t                        S_IPMonitor_debug = 0;
+static Boolean                 S_IPMonitor_verbose = FALSE;
 
 /* are we netbooted?  If so, don't touch the default route */
 static boolean_t               S_netboot = FALSE;
 
 /* are we netbooted?  If so, don't touch the default route */
 static boolean_t               S_netboot = FALSE;
@@ -268,6 +326,10 @@ static CFStringRef         S_primary_ipv6 = NULL;
 static CFStringRef             S_primary_dns = NULL;
 static CFStringRef             S_primary_proxies = NULL;
 
 static CFStringRef             S_primary_dns = NULL;
 static CFStringRef             S_primary_proxies = NULL;
 
+/* the current election results */
+static ElectionResultsRef      S_ipv4_results;
+static ElectionResultsRef      S_ipv6_results;
+
 static CFStringRef             S_state_global_ipv4 = NULL;
 static CFStringRef             S_state_global_ipv6 = NULL;
 static CFStringRef             S_state_global_dns = NULL;
 static CFStringRef             S_state_global_ipv4 = NULL;
 static CFStringRef             S_state_global_ipv6 = NULL;
 static CFStringRef             S_state_global_dns = NULL;
@@ -279,18 +341,40 @@ static CFStringRef                S_setup_service_prefix = NULL;
 static CFStringRef             S_multicast_resolvers = NULL;
 static CFStringRef             S_private_resolvers = NULL;
 
 static CFStringRef             S_multicast_resolvers = NULL;
 static CFStringRef             S_private_resolvers = NULL;
 
+#if    !TARGET_IPHONE_SIMULATOR
 static IPv4RouteListRef                S_ipv4_routelist = NULL;
 static IPv4RouteListRef                S_ipv4_routelist = NULL;
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 static const struct in_addr    S_ip_zeros = { 0 };
 static const struct in6_addr   S_ip6_zeros = IN6ADDR_ANY_INIT;
 
 static boolean_t               S_append_state = FALSE;
 
 
 static const struct in_addr    S_ip_zeros = { 0 };
 static const struct in6_addr   S_ip6_zeros = IN6ADDR_ANY_INIT;
 
 static boolean_t               S_append_state = FALSE;
 
+static CFDictionaryRef         S_dns_dict = NULL;
+
+static Boolean                 S_dnsinfo_synced = TRUE;
+
 static nwi_state_t             S_nwi_state = NULL;
 static nwi_state_t             S_nwi_state = NULL;
+static Boolean                 S_nwi_synced = TRUE;
+
+static CFDictionaryRef         S_proxies_dict = NULL;
+
+// Note: access should be gated with __network_change_queue()
+static uint32_t                        S_network_change_needed = 0;
+#define        NETWORK_CHANGE_NET      1<<0
+#define        NETWORK_CHANGE_DNS      1<<1
+#define        NETWORK_CHANGE_PROXY    1<<2
+#if    !TARGET_OS_IPHONE
+#define        NETWORK_CHANGE_SMB      1<<3
+#endif /* !TARGET_OS_IPHONE */
+static struct timeval          S_network_change_start;
+static Boolean                 S_network_change_timeout = FALSE;
+static dispatch_source_t       S_network_change_timer = NULL;
 
 #if    !TARGET_OS_IPHONE
 static CFStringRef             S_primary_smb = NULL;
 static CFStringRef             S_state_global_smb = NULL;
 
 #if    !TARGET_OS_IPHONE
 static CFStringRef             S_primary_smb = NULL;
 static CFStringRef             S_state_global_smb = NULL;
+static CFDictionaryRef         S_smb_dict = NULL;
 #endif /* !TARGET_OS_IPHONE */
 
 #if    !TARGET_OS_IPHONE
 #endif /* !TARGET_OS_IPHONE */
 
 #if    !TARGET_OS_IPHONE
@@ -314,6 +398,7 @@ enum {
     kEntityTypeSMB,
 #endif /* !TARGET_OS_IPHONE */
     ENTITY_TYPES_COUNT,
     kEntityTypeSMB,
 #endif /* !TARGET_OS_IPHONE */
     ENTITY_TYPES_COUNT,
+    kEntityTypeVPNStatus,
     kEntityTypeServiceOptions  = 31
 };
 typedef uint32_t       EntityType;
     kEntityTypeServiceOptions  = 31
 };
 typedef uint32_t       EntityType;
@@ -328,13 +413,20 @@ static const CFStringRef *entityTypeNames[ENTITY_TYPES_COUNT] = {
 #endif /* !TARGET_OS_IPHONE */
 };
 
 #endif /* !TARGET_OS_IPHONE */
 };
 
-#ifndef kSCEntNetIPv4RouteList
-#define kSCEntNetIPv4RouteList CFSTR("IPv4RouteList")
-#endif
+static Boolean
+S_dict_get_boolean(CFDictionaryRef dict, CFStringRef key, Boolean def_value);
 
 
-#ifndef kSCEntNetIPv4ServiceDict
-#define kSCEntNetIPv4ServiceDict CFSTR("IPv4ServiceDict")
-#endif
+static __inline__ char
+ipvx_char(int af)
+{
+    return ((af == AF_INET) ? '4' : '6');
+}
+
+static __inline__ char
+ipvx_other_char(int af)
+{
+    return ((af == AF_INET) ? '6' : '4');
+}
 
 static IPv4RouteListRef
 ipv4_dict_get_routelist(CFDictionaryRef ipv4_dict)
 
 static IPv4RouteListRef
 ipv4_dict_get_routelist(CFDictionaryRef ipv4_dict)
@@ -346,7 +438,7 @@ ipv4_dict_get_routelist(CFDictionaryRef ipv4_dict)
        return (NULL);
     }
 
        return (NULL);
     }
 
-    routes = CFDictionaryGetValue(ipv4_dict, kSCEntNetIPv4RouteList);
+    routes = CFDictionaryGetValue(ipv4_dict, kIPv4DictRoutes);
 
     if (routes != NULL) {
        routes_list = (IPv4RouteListRef)(void*)CFDataGetBytePtr(routes);
 
     if (routes != NULL) {
        routes_list = (IPv4RouteListRef)(void*)CFDataGetBytePtr(routes);
@@ -364,7 +456,7 @@ ipv4_dict_get_ifname(CFDictionaryRef ipv4_dict)
     }
 
     ipv4_service_dict = CFDictionaryGetValue(ipv4_dict,
     }
 
     ipv4_service_dict = CFDictionaryGetValue(ipv4_dict,
-                                            kSCEntNetIPv4ServiceDict);
+                                            kIPv4DictService);
 
     if (isA_CFDictionary(ipv4_service_dict) == NULL) {
        return NULL;
 
     if (isA_CFDictionary(ipv4_service_dict) == NULL) {
        return NULL;
@@ -458,6 +550,14 @@ keyChangeListFree(keyChangeListRef keys)
     return;
 }
 
     return;
 }
 
+static Boolean
+keyChangeListActive(keyChangeListRef keys)
+{
+    return ((CFDictionaryGetCount(keys->set) > 0) ||
+           (CFArrayGetCount(keys->remove) > 0) ||
+           (CFArrayGetCount(keys->notify) > 0));
+}
+
 static void
 keyChangeListNotifyKey(keyChangeListRef keys, CFStringRef key)
 {
 static void
 keyChangeListNotifyKey(keyChangeListRef keys, CFStringRef key)
 {
@@ -482,13 +582,11 @@ keyChangeListSetValue(keyChangeListRef keys, CFStringRef key, CFTypeRef value)
 }
 
 static void
 }
 
 static void
-keyChangeListApplyToStore(keyChangeListRef keys, SCDynamicStoreRef session,
-                         CFStringRef network_change_msg)
+keyChangeListApplyToStore(keyChangeListRef keys, SCDynamicStoreRef session)
 {
     CFArrayRef         notify = keys->notify;
     CFArrayRef         remove = keys->remove;
     CFDictionaryRef    set = keys->set;
 {
     CFArrayRef         notify = keys->notify;
     CFArrayRef         remove = keys->remove;
     CFDictionaryRef    set = keys->set;
-    int                        status;
 
     if (CFArrayGetCount(notify) == 0) {
        notify = NULL;
 
     if (CFArrayGetCount(notify) == 0) {
        notify = NULL;
@@ -504,32 +602,87 @@ keyChangeListApplyToStore(keyChangeListRef keys, SCDynamicStoreRef session,
     }
     if (S_IPMonitor_debug & kDebugFlag1) {
        if (set != NULL) {
     }
     if (S_IPMonitor_debug & kDebugFlag1) {
        if (set != NULL) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: Setting:\n%@"),
-                 set);
+           my_log(LOG_DEBUG, "IPMonitor: Setting:\n%@", set);
        }
        if (remove != NULL) {
        }
        if (remove != NULL) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: Removing:\n%@"),
-                 remove);
+           my_log(LOG_DEBUG, "IPMonitor: Removing:\n%@", remove);
        }
        if (notify != NULL) {
        }
        if (notify != NULL) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: Notifying:\n%@"),
-                 notify);
+           my_log(LOG_DEBUG, "IPMonitor: Notifying:\n%@", notify);
        }
     }
     (void)SCDynamicStoreSetMultiple(session, set, remove, notify);
 
        }
     }
     (void)SCDynamicStoreSetMultiple(session, set, remove, notify);
 
-    status = notify_post("com.apple.system.config.network_change");
-    if (status == NOTIFY_STATUS_OK) {
-       if (CFStringGetLength(network_change_msg) != 0) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("network changed:%@"), network_change_msg);
-       } else {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("network changed."));
+    return;
+}
+
+static void
+S_nwi_ifstate_dump(nwi_ifstate_t ifstate, int i)
+{
+    const char *               addr_str;
+    void *                     address;
+    char                       ntopbuf[INET6_ADDRSTRLEN];
+    char                       vpn_ntopbuf[INET6_ADDRSTRLEN];
+    const struct sockaddr *    vpn_addr;
+
+    address = nwi_ifstate_get_address(ifstate);
+    addr_str = inet_ntop(ifstate->af, address, ntopbuf, sizeof(ntopbuf));
+    vpn_addr = nwi_ifstate_get_vpn_server(ifstate);
+    if (vpn_addr != NULL) {
+       _SC_sockaddr_to_string(nwi_ifstate_get_vpn_server(ifstate),
+                              vpn_ntopbuf,
+                              sizeof(vpn_ntopbuf));
+    }
+    my_log(LOG_DEBUG,
+          "    [%d]: %s%s%s%s rank 0x%x iaddr: %s%s%s reachability_flags %u",
+          i, ifstate->ifname,
+          ifstate->diff_str != NULL ? ifstate->diff_str : "",
+          (ifstate->flags & NWI_IFSTATE_FLAGS_HAS_DNS) != 0
+          ? " dns" : "",
+          (ifstate->flags & NWI_IFSTATE_FLAGS_NOT_IN_LIST) != 0
+          ? " never" : "",
+          ifstate->rank,
+          addr_str,
+          (vpn_addr != NULL) ? " vpn_server_addr: " : "",
+          (vpn_addr != NULL) ? vpn_ntopbuf : "",
+          ifstate->reach_flags);
+    return;
+}
+
+static void
+S_nwi_state_dump(nwi_state_t state)
+{
+    int                        i;
+    nwi_ifstate_t      scan;
+
+    if (state == NULL) {
+       my_log(LOG_DEBUG, "nwi_state = <none>");
+       return;
+    }
+    my_log(LOG_DEBUG,
+          "nwi_state = { "
+          "gen = %llu size = %u #ipv4 = %u #ipv6 = %u "
+          "reach_flags_v4 = %u reach_flags_v6 %u }",
+          state->generation_count,
+          state->size,
+          state->ipv4_count,
+          state->ipv6_count,
+          nwi_state_get_reachability_flags(state, AF_INET),
+          nwi_state_get_reachability_flags(state, AF_INET6));
+    if (state->ipv4_count) {
+       my_log(LOG_DEBUG, "IPv4:");
+       for (i = 0, scan = state->nwi_ifstates;
+            i < state->ipv4_count; i++, scan++) {
+           S_nwi_ifstate_dump(scan, i);
+       }
+    }
+    if (state->ipv6_count) {
+       my_log(LOG_DEBUG, "IPv6:");
+       for (i = 0, scan = state->nwi_ifstates + state->ipv6_start;
+            i < state->ipv6_count; i++, scan++) {
+           S_nwi_ifstate_dump(scan, i);
        }
        }
-    } else {
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPMonitor: notify_post() failed: error=%ld"), status);
     }
     }
-
     return;
 }
 
     return;
 }
 
@@ -547,6 +700,7 @@ S_is_network_boot()
     return (netboot);
 }
 
     return (netboot);
 }
 
+#if    !TARGET_IPHONE_SIMULATOR
 static __inline__ int
 inet6_dgram_socket()
 {
 static __inline__ int
 inet6_dgram_socket()
 {
@@ -585,6 +739,7 @@ siocdrdel_in6(int s, int if_index, const struct in6_addr * addr)
     return (ioctl(s, SIOCDRDEL_IN6, &dr));
 }
 #endif /* SIOCDRADD_IN6 */
     return (ioctl(s, SIOCDRDEL_IN6, &dr));
 }
 #endif /* SIOCDRADD_IN6 */
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 #ifdef RTF_IFSCOPE
 static boolean_t
 
 #ifdef RTF_IFSCOPE
 static boolean_t
@@ -597,7 +752,7 @@ S_is_scoped_routing_enabled()
                      &scopedroute, &len,
                      NULL, 0) == -1)
        && (errno != ENOENT)) {
                      &scopedroute, &len,
                      NULL, 0) == -1)
        && (errno != ENOENT)) {
-       SCLog(TRUE, LOG_ERR, CFSTR("sysctlbyname() failed: %s"), strerror(errno));
+       my_log(LOG_ERR, "sysctlbyname() failed: %s", strerror(errno));
     }
     return (scopedroute);
 }
     }
     return (scopedroute);
 }
@@ -612,7 +767,7 @@ S_is_scoped_v6_routing_enabled()
                      &scopedroute_v6, &len,
                      NULL, 0) == -1)
        && (errno != ENOENT)) {
                      &scopedroute_v6, &len,
                      NULL, 0) == -1)
        && (errno != ENOENT)) {
-       SCLog(TRUE, LOG_ERR, CFSTR("sysctlbyname() failed: %s"), strerror(errno));
+       my_log(LOG_ERR, "sysctlbyname() failed: %s", strerror(errno));
     }
     return (scopedroute_v6);
 }
     }
     return (scopedroute_v6);
 }
@@ -706,13 +861,15 @@ cfstring_to_ipvx(int family, CFStringRef str, void * addr, int addr_size)
     return (FALSE);
 }
 
     return (FALSE);
 }
 
-static boolean_t
+__private_extern__
+boolean_t
 cfstring_to_ip(CFStringRef str, struct in_addr * ip_p)
 {
     return (cfstring_to_ipvx(AF_INET, str, ip_p, sizeof(*ip_p)));
 }
 
 cfstring_to_ip(CFStringRef str, struct in_addr * ip_p)
 {
     return (cfstring_to_ipvx(AF_INET, str, ip_p, sizeof(*ip_p)));
 }
 
-static boolean_t
+__private_extern__
+boolean_t
 cfstring_to_ip6(CFStringRef str, struct in6_addr * ip6_p)
 {
     return (cfstring_to_ipvx(AF_INET6, str, ip6_p, sizeof(*ip6_p)));
 cfstring_to_ip6(CFStringRef str, struct in6_addr * ip6_p)
 {
     return (cfstring_to_ipvx(AF_INET6, str, ip6_p, sizeof(*ip6_p)));
@@ -838,14 +995,17 @@ IPv4RouteCopyDescriptionWithString(IPv4RouteRef r, CFMutableStringRef str)
                         IP_LIST(&r->gateway),
                         (r->ifname[0] != '\0') ? r->ifname : "<none>",
                         IP_LIST(&r->ifa));
                         IP_LIST(&r->gateway),
                         (r->ifname[0] != '\0') ? r->ifname : "<none>",
                         IP_LIST(&r->ifa));
-    if ((r->flags & kRouteIsNotSubnetLocalFlag) != 0) {
-       CFStringAppend(str, CFSTR(" [non-local]"));
-    }
-    else if ((r->flags & kRouteIsDirectToInterfaceFlag) != 0) {
-       CFStringAppend(str, CFSTR(" [direct]"));
+    if ((r->flags & kRouteIsNULLFlag) != 0) {
+       CFStringAppend(str, CFSTR(" [null]"));
     }
     }
-
-    switch(rank_assertion) {
+    else {
+       if ((r->flags & kRouteIsNotSubnetLocalFlag) != 0) {
+           CFStringAppend(str, CFSTR(" [non-local]"));
+       }
+       else if ((r->flags & kRouteIsDirectToInterfaceFlag) != 0) {
+           CFStringAppend(str, CFSTR(" [direct]"));
+       }
+       switch (rank_assertion) {
        case kRankAssertionFirst:
            CFStringAppend(str, CFSTR(" [first]"));
            break;
        case kRankAssertionFirst:
            CFStringAppend(str, CFSTR(" [first]"));
            break;
@@ -857,10 +1017,10 @@ IPv4RouteCopyDescriptionWithString(IPv4RouteRef r, CFMutableStringRef str)
            break;
        default:
            break;
            break;
        default:
            break;
-    }
-
-    if ((r->flags & kRouteIsScopedFlag) != 0) {
-       CFStringAppend(str, CFSTR(" [SCOPED]"));
+       }
+       if ((r->flags & kRouteIsScopedFlag) != 0) {
+           CFStringAppend(str, CFSTR(" [SCOPED]"));
+       }
     }
     return;
 }
     }
     return;
 }
@@ -886,11 +1046,11 @@ IPv4RoutePrint(IPv4RouteRef route)
 }
 
 static __inline__ void
 }
 
 static __inline__ void
-IPv4RouteLog(IPv4RouteRef route)
+IPv4RouteLog(int level, IPv4RouteRef route)
 {
     CFStringRef        str = IPv4RouteCopyDescription(route);
 
 {
     CFStringRef        str = IPv4RouteCopyDescription(route);
 
-    SCLog(TRUE, LOG_NOTICE, CFSTR("%@"), str);
+    my_log(level, "%@", str);
     CFRelease(str);
     return;
 }
     CFRelease(str);
     return;
 }
@@ -936,8 +1096,8 @@ IPv4RouteCompare(IPv4RouteRef a, Rank a_rank,
        }
        a_str = IPv4RouteCopyDescription(a);
        b_str = IPv4RouteCopyDescription(b);
        }
        a_str = IPv4RouteCopyDescription(a);
        b_str = IPv4RouteCopyDescription(b);
-       SCLog(TRUE, LOG_NOTICE, CFSTR("%@ rank %u %c %@ rank %u"),
-             a_str, a_rank, ch, b_str, b_rank);
+       my_log(LOG_DEBUG, "%@ rank 0x%x %c %@ rank 0x%x",
+              a_str, a_rank, ch, b_str, b_rank);
        CFRelease(a_str);
        CFRelease(b_str);
     }
        CFRelease(a_str);
        CFRelease(b_str);
     }
@@ -973,11 +1133,11 @@ IPv4RouteListPrint(IPv4RouteListRef routes)
 }
 
 static __inline__ void
 }
 
 static __inline__ void
-IPv4RouteListLog(IPv4RouteListRef routes)
+IPv4RouteListLog(int level, IPv4RouteListRef routes)
 {
     CFStringRef        str = IPv4RouteListCopyDescription(routes);
 
 {
     CFStringRef        str = IPv4RouteListCopyDescription(routes);
 
-    SCLog(TRUE, LOG_NOTICE, CFSTR("%@"), str);
+    my_log(level, "%@", str);
     CFRelease(str);
     return;
 }
     CFRelease(str);
     return;
 }
@@ -988,6 +1148,7 @@ IPv4RouteListComputeSize(unsigned int n)
     return (offsetof(IPv4RouteList, list[n]));
 }
 
     return (offsetof(IPv4RouteList, list[n]));
 }
 
+#if    !TARGET_IPHONE_SIMULATOR
 static IPv4RouteRef
 IPv4RouteListFindRoute(IPv4RouteListRef routes, IPv4RouteRef route)
 {
 static IPv4RouteRef
 IPv4RouteListFindRoute(IPv4RouteListRef routes, IPv4RouteRef route)
 {
@@ -1054,6 +1215,7 @@ IPv4RouteListApply(IPv4RouteListRef old_routes, IPv4RouteListRef new_routes,
     }
     return;
 }
     }
     return;
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 /*
  * Function: IPv4RouteListAddRoute
 
 /*
  * Function: IPv4RouteListAddRoute
@@ -1088,6 +1250,7 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size,
 
     if (routes == NULL) {
        routes = (IPv4RouteListRef)malloc(IPv4RouteListComputeSize(init_size));
 
     if (routes == NULL) {
        routes = (IPv4RouteListRef)malloc(IPv4RouteListComputeSize(init_size));
+       bzero(routes, sizeof(*routes));
        routes->size = init_size;
        routes->count = 0;
     }
        routes->size = init_size;
        routes->count = 0;
     }
@@ -1144,7 +1307,8 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size,
                if (scan->flags & kRouteIsScopedFlag) {
                    is_scoped = TRUE;
                }
                if (scan->flags & kRouteIsScopedFlag) {
                    is_scoped = TRUE;
                }
-               ROUTELIST_DEBUG(("Hit 4:replacing [%d] rank %u < %u\n", i,
+               ROUTELIST_DEBUG(("Hit 4:replacing [%d] rank 0x%x < 0x%x\n",
+                                i,
                                 this_rank,
                                 scan->rank), kDebugFlag8);
                *scan = *this_route;
                                 this_rank,
                                 scan->rank), kDebugFlag8);
                *scan = *this_route;
@@ -1208,6 +1372,9 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size,
     /* copy the route */
     routes->list[where] = *this_route;
     routes->list[where].rank = this_rank;
     /* copy the route */
     routes->list[where] = *this_route;
     routes->list[where].rank = this_rank;
+    if (RANK_ASSERTION_MASK(this_rank) == kRankAssertionNever) {
+       routes->list[where].flags |= kRouteIsScopedFlag;
+    }
 
     /* set the scope */
     switch (scope_which) {
 
     /* set the scope */
     switch (scope_which) {
@@ -1284,6 +1451,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
                                  CFStringRef primaryRank)
 {
     struct in_addr     addr = { 0 };
                                  CFStringRef primaryRank)
 {
     struct in_addr     addr = { 0 };
+    boolean_t          exclude_from_nwi = FALSE;
     RouteFlags         flags = 0;
     unsigned int       ifindex;
     char               ifn[IFNAMSIZ];
     RouteFlags         flags = 0;
     unsigned int       ifindex;
     char               ifn[IFNAMSIZ];
@@ -1324,6 +1492,8 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
        if (ntohl(subnet.s_addr) != IN_LINKLOCALNETNUM) {
            add_subnet = TRUE;
            n++;
        if (ntohl(subnet.s_addr) != IN_LINKLOCALNETNUM) {
            add_subnet = TRUE;
            n++;
+       } else if (router.s_addr == 0) {
+           exclude_from_nwi = TRUE;
        }
     }
     if (addr.s_addr == 0) {
        }
     }
     if (addr.s_addr == 0) {
@@ -1331,8 +1501,19 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
        return (NULL);
     }
     if (router.s_addr == 0) {
        return (NULL);
     }
     if (router.s_addr == 0) {
+       /*
+        * If no router is configured, demote the rank. If there's already
+        * a rank assertion that indicates RankNever, use that, otherwise
+        * use RankLast.
+        */
        flags |= kRouteIsDirectToInterfaceFlag;
        flags |= kRouteIsDirectToInterfaceFlag;
-       rank = kRankAssertionLast;
+       if (primaryRank != NULL
+           && PrimaryRankGetRankAssertion(primaryRank) == kRankAssertionNever) {
+           rank = kRankAssertionNever;
+       }
+       else {
+           rank = kRankAssertionLast;
+       }
     }
     else {
        /*
     }
     else {
        /*
@@ -1350,6 +1531,11 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
        }
     }
 
        }
     }
 
+    if (S_dict_get_boolean(dict, kIsNULL, FALSE)) {
+       exclude_from_nwi = TRUE;
+       flags |= kRouteIsNULLFlag;
+    }
+
     if (rank == kRankAssertionNever) {
        flags |= kRouteIsScopedFlag;
     }
     if (rank == kRankAssertionNever) {
        flags |= kRouteIsScopedFlag;
     }
@@ -1370,6 +1556,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
     }
     bzero(routes, IPv4RouteListComputeSize(n));
     routes->count = n;
     }
     bzero(routes, IPv4RouteListComputeSize(n));
     routes->count = n;
+    routes->exclude_from_nwi = exclude_from_nwi;
 
     /* start at the beginning */
     r = routes->list;
 
     /* start at the beginning */
     r = routes->list;
@@ -1387,14 +1574,14 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
            r->gateway = addr;
        }
        r->rank = rank;
            r->gateway = addr;
        }
        r->rank = rank;
-       if (r->rank == kRankAssertionNever) {
-           r->flags |= kRouteIsScopedFlag;
-       }
        r++;
     }
 
     /* add the subnet route */
     if (add_subnet) {
        r++;
     }
 
     /* add the subnet route */
     if (add_subnet) {
+       if ((flags & kRouteIsNULLFlag) != 0) {
+           r->flags |= kRouteIsNULLFlag;
+       }
        r->ifindex = ifindex;
        r->gateway = addr;
        r->dest = subnet;
        r->ifindex = ifindex;
        r->gateway = addr;
        r->dest = subnet;
@@ -1402,11 +1589,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes,
        strlcpy(r->ifname, ifn, sizeof(r->ifname));
        r->ifa = addr;
        r->rank = rank;
        strlcpy(r->ifname, ifn, sizeof(r->ifname));
        r->ifa = addr;
        r->rank = rank;
-       if (r->rank == kRankAssertionNever) {
-           r->flags |= kRouteIsScopedFlag;
-       }
     }
     }
-
     return (routes);
 }
 
     return (routes);
 }
 
@@ -1467,8 +1650,8 @@ service_dict_copy(CFStringRef serviceID)
 }
 
 static void
 }
 
 static void
-dump_service_entity(CFStringRef serviceID, CFStringRef entity,
-                   CFStringRef operation, CFTypeRef val)
+log_service_entity(int level, CFStringRef serviceID, CFStringRef entity,
+                  CFStringRef operation, CFTypeRef val)
 {
 
     CFDataRef  route_list;
 {
 
     CFDataRef  route_list;
@@ -1477,14 +1660,14 @@ dump_service_entity(CFStringRef serviceID, CFStringRef entity,
     if (CFEqual(entity, kSCEntNetIPv4) && isA_CFDictionary(val) != NULL) {
        CFDictionaryRef    service_dict = NULL;
 
     if (CFEqual(entity, kSCEntNetIPv4) && isA_CFDictionary(val) != NULL) {
        CFDictionaryRef    service_dict = NULL;
 
-       route_list = CFDictionaryGetValue(val, kSCEntNetIPv4RouteList);
+       route_list = CFDictionaryGetValue(val, kIPv4DictRoutes);
        if (route_list != NULL) {
            /* ALIGN: CF should align to at least 8-byte boundaries */
            this_val = IPv4RouteListCopyDescription((IPv4RouteListRef)
                                                    (void *)CFDataGetBytePtr(route_list));
        }
 
        if (route_list != NULL) {
            /* ALIGN: CF should align to at least 8-byte boundaries */
            this_val = IPv4RouteListCopyDescription((IPv4RouteListRef)
                                                    (void *)CFDataGetBytePtr(route_list));
        }
 
-       service_dict = CFDictionaryGetValue(val, kSCEntNetIPv4ServiceDict);
+       service_dict = CFDictionaryGetValue(val, kIPv4DictService);
 
        if (service_dict != NULL && isA_CFDictionary(service_dict) != NULL) {
            if (this_val == NULL) {
 
        if (service_dict != NULL && isA_CFDictionary(service_dict) != NULL) {
            if (this_val == NULL) {
@@ -1497,8 +1680,8 @@ dump_service_entity(CFStringRef serviceID, CFStringRef entity,
     if (val == NULL) {
        val = CFSTR("<none>");
     }
     if (val == NULL) {
        val = CFSTR("<none>");
     }
-    SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: serviceID %@ %@ %@ value = %@"),
-         serviceID, operation, entity, val);
+    my_log(level, "IPMonitor: serviceID %@ %@ %@ value = %@",
+          serviceID, operation, entity, val);
     my_CFRelease(&this_val);
     return;
 }
     my_CFRelease(&this_val);
     return;
 }
@@ -1516,8 +1699,8 @@ service_dict_set(CFStringRef serviceID, CFStringRef entity,
     if (new_val == NULL) {
        if (old_val != NULL) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     if (new_val == NULL) {
        if (old_val != NULL) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               dump_service_entity(serviceID, entity, CFSTR("Removed:"),
-                                  old_val);
+               log_service_entity(LOG_DEBUG, serviceID, entity,
+                                  CFSTR("Removed:"), old_val);
            }
            CFDictionaryRemoveValue(service_dict, entity);
            changed = TRUE;
            }
            CFDictionaryRemoveValue(service_dict, entity);
            changed = TRUE;
@@ -1526,10 +1709,10 @@ service_dict_set(CFStringRef serviceID, CFStringRef entity,
     else {
        if (old_val == NULL || CFEqual(new_val, old_val) == FALSE) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     else {
        if (old_val == NULL || CFEqual(new_val, old_val) == FALSE) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               dump_service_entity(serviceID, entity,
-                                   CFSTR("Changed: old"), old_val);
-               dump_service_entity(serviceID, entity,
-                                   CFSTR("Changed: new"), new_val);
+               log_service_entity(LOG_DEBUG, serviceID, entity,
+                                  CFSTR("Changed: old"), old_val);
+               log_service_entity(LOG_DEBUG, serviceID, entity,
+                                  CFSTR("Changed: new"), new_val);
            }
            CFDictionarySetValue(service_dict, entity, new_val);
            changed = TRUE;
            }
            CFDictionarySetValue(service_dict, entity, new_val);
            changed = TRUE;
@@ -1576,7 +1759,7 @@ copy_dhcp_hostname(CFStringRef serviceID)
     }
 
     service_dict =
     }
 
     service_dict =
-       CFDictionaryGetValue(dict, kSCEntNetIPv4ServiceDict);
+       CFDictionaryGetValue(dict, kIPv4DictService);
 
     if (service_dict == NULL
        || isA_CFDictionary(service_dict) == NULL) {
 
     if (service_dict == NULL
        || isA_CFDictionary(service_dict) == NULL) {
@@ -1593,8 +1776,9 @@ copy_dhcp_hostname(CFStringRef serviceID)
     return (hostname);
 }
 
     return (hostname);
 }
 
-static boolean_t
-ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
+#if    !TARGET_IPHONE_SIMULATOR
+static void
+ipv6_service_update_router(CFStringRef serviceID, CFDictionaryRef new_val)
 {
 #ifdef SIOCDRADD_IN6
     int                        if_index;
 {
 #ifdef SIOCDRADD_IN6
     int                        if_index;
@@ -1626,15 +1810,16 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
     }
     s = inet6_dgram_socket();
     if (s < 0) {
     }
     s = inet6_dgram_socket();
     if (s < 0) {
-       syslog(LOG_ERR,
-              "IPMonitor: ipv6_service_dict_set: socket failed, %s",
+       my_log(LOG_ERR,
+              "IPMonitor: ipv6_service_update_router: socket failed, %s",
               strerror(errno));
        goto done;
     }
     if (new_val != NULL) {
        new_router = CFDictionaryGetValue(new_val, kSCPropNetIPv6Router);
     }
               strerror(errno));
        goto done;
     }
     if (new_val != NULL) {
        new_router = CFDictionaryGetValue(new_val, kSCPropNetIPv6Router);
     }
-    if (old_router != NULL
+    if (S_dict_get_boolean(old_val, kIsNULL, FALSE) == FALSE
+       && old_router != NULL
        && (new_router == NULL || CFEqual(old_router, new_router) == FALSE)) {
        /* remove the old Router */
        if (cfstring_to_ip6(old_router, &router_ip)) {
        && (new_router == NULL || CFEqual(old_router, new_router) == FALSE)) {
        /* remove the old Router */
        if (cfstring_to_ip6(old_router, &router_ip)) {
@@ -1645,7 +1830,7 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
            }
            if (siocdrdel_in6(s, if_index, &router_ip) < 0) {
                if (errno != EINVAL) {
            }
            if (siocdrdel_in6(s, if_index, &router_ip) < 0) {
                if (errno != EINVAL) {
-                   syslog(LOG_ERR,
+                   my_log(LOG_ERR,
                           "IPMonitor: siocdrdel_in6(%s, %s) failed, %s",
                           ifn,
                           inet_ntop(AF_INET6, &router_ip,
                           "IPMonitor: siocdrdel_in6(%s, %s) failed, %s",
                           ifn,
                           inet_ntop(AF_INET6, &router_ip,
@@ -1654,7 +1839,7 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
                }
            }
            else if (S_IPMonitor_debug & kDebugFlag1) {
                }
            }
            else if (S_IPMonitor_debug & kDebugFlag1) {
-               syslog(LOG_NOTICE,
+               my_log(LOG_DEBUG,
                       "IPMonitor: %s removed default route %s",
                       ifn,
                       inet_ntop(AF_INET6, &router_ip,
                       "IPMonitor: %s removed default route %s",
                       ifn,
                       inet_ntop(AF_INET6, &router_ip,
@@ -1663,7 +1848,8 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
        }
     }
     /* add the new Router */
        }
     }
     /* add the new Router */
-    if (cfstring_to_ip6(new_router, &router_ip)) {
+    if (S_dict_get_boolean(new_val, kIsNULL, FALSE) == FALSE
+       && cfstring_to_ip6(new_router, &router_ip)) {
        if (IN6_IS_ADDR_LINKLOCAL(&router_ip) ||
            IN6_IS_ADDR_MC_LINKLOCAL(&router_ip)) {
            /* scope it */
        if (IN6_IS_ADDR_LINKLOCAL(&router_ip) ||
            IN6_IS_ADDR_MC_LINKLOCAL(&router_ip)) {
            /* scope it */
@@ -1671,7 +1857,7 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
        }
        if (siocdradd_in6(s, if_index, &router_ip, 0) < 0) {
            if (errno != EINVAL) {
        }
        if (siocdradd_in6(s, if_index, &router_ip, 0) < 0) {
            if (errno != EINVAL) {
-               syslog(LOG_ERR,
+               my_log(LOG_ERR,
                       "IPMonitor: siocdradd_in6(%s, %s) failed, %s",
                       ifn,
                       inet_ntop(AF_INET6, &router_ip,
                       "IPMonitor: siocdradd_in6(%s, %s) failed, %s",
                       ifn,
                       inet_ntop(AF_INET6, &router_ip,
@@ -1680,7 +1866,7 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
            }
        }
        else if (S_IPMonitor_debug & kDebugFlag1) {
            }
        }
        else if (S_IPMonitor_debug & kDebugFlag1) {
-           syslog(LOG_NOTICE,
+           my_log(LOG_DEBUG,
                   "IPMonitor: %s added default route %s",
                   ifn,
                   inet_ntop(AF_INET6, &router_ip,
                   "IPMonitor: %s added default route %s",
                   ifn,
                   inet_ntop(AF_INET6, &router_ip,
@@ -1689,10 +1875,11 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val)
     }
     close(s);
 
     }
     close(s);
 
- done:
 done:
 #endif /* SIOCDRADD_IN6 */
 #endif /* SIOCDRADD_IN6 */
-    return (service_dict_set(serviceID, kSCEntNetIPv6, new_val));
+    return;
 }
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 #define        ALLOW_EMPTY_STRING      0x1
 
 
 #define        ALLOW_EMPTY_STRING      0x1
 
@@ -1863,19 +2050,19 @@ get_ipv4_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
        }
     }
     else {
        }
     }
     else {
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPMonitor: %@ invalid IPv4 dictionary = %@"),
-             serviceID,
-             dict);
+       my_log(LOG_NOTICE,
+              "IPMonitor: %@ invalid IPv4 dictionary = %@",
+              serviceID,
+              dict);
     }
   done:
     if (routes_data != NULL) {
        CFStringRef     keys[2];
        CFTypeRef       values[2];
 
     }
   done:
     if (routes_data != NULL) {
        CFStringRef     keys[2];
        CFTypeRef       values[2];
 
-       keys[0] = kSCEntNetIPv4ServiceDict;
+       keys[0] = kIPv4DictService;
        values[0] = dict;
        values[0] = dict;
-       keys[1] = kSCEntNetIPv4RouteList;
+       keys[1] = kIPv4DictRoutes;
        values[1] = routes_data;
 
        aggregated_dict = CFDictionaryCreate(NULL,
        values[1] = routes_data;
 
        aggregated_dict = CFDictionaryCreate(NULL,
@@ -1920,9 +2107,9 @@ get_ipv6_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
     }
     if (valid_ip == FALSE) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     }
     if (valid_ip == FALSE) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: %@ has no valid IPv6 address, ignoring"),
-                 serviceID);
+           my_log(LOG_DEBUG,
+                  "IPMonitor: %@ has no valid IPv6 address, ignoring",
+                  serviceID);
        }
        goto done;
     }
        }
        goto done;
     }
@@ -1947,7 +2134,12 @@ get_ipv6_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
     new_dict = dict;
 
  done:
     new_dict = dict;
 
  done:
-    changed = ipv6_service_dict_set(serviceID, new_dict);
+
+#if    !TARGET_IPHONE_SIMULATOR
+    ipv6_service_update_router(serviceID, new_dict);
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
+    changed = service_dict_set(serviceID, kSCEntNetIPv6, new_dict);
     if (new_dict == NULL) {
        /* clean up the rank too */
        CFDictionaryRemoveValue(S_ipv6_service_rank_dict, serviceID);
     if (new_dict == NULL) {
        /* clean up the rank too */
        CFDictionaryRemoveValue(S_ipv6_service_rank_dict, serviceID);
@@ -1965,18 +2157,21 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos,
 
     count = CFArrayGetCount(in_servers);
     for (i = 0; i < count; i++) {
 
     count = CFArrayGetCount(in_servers);
     for (i = 0; i < count; i++) {
-       CFStringRef     addr = CFArrayGetValueAtIndex(in_servers, i);
+       CFStringRef     addr;
        struct in6_addr ipv6_addr;
        struct in_addr  ip_addr;
 
        struct in6_addr ipv6_addr;
        struct in_addr  ip_addr;
 
+       addr = CFArrayGetValueAtIndex(in_servers, i);
+       assert(addr != NULL);
+
        if (cfstring_to_ip(addr, &ip_addr)) {
            /* IPv4 address */
            if ((active_protos & kProtocolFlagsIPv4) == 0
                && ntohl(ip_addr.s_addr) != INADDR_LOOPBACK) {
                if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        if (cfstring_to_ip(addr, &ip_addr)) {
            /* IPv4 address */
            if ((active_protos & kProtocolFlagsIPv4) == 0
                && ntohl(ip_addr.s_addr) != INADDR_LOOPBACK) {
                if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-                   syslog(LOG_NOTICE,
+                   my_log(LOG_DEBUG,
                           "IPMonitor: no IPv4 connectivity, "
                           "IPMonitor: no IPv4 connectivity, "
-                          "ignoring DNS server address " IP_FORMAT,
+                          "ignoring DNS server address ", IP_FORMAT,
                           IP_LIST(&ip_addr));
                }
                continue;
                           IP_LIST(&ip_addr));
                }
                continue;
@@ -1991,11 +2186,11 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos,
                if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
                    char        ntopbuf[INET6_ADDRSTRLEN];
 
                if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
                    char        ntopbuf[INET6_ADDRSTRLEN];
 
-                   syslog(LOG_NOTICE,
+                   my_log(LOG_DEBUG,
                           "IPMonitor: no IPv6 connectivity, "
                           "ignoring DNS server address %s",
                           "IPMonitor: no IPv6 connectivity, "
                           "ignoring DNS server address %s",
-                          inet_ntop(AF_INET6, &ipv6_addr,
-                                    ntopbuf, sizeof(ntopbuf)));
+                           inet_ntop(AF_INET6, &ipv6_addr,
+                                     ntopbuf, sizeof(ntopbuf)));
                }
                continue;
            }
                }
                continue;
            }
@@ -2015,9 +2210,9 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos,
        }
        else {
            /* bad IP address */
        }
        else {
            /* bad IP address */
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: ignoring bad DNS server address '%@'"),
-                 addr);
+           my_log(LOG_NOTICE,
+                  "IPMonitor: ignoring bad DNS server address '%@'",
+                  addr);
            continue;
        }
 
            continue;
        }
 
@@ -2127,6 +2322,8 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
        kSCPropNetDNSSearchOrder,
        kSCPropNetDNSServerPort,
        kSCPropNetDNSServerTimeout,
        kSCPropNetDNSSearchOrder,
        kSCPropNetDNSServerPort,
        kSCPropNetDNSServerTimeout,
+       kSCPropNetDNSServiceIdentifier,
+       kSCPropNetDNSSupplementalMatchDomainsNoSearch,
     };
     IPv4RouteListRef           routes = NULL;
 
     };
     IPv4RouteListRef           routes = NULL;
 
@@ -2216,7 +2413,7 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
     }
 
     if (active_protos == kProtocolFlagsNone) {
     }
 
     if (active_protos == kProtocolFlagsNone) {
-       /* there is no IPv4 nor IPv6, only supplemental DNS */
+       /* there is no IPv4 nor IPv6, only supplemental or service-specific DNS */
        if (CFDictionaryContainsKey(new_dict,
                                    kSCPropNetDNSSupplementalMatchDomains)) {
            /* only keep State: supplemental */
        if (CFDictionaryContainsKey(new_dict,
                                    kSCPropNetDNSSupplementalMatchDomains)) {
            /* only keep State: supplemental */
@@ -2224,6 +2421,18 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict,
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSearchDomains);
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSearchOrder);
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSortList);
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSearchDomains);
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSearchOrder);
            CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSortList);
+
+           if ((interface == NULL) && (setup_dict == NULL) && (state_dict != NULL)) {
+               /*
+                * for supplemental-only configurations, add any scoped (or
+                * wild-card "*") interface
+                */
+               interface = CFDictionaryGetValue(state_dict, kSCPropInterfaceName);
+           }
+       } else if (CFDictionaryContainsKey(new_dict, kSCPropNetDNSServiceIdentifier) &&
+                  (interface == NULL) &&
+                  (state_dict != NULL)) {
+           interface = CFDictionaryGetValue(state_dict, kSCPropInterfaceName);
        } else {
            goto done;
        }
        } else {
            goto done;
        }
@@ -2663,11 +2872,67 @@ services_info_get_interface(CFDictionaryRef services_info,
     return (interface);
 }
 
     return (interface);
 }
 
+
+
+static const CFStringRef *statusEntityNames[] = {
+    &kSCEntNetIPSec,
+    &kSCEntNetPPP,
+    &kSCEntNetVPN,
+};
+
+static Boolean
+get_transient_service_changes(CFStringRef serviceID, CFDictionaryRef services_info)
+{
+    boolean_t  changed = FALSE;
+    int                i;
+
+    static const struct {
+       const CFStringRef       *entityName;
+       const CFStringRef       *statusKey;
+    } transientServiceInfo[] = {
+       { &kSCEntNetIPSec,      &kSCPropNetIPSecStatus  },
+       { &kSCEntNetPPP,        &kSCPropNetPPPStatus    },
+       { &kSCEntNetVPN,        &kSCPropNetVPNStatus    },
+    };
+
+    for (i = 0; i < sizeof(transientServiceInfo)/sizeof(transientServiceInfo[0]); i++) {
+       CFDictionaryRef         dict;
+       CFNumberRef             status          = NULL;
+       CFMutableDictionaryRef  ts_dict         = NULL;
+
+       dict = get_service_state_entity(services_info, serviceID, *transientServiceInfo[i].entityName);
+
+       if (isA_CFDictionary(dict) != NULL) {
+           status = CFDictionaryGetValue(dict, *transientServiceInfo[i].statusKey);
+       }
+
+       if (isA_CFNumber(status) != NULL) {
+           ts_dict = CFDictionaryCreateMutable(NULL,
+                                                0,
+                                                &kCFTypeDictionaryKeyCallBacks,
+                                                &kCFTypeDictionaryValueCallBacks);
+           CFDictionaryAddValue(ts_dict,
+                                *transientServiceInfo[i].statusKey,
+                                status);
+       }
+
+       if (service_dict_set(serviceID, *transientServiceInfo[i].entityName, ts_dict)) {
+           changed = TRUE;
+       }
+
+       if (ts_dict != NULL) {
+           CFRelease(ts_dict);
+       }
+    }
+    return (changed);
+}
+
 static boolean_t
 get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options,
                 CFDictionaryRef setup_options, CFDictionaryRef services_info)
 {
     boolean_t                  changed         = FALSE;
 static boolean_t
 get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options,
                 CFDictionaryRef setup_options, CFDictionaryRef services_info)
 {
     boolean_t                  changed         = FALSE;
+    CFBooleanRef               ip_is_coupled   = NULL;
     CFMutableDictionaryRef      new_dict       = NULL;
     CFStringRef                        new_rank        = NULL;
     CFStringRef                        setup_rank      = NULL;
     CFMutableDictionaryRef      new_dict       = NULL;
     CFStringRef                        new_rank        = NULL;
     CFStringRef                        setup_rank      = NULL;
@@ -2683,13 +2948,28 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options,
      *
      * Note 2: Rank Never > Rank Last > Rank First > Rank None
      */
      *
      * Note 2: Rank Never > Rank Last > Rank First > Rank None
      */
-    if (isA_CFDictionary(setup_options)) {
-       setup_rank = CFDictionaryGetValue(setup_options, kSCPropNetServicePrimaryRank);
-       setup_rank = isA_CFString(setup_rank);
-    }
     if (isA_CFDictionary(state_options)) {
     if (isA_CFDictionary(state_options)) {
-       state_rank = CFDictionaryGetValue(state_options, kSCPropNetServicePrimaryRank);
+       CFBooleanRef    coupled;
+
+       state_rank
+           = CFDictionaryGetValue(state_options, kSCPropNetServicePrimaryRank);
        state_rank = isA_CFString(state_rank);
        state_rank = isA_CFString(state_rank);
+       coupled = CFDictionaryGetValue(state_options, kIPIsCoupled);
+       if (isA_CFBoolean(coupled) != NULL) {
+           ip_is_coupled = coupled;
+       }
+    }
+    if (isA_CFDictionary(setup_options)) {
+       CFBooleanRef    coupled;
+
+       setup_rank
+           = CFDictionaryGetValue(setup_options, kSCPropNetServicePrimaryRank);
+       setup_rank = isA_CFString(setup_rank);
+
+       coupled = CFDictionaryGetValue(setup_options, kIPIsCoupled);
+       if (isA_CFBoolean(coupled) != NULL) {
+           ip_is_coupled = coupled;
+       }
     }
 
     if (((setup_rank != NULL) && CFEqual(setup_rank, kSCValNetServicePrimaryRankNever)) ||
     }
 
     if (((setup_rank != NULL) && CFEqual(setup_rank, kSCValNetServicePrimaryRankNever)) ||
@@ -2716,21 +2996,31 @@ get_rank_changes(CFStringRef serviceID, CFDictionaryRef state_options,
        if (interface != NULL) {
            new_rank = CFDictionaryGetValue(S_if_rank_dict, interface);
            if (S_IPMonitor_debug & kDebugFlag1) {
        if (interface != NULL) {
            new_rank = CFDictionaryGetValue(S_if_rank_dict, interface);
            if (S_IPMonitor_debug & kDebugFlag1) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("serviceID %@ interface %@ rank = %@"),
-                     serviceID, interface,
-                     (new_rank != NULL) ? new_rank : CFSTR("<none>"));
+               my_log(LOG_DEBUG,
+                      "serviceID %@ interface %@ rank = %@",
+                      serviceID, interface,
+                      (new_rank != NULL) ? new_rank : CFSTR("<none>"));
            }
        }
     }
 
            }
        }
     }
 
-    if (new_rank != NULL) {
+
+    if (ip_is_coupled != NULL && CFBooleanGetValue(ip_is_coupled) == FALSE) {
+       /* don't bother setting a value if it's the default */
+       ip_is_coupled = NULL;
+    }
+    if (new_rank != NULL || ip_is_coupled != NULL) {
        new_dict = CFDictionaryCreateMutable(NULL, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
        new_dict = CFDictionaryCreateMutable(NULL, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
-       CFDictionarySetValue(new_dict, kSCPropNetServicePrimaryRank, new_rank);
+       if (new_rank != NULL) {
+           CFDictionarySetValue(new_dict, kSCPropNetServicePrimaryRank,
+                                new_rank);
+       }
+       if (ip_is_coupled != NULL) {
+           CFDictionarySetValue(new_dict, kIPIsCoupled, kCFBooleanTrue);
+       }
     }
     }
-
     changed = service_dict_set(serviceID, kSCEntNetService, new_dict);
     my_CFRelease(&new_dict);
     return (changed);
     changed = service_dict_set(serviceID, kSCEntNetService, new_dict);
     my_CFRelease(&new_dict);
     return (changed);
@@ -2758,14 +3048,14 @@ if_rank_set(CFStringRef ifname, CFDictionaryRef rank_dict)
     /* specific rank is asserted */
     if (rank != NULL) {
        if (S_IPMonitor_debug & kDebugFlag1) {
     /* specific rank is asserted */
     if (rank != NULL) {
        if (S_IPMonitor_debug & kDebugFlag1) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("Interface %@ asserted rank %@"),
-                 ifname, rank);
+           my_log(LOG_DEBUG, "Interface %@ asserted rank %@",
+                  ifname, rank);
        }
        CFDictionarySetValue(S_if_rank_dict, ifname, rank);
     } else {
        if (S_IPMonitor_debug & kDebugFlag1) {
        }
        CFDictionarySetValue(S_if_rank_dict, ifname, rank);
     } else {
        if (S_IPMonitor_debug & kDebugFlag1) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("Interface %@ removed rank."),
-                 ifname);
+           my_log(LOG_DEBUG, "Interface %@ removed rank",
+                  ifname);
        }
        CFDictionaryRemoveValue(S_if_rank_dict, ifname);
     }
        }
        CFDictionaryRemoveValue(S_if_rank_dict, ifname);
     }
@@ -2843,10 +3133,59 @@ add_service_keys(CFStringRef serviceID, CFMutableArrayRef keys, CFMutableArrayRe
     CFArrayAppendValue(patterns, key);
     CFRelease(key);
 
     CFArrayAppendValue(patterns, key);
     CFRelease(key);
 
+    return;
+}
+
+static void
+add_status_keys(CFStringRef service_id, CFMutableArrayRef patterns)
+{
+    int            i;
+
+    for (i = 0; i < sizeof(statusEntityNames)/sizeof(statusEntityNames[0]); i++) {
+       CFStringRef     pattern;
+
+       pattern = state_service_key(service_id, *statusEntityNames[i]);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+    }
 
     return;
 }
 
 
     return;
 }
 
+static const CFStringRef *reachabilitySetupKeys[] = {
+    &kSCEntNetPPP,
+    &kSCEntNetInterface,
+    &kSCEntNetIPv4,
+    &kSCEntNetIPv6,
+};
+
+
+static void
+add_reachability_keys(CFMutableArrayRef patterns)
+{
+    int                i;
+
+    for (i = 0; i < sizeof(reachabilitySetupKeys)/(sizeof(reachabilitySetupKeys[0])); i++)
+    {
+       CFStringRef pattern;
+       pattern = setup_service_key(kSCCompAnyRegex, *reachabilitySetupKeys[i]);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+    }
+}
+
+
+static void
+add_vpn_keys(CFMutableArrayRef patterns)
+{
+    CFStringRef        pattern;
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetVPN);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+}
+
+
 static CFDictionaryRef
 services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list,
                   CFArrayRef if_rank_list)
 static CFDictionaryRef
 services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list,
                   CFArrayRef if_rank_list)
@@ -2870,8 +3209,13 @@ services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list,
        CFStringRef     serviceID = CFArrayGetValueAtIndex(service_list, s);
 
        add_service_keys(serviceID, get_keys, get_patterns);
        CFStringRef     serviceID = CFArrayGetValueAtIndex(service_list, s);
 
        add_service_keys(serviceID, get_keys, get_patterns);
+       add_status_keys(serviceID, get_keys);
     }
 
     }
 
+    add_reachability_keys(get_patterns);
+
+    add_vpn_keys(get_patterns);
+
     if_count = (if_rank_list != NULL)
               ? CFArrayGetCount(if_rank_list) : 0;
     for (s = 0; s < if_count; s++) {
     if_count = (if_rank_list != NULL)
               ? CFArrayGetCount(if_rank_list) : 0;
     for (s = 0; s < if_count; s++) {
@@ -2889,20 +3233,24 @@ services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list,
     return (info);
 }
 
     return (info);
 }
 
-static int                     rtm_seq = 0;
+#if    !TARGET_IPHONE_SIMULATOR
+static int     rtm_seq = 0;
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 
+#if    !TARGET_IPHONE_SIMULATOR
 static int
 route_open_socket(void)
 {
     int sockfd;
 
     if ((sockfd = socket(PF_ROUTE, SOCK_RAW, PF_ROUTE)) == -1) {
 static int
 route_open_socket(void)
 {
     int sockfd;
 
     if ((sockfd = socket(PF_ROUTE, SOCK_RAW, PF_ROUTE)) == -1) {
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPMonitor: route_open_socket: socket failed, %s"),
-             strerror(errno));
+       my_log(LOG_NOTICE,
+              "IPMonitor: route_open_socket: socket failed, %s",
+              strerror(errno));
     }
     return (sockfd);
 }
     }
     return (sockfd);
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 /*
  * Define: ROUTE_MSG_ADDRS_SPACE
 
 /*
  * Define: ROUTE_MSG_ADDRS_SPACE
@@ -2919,6 +3267,7 @@ typedef struct {
     char               addrs[ROUTE_MSG_ADDRS_SPACE];
 } route_msg;
 
     char               addrs[ROUTE_MSG_ADDRS_SPACE];
 } route_msg;
 
+#if    !TARGET_IPHONE_SIMULATOR
 static int
 ipv4_route(int sockfd,
           int cmd, struct in_addr gateway, struct in_addr netaddr,
 static int
 ipv4_route(int sockfd,
           int cmd, struct in_addr gateway, struct in_addr netaddr,
@@ -2941,11 +3290,16 @@ ipv4_route(int sockfd,
 
     if (ifname == NULL) {
        /* this should not happen, but rather than crash, return an error */
 
     if (ifname == NULL) {
        /* this should not happen, but rather than crash, return an error */
-       syslog(LOG_NOTICE,
+       my_log(LOG_NOTICE,
               "IPMonitor: ipv4_route ifname is NULL on network address %s",
               inet_ntoa(netaddr));
        return (EBADF);
     }
               "IPMonitor: ipv4_route ifname is NULL on network address %s",
               inet_ntoa(netaddr));
        return (EBADF);
     }
+    if ((flags & kRouteIsNULLFlag) != 0) {
+       my_log(LOG_DEBUG, "IPMonitor: ignoring route %s on %s",
+              inet_ntoa(netaddr), ifname);
+       return (0);
+    }
     memset(&rtmsg, 0, sizeof(rtmsg));
     rtmsg.hdr.rtm_type = cmd;
     rtmsg.hdr.rtm_version = RTM_VERSION;
     memset(&rtmsg, 0, sizeof(rtmsg));
     rtmsg.hdr.rtm_type = cmd;
     rtmsg.hdr.rtm_version = RTM_VERSION;
@@ -2966,7 +3320,7 @@ ipv4_route(int sockfd,
        }
        if (ifindex == 0) {
            /* specifically asked for a scoped route, yet no index supplied */
        }
        if (ifindex == 0) {
            /* specifically asked for a scoped route, yet no index supplied */
-           syslog(LOG_NOTICE,
+           my_log(LOG_NOTICE,
                   "IPMonitor: ipv4_route index is 0 on %s-scoped route %s",
                   ifname, inet_ntoa(netaddr));
            return (EBADF);
                   "IPMonitor: ipv4_route index is 0 on %s-scoped route %s",
                   ifname, inet_ntoa(netaddr));
            return (EBADF);
@@ -3029,7 +3383,9 @@ ipv4_route(int sockfd,
     }
     return (ret);
 }
     }
     return (ret);
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 
+#if    !TARGET_IPHONE_SIMULATOR
 static boolean_t
 ipv6_route(int cmd, struct in6_addr gateway, struct in6_addr netaddr,
           struct in6_addr netmask, char * ifname, boolean_t is_direct)
 static boolean_t
 ipv6_route(int cmd, struct in6_addr gateway, struct in6_addr netaddr,
           struct in6_addr netmask, char * ifname, boolean_t is_direct)
@@ -3110,9 +3466,9 @@ ipv6_route(int cmd, struct in6_addr gateway, struct in6_addr netaddr,
        }
        else {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        }
        else {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor ipv6_route: write routing"
-                           " socket failed, %s"), strerror(errno));
+               my_log(LOG_DEBUG,
+                      "IPMonitor ipv6_route: write routing"
+                      " socket failed, %s", strerror(errno));
            }
            ret = FALSE;
        }
            }
            ret = FALSE;
        }
@@ -3126,7 +3482,7 @@ static boolean_t
 ipv6_default_route_delete(void)
 {
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
 ipv6_default_route_delete(void)
 {
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-       SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: IPv6 route delete default"));
+       my_log(LOG_DEBUG, "IPMonitor: IPv6 route delete default");
     }
     return (ipv6_route(RTM_DELETE, S_ip6_zeros, S_ip6_zeros, S_ip6_zeros,
                       NULL, FALSE));
     }
     return (ipv6_route(RTM_DELETE, S_ip6_zeros, S_ip6_zeros, S_ip6_zeros,
                       NULL, FALSE));
@@ -3139,17 +3495,19 @@ ipv6_default_route_add(struct in6_addr router, char * ifname,
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        char    ntopbuf[INET6_ADDRSTRLEN];
 
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        char    ntopbuf[INET6_ADDRSTRLEN];
 
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPMonitor: IPv6 route add default"
-                   " %s interface %s direct %d"),
-             inet_ntop(AF_INET6, &router, ntopbuf, sizeof(ntopbuf)),
-             ifname, is_direct);
+       my_log(LOG_DEBUG,
+              "IPMonitor: IPv6 route add default"
+              " %s interface %s direct %d",
+              inet_ntop(AF_INET6, &router, ntopbuf, sizeof(ntopbuf)),
+              ifname, is_direct);
     }
     return (ipv6_route(RTM_ADD, router, S_ip6_zeros, S_ip6_zeros,
                       ifname, is_direct));
 }
     }
     return (ipv6_route(RTM_ADD, router, S_ip6_zeros, S_ip6_zeros,
                       ifname, is_direct));
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 
 
 
+#if    !TARGET_IPHONE_SIMULATOR
 static int
 multicast_route_delete(int sockfd)
 {
 static int
 multicast_route_delete(int sockfd)
 {
@@ -3171,7 +3529,9 @@ multicast_route_add(int sockfd)
     return (ipv4_route(sockfd, RTM_ADD, gateway, netaddr, netmask, "lo0", 0,
                       gateway, 0));
 }
     return (ipv4_route(sockfd, RTM_ADD, gateway, netaddr, netmask, "lo0", 0,
                       gateway, 0));
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 
+#if    !TARGET_IPHONE_SIMULATOR
 #ifdef RTF_IFSCOPE
 static void
 set_ipv6_default_interface(char * ifname)
 #ifdef RTF_IFSCOPE
 static void
 set_ipv6_default_interface(char * ifname)
@@ -3190,15 +3550,15 @@ set_ipv6_default_interface(char * ifname)
 
     sock = inet6_dgram_socket();
     if (sock == -1) {
 
     sock = inet6_dgram_socket();
     if (sock == -1) {
-       SCLog(TRUE, LOG_ERR,
-             CFSTR("IPMonitor: set_ipv6_default_interface: socket failed, %s"),
-             strerror(errno));
+       my_log(LOG_ERR,
+              "IPMonitor: set_ipv6_default_interface: socket failed, %s",
+              strerror(errno));
        return;
     }
     if (ioctl(sock, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) == -1) {
        return;
     }
     if (ioctl(sock, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) == -1) {
-       SCLog(TRUE, LOG_ERR,
-             CFSTR("IPMonitor: set_ipv6_default_interface: ioctl(SIOCSDEFIFACE_IN6) failed, %s"),
-             strerror(errno));
+       my_log(LOG_ERR,
+              "IPMonitor: set_ipv6_default_interface: ioctl(SIOCSDEFIFACE_IN6) failed, %s",
+              strerror(errno));
     }
     close(sock);
     return;
     }
     close(sock);
     return;
@@ -3215,6 +3575,7 @@ set_ipv6_router(struct in6_addr * router, char * ifname, boolean_t is_direct)
     }
     return;
 }
     }
     return;
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 #if    !TARGET_OS_IPHONE
 static __inline__ void
 
 #if    !TARGET_OS_IPHONE
 static __inline__ void
@@ -3296,6 +3657,7 @@ set_dns(CFArrayRef val_search_domains,
 }
 #endif /* !TARGET_OS_IPHONE */
 
 }
 #endif /* !TARGET_OS_IPHONE */
 
+#if    !TARGET_IPHONE_SIMULATOR
 static boolean_t
 router_is_our_ipv6_address(CFStringRef router, CFArrayRef addr_list)
 {
 static boolean_t
 router_is_our_ipv6_address(CFStringRef router, CFArrayRef addr_list)
 {
@@ -3314,19 +3676,44 @@ router_is_our_ipv6_address(CFStringRef router, CFArrayRef addr_list)
     }
     return (FALSE);
 }
     }
     return (FALSE);
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 static IPv4RouteListRef
 service_dict_get_ipv4_routelist(CFDictionaryRef service_dict)
 {
     CFDictionaryRef    dict;
 
 static IPv4RouteListRef
 service_dict_get_ipv4_routelist(CFDictionaryRef service_dict)
 {
     CFDictionaryRef    dict;
-    IPv4RouteListRef   routes = NULL;
 
     dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv4);
 
 
     dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv4);
 
-    routes = ipv4_dict_get_routelist(dict);
-    return (routes);
+    return (ipv4_dict_get_routelist(dict));
+}
+
+static CFStringRef
+service_dict_get_ipv4_ifname(CFDictionaryRef service_dict)
+{
+    CFDictionaryRef    dict;
+
+    dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv4);
+    return (ipv4_dict_get_ifname(dict));
 }
 
 }
 
+static boolean_t
+service_get_ip_is_coupled(CFStringRef serviceID)
+{
+    CFDictionaryRef    dict;
+    boolean_t          ip_is_coupled = FALSE;
+
+    dict = service_dict_get(serviceID, kSCEntNetService);
+    if (dict != NULL) {
+       if (CFDictionaryContainsKey(dict, kIPIsCoupled)) {
+           ip_is_coupled = TRUE;
+       }
+    }
+    return (ip_is_coupled);
+}
+
+#if    !TARGET_IPHONE_SIMULATOR
+
 typedef struct apply_ipv4_route_context {
     IPv4RouteListRef   old;
     IPv4RouteListRef   new;
 typedef struct apply_ipv4_route_context {
     IPv4RouteListRef   old;
     IPv4RouteListRef   new;
@@ -3372,14 +3759,14 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg)
                                            ifn_p, route);
            }
            if (retval != 0) {
                                            ifn_p, route);
            }
            if (retval != 0) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor apply_ipv4_route failed to add"
-                           " %s/32 route, %s"),
-                     inet_ntoa(route->gateway), strerror(retval));
+               my_log(LOG_NOTICE,
+                      "IPMonitor apply_ipv4_route failed to add"
+                      " %s/32 route, %s",
+                      inet_ntoa(route->gateway), strerror(retval));
            }
            else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            }
            else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("Added IPv4 Route %s/32"),
-                     inet_ntoa(route->gateway));
+               my_log(LOG_DEBUG, "Added IPv4 Route %s/32",
+                      inet_ntoa(route->gateway));
            }
        }
        retval = ipv4_route(context->sockfd,
            }
        }
        retval = ipv4_route(context->sockfd,
@@ -3399,16 +3786,16 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg)
                                route->ifa, route->flags);
        }
        if (retval != 0) {
                                route->ifa, route->flags);
        }
        if (retval != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor apply_ipv4_route failed to add"
-                       " route, %s:"), strerror(retval));
-           IPv4RouteLog(route);
+           my_log(LOG_NOTICE,
+                  "IPMonitor apply_ipv4_route failed to add"
+                  " route, %s:", strerror(retval));
+           IPv4RouteLog(LOG_NOTICE, route);
        }
        else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        }
        else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("Added IPv4 route new[%d] = "),
-                 route - context->new->list);
-           IPv4RouteLog(route);
+           my_log(LOG_DEBUG,
+                  "Added IPv4 route new[%d] = ",
+                  route - context->new->list);
+           IPv4RouteLog(LOG_DEBUG, route);
        }
        break;
     case kIPv4RouteListRemoveRouteCommand:
        }
        break;
     case kIPv4RouteListRemoveRouteCommand:
@@ -3418,30 +3805,30 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg)
                            route->ifa, route->flags);
        if (retval != 0) {
            if (retval != ESRCH) {
                            route->ifa, route->flags);
        if (retval != 0) {
            if (retval != ESRCH) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor apply_ipv4_route failed to remove"
-                           " route, %s: "), strerror(retval));
-               IPv4RouteLog(route);
+               my_log(LOG_NOTICE,
+                      "IPMonitor apply_ipv4_route failed to remove"
+                      " route, %s: ", strerror(retval));
+               IPv4RouteLog(LOG_NOTICE, route);
            }
        }
        else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            }
        }
        else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("Removed IPv4 route old[%d] = "),
-                 route - context->old->list);
-           IPv4RouteLog(route);
+           my_log(LOG_DEBUG,
+                  "Removed IPv4 route old[%d] = ",
+                  route - context->old->list);
+           IPv4RouteLog(LOG_DEBUG, route);
        }
        if ((route->flags & kRouteIsNotSubnetLocalFlag) != 0) {
            retval = ipv4_route_gateway(context->sockfd, RTM_DELETE,
                                        ifn_p, route);
            if (retval != 0) {
        }
        if ((route->flags & kRouteIsNotSubnetLocalFlag) != 0) {
            retval = ipv4_route_gateway(context->sockfd, RTM_DELETE,
                                        ifn_p, route);
            if (retval != 0) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor apply_ipv4_route failed to remove"
-                           " %s/32 route, %s: "),
-                     inet_ntoa(route->gateway), strerror(retval));
+               my_log(LOG_NOTICE,
+                      "IPMonitor apply_ipv4_route failed to remove"
+                      " %s/32 route, %s: ",
+                      inet_ntoa(route->gateway), strerror(retval));
            }
            else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            }
            else if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("Removed IPv4 Route %s/32"),
-                     inet_ntoa(route->gateway));
+               my_log(LOG_DEBUG, "Removed IPv4 Route %s/32",
+                      inet_ntoa(route->gateway));
            }
        }
        break;
            }
        }
        break;
@@ -3450,6 +3837,7 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg)
     }
     return;
 }
     }
     return;
 }
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 /*
  * Function: update_ipv4
 
 /*
  * Function: update_ipv4
@@ -3465,7 +3853,9 @@ update_ipv4(CFStringRef           primary,
            IPv4RouteListRef    new_routelist,
            keyChangeListRef    keys)
 {
            IPv4RouteListRef    new_routelist,
            keyChangeListRef    keys)
 {
+#if    !TARGET_IPHONE_SIMULATOR
     apply_ipv4_route_context_t context;
     apply_ipv4_route_context_t context;
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
     if (keys != NULL) {
        if (new_routelist != NULL && primary != NULL) {
 
     if (keys != NULL) {
        if (new_routelist != NULL && primary != NULL) {
@@ -3515,23 +3905,24 @@ update_ipv4(CFStringRef         primary,
        }
     }
 
        }
     }
 
+#if    !TARGET_IPHONE_SIMULATOR
     bzero(&context, sizeof(context));
     context.sockfd = route_open_socket();
     if (context.sockfd != -1) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            if (S_ipv4_routelist == NULL) {
     bzero(&context, sizeof(context));
     context.sockfd = route_open_socket();
     if (context.sockfd != -1) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            if (S_ipv4_routelist == NULL) {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("Old Routes = <none>"));
+               my_log(LOG_DEBUG, "Old Routes = <none>");
            }
            else {
            }
            else {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("Old Routes = "));
-               IPv4RouteListLog(S_ipv4_routelist);
+               my_log(LOG_DEBUG, "Old Routes = ");
+               IPv4RouteListLog(LOG_DEBUG, S_ipv4_routelist);
            }
            if (new_routelist == NULL) {
            }
            if (new_routelist == NULL) {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("New Routes = <none>"));
+               my_log(LOG_DEBUG, "New Routes = <none>");
            }
            else {
            }
            else {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("New Routes = "));
-               IPv4RouteListLog(new_routelist);
+               my_log(LOG_DEBUG, "New Routes = ");
+               IPv4RouteListLog(LOG_DEBUG, new_routelist);
            }
        }
        context.old = S_ipv4_routelist;
            }
        }
        context.old = S_ipv4_routelist;
@@ -3550,64 +3941,75 @@ update_ipv4(CFStringRef         primary,
        free(S_ipv4_routelist);
     }
     S_ipv4_routelist = new_routelist;
        free(S_ipv4_routelist);
     }
     S_ipv4_routelist = new_routelist;
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
     return;
 }
 
 static void
     return;
 }
 
 static void
-update_ipv6(CFDictionaryRef    services_info,
-           CFStringRef         primary,
+update_ipv6(CFStringRef                primary,
            keyChangeListRef    keys)
 {
     CFDictionaryRef    ipv6_dict = NULL;
 
     if (primary != NULL) {
            keyChangeListRef    keys)
 {
     CFDictionaryRef    ipv6_dict = NULL;
 
     if (primary != NULL) {
-       CFDictionaryRef service_dict;
-
-       service_dict = CFDictionaryGetValue(S_service_state_dict, primary);
-       if (service_dict != NULL) {
-           ipv6_dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv6);
-       }
+       ipv6_dict = service_dict_get(primary, kSCEntNetIPv6);
     }
     if (ipv6_dict != NULL) {
     }
     if (ipv6_dict != NULL) {
+#if    !TARGET_IPHONE_SIMULATOR
        CFArrayRef              addrs;
        CFArrayRef              addrs;
+#endif /* !TARGET_IPHONE_SIMULATOR */
        CFMutableDictionaryRef  dict = NULL;
        CFStringRef             if_name = NULL;
        CFMutableDictionaryRef  dict = NULL;
        CFStringRef             if_name = NULL;
+#if    !TARGET_IPHONE_SIMULATOR
        char                    ifn[IFNAMSIZ] = { '\0' };
        char *                  ifn_p = NULL;
        boolean_t               is_direct = FALSE;
        char                    ifn[IFNAMSIZ] = { '\0' };
        char *                  ifn_p = NULL;
        boolean_t               is_direct = FALSE;
+#endif /* !TARGET_IPHONE_SIMULATOR */
        CFStringRef             val_router = NULL;
 
        dict = CFDictionaryCreateMutable(NULL, 0,
                                         &kCFTypeDictionaryKeyCallBacks,
                                         &kCFTypeDictionaryValueCallBacks);
        CFStringRef             val_router = NULL;
 
        dict = CFDictionaryCreateMutable(NULL, 0,
                                         &kCFTypeDictionaryKeyCallBacks,
                                         &kCFTypeDictionaryValueCallBacks);
-       val_router = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Router);
+
+#if    !TARGET_IPHONE_SIMULATOR
        addrs = CFDictionaryGetValue(ipv6_dict,
                                     kSCPropNetIPv6Addresses);
        addrs = CFDictionaryGetValue(ipv6_dict,
                                     kSCPropNetIPv6Addresses);
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
+       val_router = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Router);
        if (val_router != NULL) {
        if (val_router != NULL) {
-           /* no router if router is one of our IP addresses */
+#if    !TARGET_IPHONE_SIMULATOR
            is_direct = router_is_our_ipv6_address(val_router, addrs);
            is_direct = router_is_our_ipv6_address(val_router, addrs);
+#endif /* !TARGET_IPHONE_SIMULATOR */
+           /* no router if router is one of our IP addresses */
            CFDictionarySetValue(dict, kSCPropNetIPv6Router,
                                 val_router);
        }
            CFDictionarySetValue(dict, kSCPropNetIPv6Router,
                                 val_router);
        }
+#if    !TARGET_IPHONE_SIMULATOR
        else {
            val_router = CFArrayGetValueAtIndex(addrs, 0);
            is_direct = TRUE;
        }
        else {
            val_router = CFArrayGetValueAtIndex(addrs, 0);
            is_direct = TRUE;
        }
+#endif /* !TARGET_IPHONE_SIMULATOR */
        if_name = CFDictionaryGetValue(ipv6_dict, kSCPropInterfaceName);
        if (if_name) {
            CFDictionarySetValue(dict,
                                 kSCDynamicStorePropNetPrimaryInterface,
                                 if_name);
        if_name = CFDictionaryGetValue(ipv6_dict, kSCPropInterfaceName);
        if (if_name) {
            CFDictionarySetValue(dict,
                                 kSCDynamicStorePropNetPrimaryInterface,
                                 if_name);
+#if    !TARGET_IPHONE_SIMULATOR
            if (CFStringGetCString(if_name, ifn, sizeof(ifn),
                                   kCFStringEncodingASCII)) {
                ifn_p = ifn;
            }
            if (CFStringGetCString(if_name, ifn, sizeof(ifn),
                                   kCFStringEncodingASCII)) {
                ifn_p = ifn;
            }
+#endif /* !TARGET_IPHONE_SIMULATOR */
        }
        CFDictionarySetValue(dict, kSCDynamicStorePropNetPrimaryService,
                             primary);
        keyChangeListSetValue(keys, S_state_global_ipv6, dict);
        CFRelease(dict);
 
        }
        CFDictionarySetValue(dict, kSCDynamicStorePropNetPrimaryService,
                             primary);
        keyChangeListSetValue(keys, S_state_global_ipv6, dict);
        CFRelease(dict);
 
+#if    !TARGET_IPHONE_SIMULATOR
 #ifdef RTF_IFSCOPE
        if (S_scopedroute_v6) {
            set_ipv6_default_interface(ifn_p);
 #ifdef RTF_IFSCOPE
        if (S_scopedroute_v6) {
            set_ipv6_default_interface(ifn_p);
@@ -3619,9 +4021,11 @@ update_ipv6(CFDictionaryRef      services_info,
            (void)cfstring_to_ip6(val_router, &router);
            set_ipv6_router(&router, ifn_p, is_direct);
        }
            (void)cfstring_to_ip6(val_router, &router);
            set_ipv6_router(&router, ifn_p, is_direct);
        }
+#endif /* !TARGET_IPHONE_SIMULATOR */
     }
     else {
        keyChangeListRemoveValue(keys, S_state_global_ipv6);
     }
     else {
        keyChangeListRemoveValue(keys, S_state_global_ipv6);
+#if    !TARGET_IPHONE_SIMULATOR
 #ifdef RTF_IFSCOPE
        if (S_scopedroute_v6) {
            set_ipv6_default_interface(NULL);
 #ifdef RTF_IFSCOPE
        if (S_scopedroute_v6) {
            set_ipv6_default_interface(NULL);
@@ -3630,16 +4034,18 @@ update_ipv6(CFDictionaryRef     services_info,
        { /* route delete default ... */
            set_ipv6_router(NULL, NULL, FALSE);
        }
        { /* route delete default ... */
            set_ipv6_router(NULL, NULL, FALSE);
        }
+#endif /* !TARGET_IPHONE_SIMULATOR */
     }
     return;
 }
 
     }
     return;
 }
 
-static void
+static Boolean
 update_dns(CFDictionaryRef     services_info,
           CFStringRef          primary,
           keyChangeListRef     keys)
 {
 update_dns(CFDictionaryRef     services_info,
           CFStringRef          primary,
           keyChangeListRef     keys)
 {
-    CFDictionaryRef    dict = NULL;
+    Boolean            changed = FALSE;
+    CFDictionaryRef    dict    = NULL;
 
     if (primary != NULL) {
        CFDictionaryRef service_dict;
 
     if (primary != NULL) {
        CFDictionaryRef service_dict;
@@ -3649,33 +4055,41 @@ update_dns(CFDictionaryRef      services_info,
            dict = CFDictionaryGetValue(service_dict, kSCEntNetDNS);
        }
     }
            dict = CFDictionaryGetValue(service_dict, kSCEntNetDNS);
        }
     }
-    if (dict == NULL) {
+
+    if (!_SC_CFEqual(S_dns_dict, dict)) {
+       if (dict == NULL) {
 #if    !TARGET_OS_IPHONE
 #if    !TARGET_OS_IPHONE
-       empty_dns();
+           empty_dns();
 #endif /* !TARGET_OS_IPHONE */
 #endif /* !TARGET_OS_IPHONE */
-       keyChangeListRemoveValue(keys, S_state_global_dns);
-    }
-    else {
-       CFMutableDictionaryRef  new_dict;
+           keyChangeListRemoveValue(keys, S_state_global_dns);
+       } else {
+           CFMutableDictionaryRef      new_dict;
 
 #if    !TARGET_OS_IPHONE
 
 #if    !TARGET_OS_IPHONE
-       set_dns(CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains),
-               CFDictionaryGetValue(dict, kSCPropNetDNSDomainName),
-               CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses),
-               CFDictionaryGetValue(dict, kSCPropNetDNSSortList));
+           set_dns(CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains),
+                   CFDictionaryGetValue(dict, kSCPropNetDNSDomainName),
+                   CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses),
+                   CFDictionaryGetValue(dict, kSCPropNetDNSSortList));
 #endif /* !TARGET_OS_IPHONE */
 #endif /* !TARGET_OS_IPHONE */
-       new_dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
-       CFDictionaryRemoveValue(new_dict, kSCPropInterfaceName);
-       CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchDomains);
-       CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchOrders);
-       CFDictionaryRemoveValue(new_dict, DNS_CONFIGURATION_SCOPED_QUERY_KEY);
-       keyChangeListSetValue(keys, S_state_global_dns, new_dict);
-       CFRelease(new_dict);
+           new_dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+           CFDictionaryRemoveValue(new_dict, kSCPropInterfaceName);
+           CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchDomains);
+           CFDictionaryRemoveValue(new_dict, kSCPropNetDNSSupplementalMatchOrders);
+           CFDictionaryRemoveValue(new_dict, DNS_CONFIGURATION_SCOPED_QUERY_KEY);
+           keyChangeListSetValue(keys, S_state_global_dns, new_dict);
+           CFRelease(new_dict);
+       }
+       changed = TRUE;
     }
     }
-    return;
+
+    if (dict != NULL) CFRetain(dict);
+    if (S_dns_dict != NULL) CFRelease(S_dns_dict);
+    S_dns_dict = dict;
+
+    return changed;
 }
 
 }
 
-static void
+static Boolean
 update_dnsinfo(CFDictionaryRef services_info,
               CFStringRef      primary,
               keyChangeListRef keys,
 update_dnsinfo(CFDictionaryRef services_info,
               CFStringRef      primary,
               keyChangeListRef keys,
@@ -3706,15 +4120,42 @@ update_dnsinfo(CFDictionaryRef  services_info,
     if (changed) {
        keyChangeListNotifyKey(keys, S_state_global_dns);
     }
     if (changed) {
        keyChangeListNotifyKey(keys, S_state_global_dns);
     }
-    return;
+    return changed;
 }
 
 }
 
-static void
+static Boolean
+update_nwi(nwi_state_t state)
+{
+    unsigned char              signature[CC_SHA1_DIGEST_LENGTH];
+    static unsigned char       signature_last[CC_SHA1_DIGEST_LENGTH];
+
+    _nwi_state_signature(state, signature, sizeof(signature));
+    if (bcmp(signature, signature_last, sizeof(signature)) == 0) {
+       return FALSE;
+    }
+
+    // save [new] signature
+    bcopy(signature, signature_last, sizeof(signature));
+
+    // save [new] configuration
+    if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
+       my_log(LOG_DEBUG, "Updating network information");
+       S_nwi_state_dump(state);
+    }
+    if (_nwi_state_store(state) == FALSE) {
+       my_log(LOG_ERR, "Notifying nwi_state_store failed");
+    }
+
+    return TRUE;
+}
+
+static Boolean
 update_proxies(CFDictionaryRef services_info,
               CFStringRef      primary,
               keyChangeListRef keys,
               CFArrayRef       service_order)
 {
 update_proxies(CFDictionaryRef services_info,
               CFStringRef      primary,
               keyChangeListRef keys,
               CFArrayRef       service_order)
 {
+    Boolean        changed     = FALSE;
     CFDictionaryRef dict       = NULL;
     CFDictionaryRef new_dict;
 
     CFDictionaryRef dict       = NULL;
     CFDictionaryRef new_dict;
 
@@ -3729,23 +4170,30 @@ update_proxies(CFDictionaryRef  services_info,
 
     new_dict = proxy_configuration_update(dict,
                                          S_service_state_dict,
 
     new_dict = proxy_configuration_update(dict,
                                          S_service_state_dict,
-                                         service_order);
-    if (new_dict == NULL) {
-       keyChangeListRemoveValue(keys, S_state_global_proxies);
-    }
-    else {
-       keyChangeListSetValue(keys, S_state_global_proxies, new_dict);
-       CFRelease(new_dict);
+                                         service_order,
+                                         services_info);
+    if (!_SC_CFEqual(S_proxies_dict, new_dict)) {
+       if (new_dict == NULL) {
+           keyChangeListRemoveValue(keys, S_state_global_proxies);
+       } else {
+           keyChangeListSetValue(keys, S_state_global_proxies, new_dict);
+       }
+       changed = TRUE;
     }
     }
-    return;
+
+    if (S_proxies_dict != NULL) CFRelease(S_proxies_dict);
+    S_proxies_dict = new_dict;
+
+    return changed;
 }
 
 #if    !TARGET_OS_IPHONE
 }
 
 #if    !TARGET_OS_IPHONE
-static void
+static Boolean
 update_smb(CFDictionaryRef     services_info,
           CFStringRef          primary,
           keyChangeListRef     keys)
 {
 update_smb(CFDictionaryRef     services_info,
           CFStringRef          primary,
           keyChangeListRef     keys)
 {
+    Boolean            changed = FALSE;
     CFDictionaryRef    dict    = NULL;
 
     if (primary != NULL) {
     CFDictionaryRef    dict    = NULL;
 
     if (primary != NULL) {
@@ -3756,14 +4204,21 @@ update_smb(CFDictionaryRef      services_info,
            dict = CFDictionaryGetValue(service_dict, kSCEntNetSMB);
        }
     }
            dict = CFDictionaryGetValue(service_dict, kSCEntNetSMB);
        }
     }
-    if (dict == NULL) {
-       keyChangeListRemoveValue(keys, S_state_global_smb);
-    }
-    else {
-       keyChangeListSetValue(keys, S_state_global_smb, dict);
+
+    if (!_SC_CFEqual(S_smb_dict, dict)) {
+       if (dict == NULL) {
+           keyChangeListRemoveValue(keys, S_state_global_smb);
+       } else {
+           keyChangeListSetValue(keys, S_state_global_smb, dict);
+       }
+       changed = TRUE;
     }
 
     }
 
-    return;
+    if (dict != NULL) CFRetain(dict);
+    if (S_smb_dict != NULL) CFRelease(S_smb_dict);
+    S_smb_dict = dict;
+
+    return changed;
 }
 #endif /* !TARGET_OS_IPHONE */
 
 }
 #endif /* !TARGET_OS_IPHONE */
 
@@ -3830,371 +4285,930 @@ rank_dict_set_service_rank(CFMutableDictionaryRef rank_dict,
     return;
 }
 
     return;
 }
 
-typedef struct election_info {
-    int                        n_services;
-    CFArrayRef         order;
-    int                        n_order;
-    CFStringRef                serviceID;
-    CFDictionaryRef    service_dict;
-    Rank               rank;
-} election_info_t;
+static const CFStringRef *transientInterfaceEntityNames[] = {
+    &kSCEntNetPPP,
+};
 
 
-typedef boolean_t election_func_t(void * context, election_info_t * info);
 
 
-/*
- * Function: elect_ipv4
- * Purpose:
- *   This function builds the list of IPv4 routes that should be active.
- *   As elect_new_primary() invokes us with each service, we build up the
- *   result in the passed in context, a pointer to an IPv4RouteListRef.
- */
-static boolean_t
-elect_ipv4(void * context, election_info_t * info)
+static void
+CollectTransientServices(const void * key,
+                        const void * value,
+                        void * context)
 {
 {
-    Rank               primary_rank;
-    IPv4RouteListRef * routes_p = (IPv4RouteListRef *)context;
-    IPv4RouteListRef   service_routes;
+    int                        i;
+    CFStringRef                service = key;
+    CFMutableArrayRef  vif_setup_keys = context;
 
 
-    service_routes = service_dict_get_ipv4_routelist(info->service_dict);
+    /* This service is either a vpn type service or a comm center service */
+    if (!CFStringHasPrefix(service, kSCDynamicStoreDomainSetup)) {
+       return;
+    }
 
 
-    info->rank = get_service_rank(info->order, info->n_order,
-                                   info->serviceID);
+    for (i = 0; i < sizeof(transientInterfaceEntityNames)/sizeof(transientInterfaceEntityNames[0]); i++) {
+       if (!CFStringHasSuffix(service, *transientInterfaceEntityNames[i])) {
+           continue;
+       }
 
 
-    if (service_routes == NULL) {
-       return (FALSE);
+       CFArrayAppendValue(vif_setup_keys, service);
     }
     }
+    return;
+}
 
 
-    primary_rank = RANK_ASSERTION_MASK(service_routes->list->rank);
 
 
-    if (S_ppp_override_primary
-            && (strncmp(PPP_PREFIX, service_routes->list->ifname,
-                        sizeof(PPP_PREFIX) - 1) == 0)) {
-       /* PPP override: make ppp* look the best */
-       /* Hack: should use interface type, not interface name */
-       primary_rank = kRankAssertionFirst;
+static SCNetworkReachabilityFlags
+GetReachabilityFlagsFromVPN(CFDictionaryRef services_info,
+                           CFStringRef     service_id,
+                           CFStringRef     entity,
+                           CFStringRef     vpn_setup_key)
+{
+    CFStringRef                        key;
+    CFDictionaryRef            dict;
+    SCNetworkReachabilityFlags flags = 0;
+
+
+    key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                       kSCDynamicStoreDomainSetup,
+                                                       service_id,
+                                                       kSCEntNetInterface);
+    dict = CFDictionaryGetValue(services_info, key);
+    CFRelease(key);
+
+    if (isA_CFDictionary(dict)
+       && CFDictionaryContainsKey(dict, kSCPropNetInterfaceDeviceName)) {
+
+       flags = (kSCNetworkReachabilityFlagsReachable
+               | kSCNetworkReachabilityFlagsTransientConnection
+               | kSCNetworkReachabilityFlagsConnectionRequired);
+
+       if (CFEqual(entity, kSCEntNetPPP)) {
+           CFNumberRef num;
+           CFDictionaryRef p_dict = CFDictionaryGetValue(services_info, vpn_setup_key);
+
+           if (!isA_CFDictionary(p_dict)) {
+               return (flags);
+           }
+
+           // get PPP dial-on-traffic status
+           num = CFDictionaryGetValue(p_dict, kSCPropNetPPPDialOnDemand);
+           if (isA_CFNumber(num)) {
+               int32_t ppp_demand;
+
+               if (CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_demand)) {
+                   if (ppp_demand) {
+                       flags |= kSCNetworkReachabilityFlagsConnectionOnTraffic;
+                   }
+               }
+           }
+       }
     }
     }
+    return (flags);
+}
+
+static Boolean
+S_dict_get_boolean(CFDictionaryRef dict, CFStringRef key, Boolean def_value)
+{
+    Boolean            ret = def_value;
 
 
-    info->rank = RankMake(info->rank, primary_rank);
+    if (dict != NULL) {
+       CFBooleanRef    val;
 
 
-    if (routes_p != NULL) {
-       *routes_p = IPv4RouteListAddRouteList(*routes_p,
-                                             info->n_services * 3,
-                                             service_routes,
-                                             info->rank);
+       val = CFDictionaryGetValue(dict, key);
+       if (isA_CFBoolean(val) != NULL) {
+           ret = CFBooleanGetValue(val);
+       }
     }
     }
+    return (ret);
+}
 
 
-    if (primary_rank == kRankAssertionNever) {
-       /* never elect as primary */
-       return (FALSE);
+
+static void
+GetReachabilityFlagsFromTransientServices(CFDictionaryRef services_info,
+                                         SCNetworkReachabilityFlags *reach_flags_v4,
+                                         SCNetworkReachabilityFlags *reach_flags_v6)
+{
+    int i;
+    int count;
+    CFMutableArrayRef vif_setup_keys;
+
+    vif_setup_keys = CFArrayCreateMutable(NULL,
+                                         0,
+                                         &kCFTypeArrayCallBacks);
+
+    CFDictionaryApplyFunction(services_info, CollectTransientServices, vif_setup_keys);
+
+    count = CFArrayGetCount(vif_setup_keys);
+
+    if (count != 0) {
+       my_log(LOG_DEBUG, "Collected the following VIF Setup Keys: %@", vif_setup_keys);
     }
     }
-    if (strncmp(service_routes->list->ifname, "lo0",
-               sizeof(service_routes->list->ifname)) == 0) {
-       /* never elect as primary */
-       return (FALSE);
+
+    for (i = 0; i < count; i++) {
+       CFArrayRef          components = NULL;
+       CFStringRef         entity;
+       CFStringRef         service_id;
+       CFStringRef         vif_setup_key;
+
+       vif_setup_key = CFArrayGetValueAtIndex(vif_setup_keys, i);
+
+       /*
+        * setup key in the following format:
+        * Setup:/Network/Service/<Service ID>/<Entity>
+        */
+       components = CFStringCreateArrayBySeparatingStrings(NULL, vif_setup_key, CFSTR("/"));
+
+       if (CFArrayGetCount(components) != 5) {
+           my_log(LOG_ERR, "Invalid Setup Key encountered: %@", vif_setup_key);
+           goto skip;
+       }
+
+       /* service id is the 3rd element */
+       service_id = CFArrayGetValueAtIndex(components, 3);
+
+       /* entity id is the 4th element */
+       entity = CFArrayGetValueAtIndex(components, 4);
+
+       my_log(LOG_DEBUG, "Service %@ is a %@ Entity", service_id, entity);
+
+
+       if (CFEqual(entity, kSCEntNetPPP)) {
+           SCNetworkReachabilityFlags  flags;
+           CFStringRef                 key;
+
+           flags = GetReachabilityFlagsFromVPN(services_info,
+                                               service_id,
+                                               entity,
+                                               vif_setup_key);
+
+           /* Check for the v4 reachability flags */
+           key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             service_id,
+                                                             kSCEntNetIPv4);
+
+           if (CFDictionaryContainsKey(services_info, key)) {
+               *reach_flags_v4 |= flags;
+               my_log(LOG_DEBUG,"Service %@ setting ipv4 reach flags: %d", service_id, *reach_flags_v4);
+           }
+
+           CFRelease(key);
+
+           /* Check for the v6 reachability flags */
+           key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             service_id,
+                                                             kSCEntNetIPv6);
+
+           if (CFDictionaryContainsKey(services_info, key)) {
+               *reach_flags_v6 |= flags;
+               my_log(LOG_DEBUG,"Service %@ setting ipv6 reach flags: %d", service_id, *reach_flags_v6);
+           }
+           CFRelease(key);
+
+           if (flags != 0) {
+               if (components != NULL) {
+                   CFRelease(components);
+               }
+               goto done;
+           }
+       }
+skip:
+       if (components != NULL) {
+           CFRelease(components);
+       }
     }
     }
+done:
+    CFRelease(vif_setup_keys);
+    return;
+}
 
 
-    rank_dict_set_service_rank(S_ipv4_service_rank_dict,
-                              info->serviceID, info->rank);
-    return (TRUE);
+static SCNetworkReachabilityFlags
+GetReachFlagsFromStatus(CFStringRef entity, int status)
+{
+    SCNetworkReachabilityFlags flags = 0;
+
+    if (CFEqual(entity, kSCEntNetPPP)) {
+       switch (status) {
+           case PPP_RUNNING :
+               /* if we're really UP and RUNNING */
+               break;
+           case PPP_ONHOLD :
+               /* if we're effectively UP and RUNNING */
+               break;
+           case PPP_IDLE :
+               /* if we're not connected at all */
+               my_log(LOG_INFO, "PPP link idle");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+           case PPP_STATERESERVED :
+               // if we're not connected at all
+               my_log(LOG_INFO, "PPP link idle, dial-on-traffic to connect");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+           default :
+               /* if we're in the process of [dis]connecting */
+               my_log(LOG_INFO, "PPP link, connection in progress");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+       }
+    }
+#ifdef HAVE_IPSEC_STATUS
+    else if (CFEqual(entity, kSCEntNetIPSec)) {
+       switch (status) {
+           case IPSEC_RUNNING :
+               /* if we're really UP and RUNNING */
+               break;
+           case IPSEC_IDLE :
+               /* if we're not connected at all */
+               my_log(LOG_INFO, "IPSec link idle");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+           default :
+               /* if we're in the process of [dis]connecting */
+               my_log(LOG_INFO, "IPSec link, connection in progress");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+       }
+    }
+#endif // HAVE_IPSEC_STATUS
+#ifdef HAVE_VPN_STATUS
+    else if  (CFEqual(entity, kSCEntNetVPN)) {
+       switch (status) {
+           case VPN_RUNNING :
+               /* if we're really UP and RUNNING */
+               break;
+           case VPN_IDLE :
+           case VPN_LOADING :
+           case VPN_LOADED :
+           case VPN_UNLOADING :
+               /* if we're not connected at all */
+               my_log(LOG_INFO, "%s  VPN link idle");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+           default :
+               /* if we're in the process of [dis]connecting */
+               my_log(LOG_INFO, "VPN link, connection in progress");
+               flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+               break;
+       }
+    }
+#endif // HAVE_VPN_STATUS
+    return (flags);
 }
 
 static void
 }
 
 static void
-IPv6RankedListInsertE(IPv6RankedListRef list, IPv6RankedERef e)
+VPNAttributesGet(CFStringRef               service_id,
+                CFDictionaryRef            services_info,
+                SCNetworkReachabilityFlags *flags,
+                CFStringRef                *server_address,
+                int                        af)
 {
 {
-    int        idx                 = 0;
-    int elems_to_be_moved   = 0;
+    int                                i;
+    CFDictionaryRef            entity_dict;
+    boolean_t                  found = FALSE;
+    CFNumberRef                        num;
+    CFDictionaryRef            p_state = NULL;
+    int                                status = 0;
+
+    /* if the IPv[4/6] exist */
+    entity_dict = service_dict_get(service_id, (af == AF_INET) ? kSCEntNetIPv4 : kSCEntNetIPv6);
+    if (!isA_CFDictionary(entity_dict)) {
+       return;
+    }
 
 
-    if (list == NULL) return;
+    if (af == AF_INET) {
+       entity_dict = CFDictionaryGetValue(entity_dict, kIPv4DictService);
+       if (!isA_CFDictionary(entity_dict)) {
+           return;
+       }
+    }
 
 
-    for (idx = 0; idx < list->count; idx++) {
-       if ((e->rank < list->elem[idx].rank)) {
+    for (i = 0; i < sizeof(statusEntityNames)/sizeof(statusEntityNames[0]); i++) {
+       p_state = service_dict_get(service_id, *statusEntityNames[i]);
+       /* ensure that this is a VPN Type service */
+       if (isA_CFDictionary(p_state)) {
+           found = TRUE;
            break;
        }
     }
 
            break;
        }
     }
 
-    if ((S_IPMonitor_debug & kDebugFlag2) != 0) {
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPv6RankedListInsertE: %s flags 0x%x at index %d with rank %u."),
-             e->ifname, e->flags, idx, e->rank);
+    /* Did we find a vpn type service?  If not, we are done.*/
+    if (!found) {
+       return;
+    }
+
+    *flags |= (kSCNetworkReachabilityFlagsReachable| kSCNetworkReachabilityFlagsTransientConnection);
+
+    /* Get the Server Address */
+    if (server_address != NULL) {
+       *server_address = CFDictionaryGetValue(entity_dict, CFSTR("ServerAddress"));
+       *server_address = isA_CFString(*server_address);
+       if (*server_address != NULL) {
+           CFRetain(*server_address);
+       }
     }
 
     }
 
-    elems_to_be_moved = list->count - idx;
-    if (elems_to_be_moved > 0) {
-       bcopy((void*) &list->elem[idx], (void*) &list->elem[idx+1],
-             elems_to_be_moved * sizeof(*e));
+    /* get status */
+    if (!CFDictionaryGetValueIfPresent(p_state,
+                                      kSCPropNetVPNStatus,
+                                      (const void **)&num) ||
+       !isA_CFNumber(num) ||
+       !CFNumberGetValue(num, kCFNumberSInt32Type, &status)) {
+       return;
     }
 
     }
 
-    bcopy((void*) e, (void*) &list->elem[idx], sizeof(*e));
-    list->count++;
+    *flags |= GetReachFlagsFromStatus(*statusEntityNames[i], status);
+
+    if (CFEqual(*statusEntityNames[i], kSCEntNetPPP)) {
+       CFStringRef     key;
+       CFDictionaryRef p_setup;
+       int             ppp_demand;
+
+       key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                         kSCDynamicStoreDomainSetup,
+                                                         service_id,
+                                                         kSCEntNetPPP);
+       p_setup = CFDictionaryGetValue(services_info, key);
+       CFRelease(key);
+
+       /* get dial-on-traffic status */
+       if (isA_CFDictionary(p_setup) &&
+           CFDictionaryGetValueIfPresent(p_setup,
+                                         kSCPropNetPPPDialOnDemand,
+                                         (const void **)&num) &&
+           isA_CFNumber(num) &&
+           CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_demand) &&
+           (ppp_demand != 0)) {
+           *flags |= kSCNetworkReachabilityFlagsConnectionOnTraffic;
+           if (status == PPP_IDLE) {
+               *flags |= kSCNetworkReachabilityFlagsInterventionRequired;
+           }
+       }
+    }
     return;
 }
 
     return;
 }
 
-static boolean_t
-elect_ipv6(void * context, election_info_t * info)
-{
-    CFStringRef                if_name;
-    CFStringRef                primaryRankStr  = NULL;
-    CFDictionaryRef    proto_dict;
-    CFStringRef                router;
-    CFDictionaryRef    service_options;
-    IPv6RankedListRef  list = (IPv6RankedListRef) context;
-    IPv6RankedE                elem;
-    CFDictionaryRef    dns_dict = NULL;
-    Rank               primary_rank = kRankAssertionDefault;
 
 
-    memset((void *)&elem, 0, sizeof(elem));
+typedef struct ElectionInfo {
+    int                        n_services;
+    CFArrayRef         order;
+    int                        n_order;
+    ElectionResultsRef results;
+} ElectionInfo, * ElectionInfoRef;
+
+typedef CFDictionaryApplierFunction    ElectionFuncRef;
 
 
-    info->rank = get_service_rank(info->order, info->n_order, info->serviceID);
+static void
+CandidateRelease(CandidateRef candidate)
+{
+    my_CFRelease(&candidate->serviceID);
+    my_CFRelease(&candidate->if_name);
+    my_CFRelease(&candidate->signature);
+    return;
+}
 
 
-    proto_dict = CFDictionaryGetValue(info->service_dict, kSCEntNetIPv6);
-    if (proto_dict == NULL) {
-       return (FALSE);
+static void
+CandidateCopy(CandidateRef dest, CandidateRef src)
+{
+    *dest = *src;
+    if (dest->serviceID) {
+       CFRetain(dest->serviceID);
     }
     }
-    if_name = CFDictionaryGetValue(proto_dict, kSCPropInterfaceName);
-    if (if_name == NULL) {
-       /* we need an interface name */
-       return (FALSE);
+    if (dest->if_name) {
+       CFRetain(dest->if_name);
     }
     }
-    if (CFEqual(if_name, CFSTR("lo0"))) {
-       /* don't ever elect loopback */
-       return (FALSE);
+    if(dest->signature) {
+       CFRetain(dest->signature);
     }
     }
-    CFStringGetCString(if_name, elem.ifname,
-                      sizeof(elem.ifname),
-                      kCFStringEncodingASCII);
-    router = CFDictionaryGetValue(proto_dict,
-                                 kSCPropNetIPv6Router);
-    if (router == NULL) {
-       /* can't become primary without a router */
-       return (FALSE);
+    return;
+}
+
+static ElectionResultsRef
+ElectionResultsAlloc(int size)
+{
+    ElectionResultsRef results;
+
+    results = (ElectionResultsRef)malloc(ElectionResultsComputeSize(size));
+    results->count = 0;
+    results->size = size;
+    return (results);
+}
+
+static void
+ElectionResultsRelease(ElectionResultsRef results)
+{
+    int                        i;
+    CandidateRef       scan;
+
+    for (i = 0, scan = results->candidates;
+        i < results->count;
+        i++, scan++) {
+       CandidateRelease(scan);
     }
     }
+    free(results);
+    return;
+}
+
+static void
+ElectionResultsLog(int level, ElectionResultsRef results, const char * prefix)
+{
+    int                        i;
+    CandidateRef       scan;
 
 
-    dns_dict = service_dict_get(info->serviceID, kSCEntNetDNS);
-    if (dns_dict != NULL) {
-       elem.flags |= NWI_IFSTATE_FLAGS_HAS_DNS;
+    if (results == NULL) {
+       my_log(level, "%s: no candidates", prefix);
+       return;
     }
     }
+    my_log(level, "%s: %d candidates", prefix, results->count);
+    for (i = 0, scan = results->candidates;
+        i < results->count;
+        i++, scan++) {
+       my_log(level, "%d. %@ Rank=0x%x serviceID=%@", i, scan->if_name,
+              scan->rank, scan->serviceID);
+    }
+    return;
+}
 
 
-    service_options = service_dict_get(info->serviceID, kSCEntNetService);
-    if (service_options != NULL) {
-       primaryRankStr = CFDictionaryGetValue(service_options, kSCPropNetServicePrimaryRank);
-       if (primaryRankStr != NULL) {
-           primary_rank = PrimaryRankGetRankAssertion(primaryRankStr);
-       }
-       if (primary_rank == kRankAssertionNever) {
-           elem.flags |= NWI_IFSTATE_FLAGS_NOT_IN_LIST;
-           elem.rank = RankMake(info->rank, primary_rank);
-           IPv6RankedListInsertE(list, &elem);
-           return (FALSE);
+/*
+ * Function: ElectionResultsAddCandidate
+ * Purpose:
+ *   Add the candidate into the election results. Find the insertion point
+ *   by comparing the rank of the candidate with existing entries.
+ */
+static void
+ElectionResultsAddCandidate(ElectionResultsRef results, CandidateRef candidate)
+{
+    int                        i;
+    int                        where;
+
+#define BAD_INDEX      (-1)
+    if (results->count == results->size) {
+       /* this should not happen */
+       my_log(LOG_NOTICE, "can't fit another candidate");
+       return;
+    }
+
+    /* find the insertion point */
+    where = BAD_INDEX;
+    for (i = 0; i < results->count; i++) {
+       CandidateRef    this_candidate = results->candidates + i;
+
+       if (candidate->rank < this_candidate->rank) {
+           where = i;
+           break;
        }
     }
        }
     }
+    /* add it to the end */
+    if (where == BAD_INDEX) {
+       CandidateCopy(results->candidates + results->count, candidate);
+       results->count++;
+       return;
+    }
+    /* slide existing entries over */
+    for (i = results->count; i > where; i--) {
+       results->candidates[i] = results->candidates[i - 1];
+    }
+    /* insert element */
+    CandidateCopy(results->candidates + where, candidate);
+    results->count++;
+    return;
+}
 
 
-    if (get_override_primary(proto_dict)) {
-       primary_rank = kRankAssertionFirst;
+/*
+ * Function: ElectionResultsCopy
+ * Purpose:
+ *   Visit all of the services and invoke the protocol-specific election
+ *   function.  Return the results of the election.
+ */
+static ElectionResultsRef
+ElectionResultsCopy(ElectionFuncRef elect_func, CFArrayRef order, int n_order)
+{
+    int                        count;
+    ElectionInfo       info;
+
+    count = CFDictionaryGetCount(S_service_state_dict);
+    if (count == 0) {
+       return (NULL);
     }
     }
-    else if (S_ppp_override_primary
-            && CFStringHasPrefix(if_name, CFSTR(PPP_PREFIX))) {
-       /* PPP override: make ppp* look the best */
-       /* Hack: should use interface type, not interface name */
-       primary_rank = kRankAssertionFirst;
+    info.results = ElectionResultsAlloc(count);
+    info.n_services = count;
+    info.order = order;
+    info.n_order = n_order;
+    CFDictionaryApplyFunction(S_service_state_dict, elect_func, (void *)&info);
+    if (info.results->count == 0) {
+       ElectionResultsRelease(info.results);
+       info.results = NULL;
     }
     }
+    return (info.results);
+}
 
 
-    elem.rank = RankMake(info->rank, primary_rank);
-    info->rank = RankMake(info->rank, primary_rank);
+/*
+ * Function: ElectionResultsCandidateNeedsDemotion
+ * Purpose:
+ *   Check whether the given candidate requires demotion. A candidate
+ *   might need to be demoted if its IPv4 and IPv6 services must be coupled
+ *   but a higher ranked service has IPv4 or IPv6.
+ */
+static Boolean
+ElectionResultsCandidateNeedsDemotion(ElectionResultsRef other_results,
+                                     CandidateRef candidate)
+{
+    CandidateRef       other_candidate;
+    Boolean            ret = FALSE;
 
 
-    (void)cfstring_to_ip6(router, &elem.iaddr6);
+    if (other_results == NULL
+       || candidate->ip_is_coupled == FALSE
+       || RANK_ASSERTION_MASK(candidate->rank) == kRankAssertionNever) {
+       goto done;
+    }
+    other_candidate = other_results->candidates;
+    if (CFEqual(other_candidate->if_name, candidate->if_name)) {
+       /* they are over the same interface, no need to demote */
+       goto done;
+    }
+    if (CFStringHasPrefix(other_candidate->if_name, CFSTR("stf"))) {
+       /* avoid creating a feedback loop */
+       goto done;
+    }
+    if (RANK_ASSERTION_MASK(other_candidate->rank) == kRankAssertionNever) {
+       /* the other candidate isn't eligible to become primary, ignore */
+       goto done;
+    }
+    if (candidate->rank < other_candidate->rank) {
+       /* we're higher ranked than the other candidate, ignore */
+       goto done;
+    }
+    ret = TRUE;
+
+ done:
+    return (ret);
 
 
-    IPv6RankedListInsertE(list, &elem);
-    rank_dict_set_service_rank(S_ipv6_service_rank_dict,
-                              info->serviceID, info->rank);
-    return (TRUE);
 }
 
 }
 
+
 static void
 static void
-update_nwi_state_ipv6(nwi_state_t state, IPv6RankedListRef list)
+get_signature_sha1(CFStringRef         signature,
+                  unsigned char        * sha1)
 {
 {
-    int idx;
+    CC_SHA1_CTX            ctx;
+    CFDataRef      signature_data;
 
 
-    if (state == NULL) {
-       return;
-    }
+    signature_data = CFStringCreateExternalRepresentation(NULL,
+                                                         signature,
+                                                         kCFStringEncodingUTF8,
+                                                         0);
+
+    CC_SHA1_Init(&ctx);
+    CC_SHA1_Update(&ctx,
+                  signature_data,
+                  CFDataGetLength(signature_data));
+    CC_SHA1_Final(sha1, &ctx);
 
 
-    /* A null list indicates to clear the ifstates */
-    nwi_state_clear(state, AF_INET6);
+    CFRelease(signature_data);
+
+    return;
+}
+
+
+static void
+add_candidate_to_nwi_state(nwi_state_t nwi_state, int af,
+                          CandidateRef candidate, Rank rank)
+{
+    uint64_t           flags = 0;
+    char               ifname[IFNAMSIZ];
+    nwi_ifstate_t      ifstate;
 
 
-    if (list == NULL) {
+    if (nwi_state == NULL) {
+       /* can't happen */
        return;
     }
        return;
     }
+    if (RANK_ASSERTION_MASK(rank) == kRankAssertionNever) {
+       flags |= NWI_IFSTATE_FLAGS_NOT_IN_LIST;
+    }
+    if (service_dict_get(candidate->serviceID, kSCEntNetDNS) != NULL) {
+       flags |= NWI_IFSTATE_FLAGS_HAS_DNS;
+    }
+    CFStringGetCString(candidate->if_name, ifname, sizeof(ifname),
+                      kCFStringEncodingASCII);
+    if ((S_IPMonitor_debug & kDebugFlag2) != 0) {
+       my_log(LOG_DEBUG,
+              "Inserting IPv%c [%s] with flags 0x%x primary_rank 0x%x reach_flags %d",
+              ipvx_char(af), ifname, rank, candidate->reachability_flags);
+    }
+    ifstate = nwi_insert_ifstate(nwi_state, ifname, af, flags, rank,
+                                (void *)&candidate->addr,
+                                (void *)&candidate->vpn_server_addr,
+                                candidate->reachability_flags);
+    if (ifstate != NULL && candidate->signature) {
+       uint8_t     hash[CC_SHA1_DIGEST_LENGTH];
+
+       get_signature_sha1(candidate->signature, hash);
+       nwi_ifstate_set_signature(ifstate, hash);
+    }
+    return;
+}
 
 
-    for (idx = 0 ; idx < list->count; idx++) {
-       if ((S_IPMonitor_debug & kDebugFlag2) != 0) {
-           char        ntopbuf[INET6_ADDRSTRLEN];
 
 
-           inet_ntop(AF_INET6, &list->elem[idx].iaddr6, ntopbuf,
-                     sizeof(ntopbuf));
+static void
+add_reachability_flags_to_candidate(CandidateRef candidate, CFDictionaryRef services_info, int af)
+{
+    SCNetworkReachabilityFlags flags = kSCNetworkReachabilityFlagsReachable;
+    CFStringRef                        vpn_server_address = NULL;
 
 
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("Inserting v6 [%s] into list with flags 0x%x"
-                       " with rank %lu ipv6 addr %s"),
-                       list->elem[idx].ifname, list->elem[idx].flags,
-                       list->elem[idx].rank, ntopbuf);
-       }
+    VPNAttributesGet(candidate->serviceID,
+                    services_info,
+                    &flags,
+                    &vpn_server_address,
+                    af);
 
 
-       nwi_insert_ifstate(state, list->elem[idx].ifname,
-                          AF_INET6, list->elem[idx].flags,
-                          list->elem[idx].rank,
-                          (void *)&list->elem[idx].iaddr6);
+    candidate->reachability_flags = flags;
+
+    if (vpn_server_address == NULL) {
+       bzero(&candidate->vpn_server_addr, sizeof(candidate->vpn_server_addr));
+    } else {
+       char buf[128];
+       CFStringGetCString(vpn_server_address, buf, sizeof(buf), kCFStringEncodingASCII);
+
+       _SC_string_to_sockaddr(buf,
+                              AF_UNSPEC,
+                              (void *)&candidate->vpn_server_addr,
+                              sizeof(candidate->vpn_server_addr));
+
+       CFRelease(vpn_server_address);
     }
     }
-    nwi_state_set_last(state, AF_INET6);
+    return;
 }
 }
+/*
+ * Function: ElectionResultsCopyPrimary
+ * Purpose:
+ *   Use the results of the current protocol and the other protocol to
+ *   determine which service should become primary.
+ *
+ *   At the same time, generate the nwi_state for the protocol.
+ *
+ *   For IPv4, also generate the IPv4 routing table.
+ */
+static CFStringRef
+ElectionResultsCopyPrimary(ElectionResultsRef results,
+                          ElectionResultsRef other_results,
+                          nwi_state_t nwi_state, int af,
+                          IPv4RouteListRef * ret_routes,
+                          CFDictionaryRef services_info)
+{
+    CFStringRef                primary = NULL;
+    Boolean            primary_is_null = FALSE;
+    IPv4RouteListRef   routes = NULL;
 
 
-static boolean_t
-interface_has_dns(const void * * values, int values_count,
-                 const char * ifname)
-{
-    boolean_t          has_dns = FALSE;
-    int                        i;
-    CFStringRef                ifname_cf;
+    if (nwi_state != NULL) {
+       nwi_state_clear(nwi_state, af);
+    }
+    if (results != NULL) {
+       CandidateRef    deferred[results->count];
+       int             deferred_count;
+       int             i;
+       CandidateRef    scan;
 
 
-    ifname_cf = CFStringCreateWithCString(NULL, ifname, kCFStringEncodingASCII);
-    for (i = 0; i < values_count; i++) {
-       CFDictionaryRef         dns_dict;
+       deferred_count = 0;
+       for (i = 0, scan = results->candidates;
+            i < results->count;
+            i++, scan++) {
+           Boolean             is_primary = FALSE;
+           Rank                rank = scan->rank;
+           Boolean             skip = FALSE;
+
+           if (primary == NULL
+               && RANK_ASSERTION_MASK(rank) != kRankAssertionNever) {
+               if (ElectionResultsCandidateNeedsDemotion(other_results,
+                                                         scan)) {
+                   /* demote to RankNever */
+                   my_log(LOG_NOTICE,
+                          "IPv%c over %@ demoted: not primary for IPv%c",
+                          ipvx_char(af), scan->if_name, ipvx_other_char(af));
+                   rank = RankMake(rank, kRankAssertionNever);
+                   deferred[deferred_count++] = scan;
+                   skip = TRUE;
+               }
+               else {
+                   primary = CFRetain(scan->serviceID);
+                   is_primary = TRUE;
+               }
+           }
+           if (af == AF_INET) {
+               /* generate the routing table for IPv4 */
+               CFDictionaryRef         service_dict;
+               IPv4RouteListRef        service_routes;
+
+               service_dict
+                   = service_dict_get(scan->serviceID, kSCEntNetIPv4);
+               service_routes = ipv4_dict_get_routelist(service_dict);
+               if (service_routes != NULL) {
+                   routes = IPv4RouteListAddRouteList(routes,
+                                                      results->count * 3,
+                                                      service_routes,
+                                                      rank);
+                   if (service_routes->exclude_from_nwi) {
+                       skip = TRUE;
+                   }
+               }
+               else {
+                   skip = TRUE;
+               }
+           }
+           else {
+               /* a NULL service must be excluded from nwi */
+               CFDictionaryRef         ipv6_dict;
 
 
-       dns_dict = CFDictionaryGetValue(values[i], kSCEntNetDNS);
-       if (dns_dict != NULL) {
-           CFStringRef         this_ifname;
+               ipv6_dict = service_dict_get(scan->serviceID, kSCEntNetIPv6);
 
 
-           this_ifname = CFDictionaryGetValue(dns_dict, kSCPropInterfaceName);
-           if (this_ifname != NULL
-               && CFEqual(this_ifname, ifname_cf)) {
-               has_dns = TRUE;
-               break;
+               if (S_dict_get_boolean(ipv6_dict, kIsNULL, FALSE)) {
+                   skip = TRUE;
+               }
+           }
+           if (skip) {
+               /* if we're skipping the primary, it's NULL */
+               if (is_primary) {
+                   primary_is_null = TRUE;
+               }
+           }
+           else {
+               if (primary_is_null) {
+                   /* everything after the primary must be Never */
+                   rank = RankMake(rank, kRankAssertionNever);
+               }
+               add_reachability_flags_to_candidate(scan, services_info, af);
+               add_candidate_to_nwi_state(nwi_state, af, scan, rank);
            }
        }
            }
        }
+       for (i = 0; i < deferred_count; i++) {
+           CandidateRef        candidate = deferred[i];
+           Rank                rank;
+
+           /* demote to RankNever */
+           rank = RankMake(candidate->rank, kRankAssertionNever);
+           add_reachability_flags_to_candidate(candidate, services_info, af);
+           add_candidate_to_nwi_state(nwi_state, af, candidate, rank);
+       }
+    }
+    if (nwi_state != NULL) {
+       nwi_state_set_last(nwi_state, af);
+    }
+    if (ret_routes != NULL) {
+       *ret_routes = routes;
     }
     }
-    CFRelease(ifname_cf);
-    return (has_dns);
+    else if (routes != NULL) {
+       free(routes);
+    }
+    if (primary_is_null) {
+       my_CFRelease(&primary);
+    }
+    return (primary);
+}
+
+
+static inline
+CFStringRef
+service_dict_get_signature(CFDictionaryRef service_dict)
+{
+    return (CFDictionaryGetValue(service_dict, kStoreKeyNetworkSignature));
 }
 
 }
 
+
+/*
+ * Function: elect_ipv4
+ * Purpose:
+ *   Evaluate the service and determine what rank the service should have.
+ *   If it's a suitable candidate, add it to the election results.
+ */
 static void
 static void
-update_nwi_state_ipv4(nwi_state_t state, IPv4RouteListRef route)
+elect_ipv4(const void * key, const void * value, void * context)
 {
 {
-    int                        idx;
-    IPv4RouteRef       r;
-    const void * *     values;
-    const void *       values_buf[10];
-    int                        values_count;
+    Candidate          candidate;
+    CFStringRef                if_name;
+    ElectionInfoRef    info;
+    Rank               primary_rank;
+    CFDictionaryRef    service_dict = (CFDictionaryRef)value;
+    IPv4RouteListRef   service_routes;
+    CFDictionaryRef    v4_dict;
+    CFDictionaryRef    v4_service_dict;
 
 
-    if (state == NULL) {
+    service_routes = service_dict_get_ipv4_routelist(service_dict);
+    if (service_routes == NULL) {
+       /* no service routes, no service */
        return;
     }
        return;
     }
-    nwi_state_clear(state, AF_INET);
-    if (route == NULL) {
+    if_name = service_dict_get_ipv4_ifname(service_dict);
+    if (if_name == NULL) {
+       /* need an interface name */
        return;
     }
        return;
     }
-    values_count = CFDictionaryGetCount(S_service_state_dict);
-    if (values_count == 0) {
+    if (CFEqual(if_name, CFSTR("lo0"))) {
+       /* don't ever elect loopback */
        return;
     }
        return;
     }
-    if (values_count <= (sizeof(values_buf) / sizeof(values_buf[0]))) {
-       values = values_buf;
-    }
-    else {
-       values = (const void * *)malloc(sizeof(*values) * values_count);
-    }
-    CFDictionaryGetKeysAndValues(S_service_state_dict,
-                                NULL, (const void * *)values);
-    for (idx = 0, r = route->list; idx < route->count; idx++, r++)  {
-       uint64_t                flags = 0ULL;
-
-       if (r->dest.s_addr != 0) {
-           /* we're done, no more default routes */
-           break;
-       }
-       if (RANK_ASSERTION_MASK(r->rank) == kRankAssertionNever) {
-           flags |= NWI_IFSTATE_FLAGS_NOT_IN_LIST;
-       }
-
-       if (interface_has_dns(values, values_count, r->ifname)) {
-           flags |= NWI_IFSTATE_FLAGS_HAS_DNS;
-       }
-       if ((S_IPMonitor_debug & kDebugFlag2) != 0) {
-           SCLog(TRUE, LOG_NOTICE, CFSTR("Inserting v4 [%s] with flags 0x%x primary_rank %u"),
-                 r->ifname, flags, r->rank);
-       }
-       nwi_insert_ifstate(state, r->ifname, AF_INET, flags, r->rank,
-                          (void *)&r->ifa);
-    }
-    if (values != values_buf) {
-       free(values);
+    info = (ElectionInfoRef)context;
+    bzero(&candidate, sizeof(candidate));
+    candidate.serviceID = (CFStringRef)key;
+    candidate.rank = get_service_rank(info->order, info->n_order,
+                                     candidate.serviceID);
+    primary_rank = RANK_ASSERTION_MASK(service_routes->list->rank);
+    if (S_ppp_override_primary
+       && (strncmp(PPP_PREFIX, service_routes->list->ifname,
+                   sizeof(PPP_PREFIX) - 1) == 0)) {
+       /* PPP override: make ppp* look the best */
+       /* Hack: should use interface type, not interface name */
+       primary_rank = kRankAssertionFirst;
     }
     }
-    nwi_state_set_last(state, AF_INET);
+    candidate.rank = RankMake(candidate.rank, primary_rank);
+    candidate.ip_is_coupled = service_get_ip_is_coupled(candidate.serviceID);
+    candidate.if_name = if_name;
+    candidate.addr.v4 = service_routes->list->ifa;
+    rank_dict_set_service_rank(S_ipv4_service_rank_dict,
+                              candidate.serviceID, candidate.rank);
+    v4_dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv4);
+    v4_service_dict = CFDictionaryGetValue(v4_dict, kIPv4DictService);
+    candidate.signature = service_dict_get_signature(v4_service_dict);
+    ElectionResultsAddCandidate(info->results, &candidate);
     return;
 }
 
     return;
 }
 
+
 /*
 /*
- * Function: elect_new_primary
+ * Function: elect_ipv6
  * Purpose:
  * Purpose:
- *   Walk the list of services, passing each service dictionary to "elect_func".
- *   "elect_func" returns rank information about the service that let us
- *   determine the new primary.
+ *   Evaluate the service and determine what rank the service should have.
+ *   If it's a suitable candidate, add it to the election results.
  */
  */
-static CFStringRef
-elect_new_primary(election_func_t * elect_func, void * context,
-                 CFArrayRef order, int n_order)
+static void
+elect_ipv6(const void * key, const void * value, void * context)
 {
 {
-    int                        count;
-    int                        i;
-    election_info_t    info;
-    void * *           keys;
-#define N_KEYS_VALUES_STATIC   10
-    void *             keys_values_buf[N_KEYS_VALUES_STATIC * 2];
-    CFStringRef                new_primary = NULL;
-    Rank               new_rank = 0;
-    void * *           values;
+    CFArrayRef         addrs;
+    Candidate          candidate;
+    CFStringRef                if_name;
+    ElectionInfoRef    info;
+    Rank               primary_rank = kRankAssertionDefault;
+    CFDictionaryRef    ipv6_dict;
+    CFStringRef                router;
+    CFDictionaryRef    service_dict = (CFDictionaryRef)value;
+    CFDictionaryRef    service_options;
 
 
-    count = CFDictionaryGetCount(S_service_state_dict);
-    if (count <= N_KEYS_VALUES_STATIC) {
-       keys = keys_values_buf;
+
+    ipv6_dict = CFDictionaryGetValue(service_dict, kSCEntNetIPv6);
+    if (ipv6_dict == NULL) {
+       /* no IPv6 */
+       return;
     }
     }
-    else {
-       keys = (void * *)malloc(sizeof(*keys) * count * 2);
+    if_name = CFDictionaryGetValue(ipv6_dict, kSCPropInterfaceName);
+    if (if_name == NULL) {
+       /* need an interface name */
+       return;
+    }
+    if (CFEqual(if_name, CFSTR("lo0"))) {
+       /* don't ever elect loopback */
+       return;
+    }
+    router = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Router);
+    if (router == NULL) {
+       /* don't care about services without a router */
+       return;
     }
     }
-    values = keys + count;
-    CFDictionaryGetKeysAndValues(S_service_state_dict,
-                                (const void * *)keys,
-                                (const void * *)values);
-
-    info.n_services = count;
-    info.order = order;
-    info.n_order = n_order;
-    new_rank = 0;
-    for (i = 0; i < count; i++) {
-       boolean_t       found_new_primary = FALSE;
-
-       info.serviceID = (CFStringRef)keys[i];
-       info.service_dict = (CFDictionaryRef)values[i];
-       info.rank = kRankAssertionMask;
+    info = (ElectionInfoRef)context;
+    bzero(&candidate, sizeof(candidate));
+    candidate.serviceID = (CFStringRef)key;
+    candidate.if_name = if_name;
+    addrs = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Addresses);
+    (void)cfstring_to_ip6(CFArrayGetValueAtIndex(addrs, 0),
+                         &candidate.addr.v6);
+    candidate.rank = get_service_rank(info->order, info->n_order,
+                                     candidate.serviceID);
+    service_options
+       = service_dict_get(candidate.serviceID, kSCEntNetService);
+    if (service_options != NULL) {
+       CFStringRef     primaryRankStr = NULL;
 
 
-       if ((*elect_func)(context, &info) == FALSE) {
-           continue;
+       primaryRankStr = CFDictionaryGetValue(service_options,
+                                             kSCPropNetServicePrimaryRank);
+       if (primaryRankStr != NULL) {
+           primary_rank = PrimaryRankGetRankAssertion(primaryRankStr);
        }
        }
-       if (new_primary == NULL
-           || (info.rank < new_rank)) {
-           found_new_primary = TRUE;
+       candidate.ip_is_coupled
+           = CFDictionaryContainsKey(service_options, kIPIsCoupled);
+    }
+    if (primary_rank != kRankAssertionNever) {
+       if (get_override_primary(ipv6_dict)) {
+           primary_rank = kRankAssertionFirst;
        }
        }
-
-       if (found_new_primary) {
-           new_primary = info.serviceID;
-           new_rank = info.rank;
+       else if (S_ppp_override_primary
+                && CFStringHasPrefix(if_name, CFSTR(PPP_PREFIX))) {
+           /* PPP override: make ppp* look the best */
+           /* Hack: should use interface type, not interface name */
+           primary_rank = kRankAssertionFirst;
        }
     }
        }
     }
-    if (new_primary != NULL) {
-       CFRetain(new_primary);
-    }
-    if (keys != keys_values_buf) {
-       free(keys);
-    }
-    return (new_primary);
+    candidate.rank = RankMake(candidate.rank, primary_rank);
+    rank_dict_set_service_rank(S_ipv6_service_rank_dict,
+                              candidate.serviceID, candidate.rank);
+    candidate.signature = service_dict_get_signature(ipv6_dict);
+    ElectionResultsAddCandidate(info->results, &candidate);
+    return;
 }
 
 static uint32_t
 }
 
 static uint32_t
@@ -4224,6 +5238,11 @@ service_changed(CFDictionaryRef services_info, CFStringRef serviceID)
            changed |= (1 << i);
        }
     }
            changed |= (1 << i);
        }
     }
+
+    if (get_transient_service_changes(serviceID, services_info)) {
+       changed |= (1 << kEntityTypeVPNStatus);
+    }
+
     return (changed);
 }
 
     return (changed);
 }
 
@@ -4267,27 +5286,27 @@ set_new_primary(CFStringRef * primary_p, CFStringRef new_primary,
     if (new_primary != NULL) {
        if (primary != NULL && CFEqual(new_primary, primary)) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     if (new_primary != NULL) {
        if (primary != NULL && CFEqual(new_primary, primary)) {
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor: %@ is still primary %s"),
-                     new_primary, entity);
+               my_log(LOG_DEBUG,
+                      "IPMonitor: %@ is still primary %s",
+                      new_primary, entity);
            }
        }
        else {
            my_CFRelease(primary_p);
            *primary_p = CFRetain(new_primary);
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            }
        }
        else {
            my_CFRelease(primary_p);
            *primary_p = CFRetain(new_primary);
            if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               SCLog(TRUE, LOG_NOTICE,
-                     CFSTR("IPMonitor: %@ is the new primary %s"),
-                     new_primary, entity);
+               my_log(LOG_DEBUG,
+                      "IPMonitor: %@ is the new primary %s",
+                      new_primary, entity);
            }
            changed = TRUE;
        }
     }
     else if (primary != NULL) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
            }
            changed = TRUE;
        }
     }
     else if (primary != NULL) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: %@ is no longer primary %s"),
-                 primary, entity);
+           my_log(LOG_DEBUG,
+                  "IPMonitor: %@ is no longer primary %s",
+                  primary, entity);
        }
        my_CFRelease(primary_p);
        changed = TRUE;
        }
        my_CFRelease(primary_p);
        changed = TRUE;
@@ -4305,13 +5324,6 @@ rank_service_entity(CFDictionaryRef rank_dict, CFStringRef serviceID,
     return (rank_dict_get_service_rank(rank_dict, serviceID));
 }
 
     return (rank_dict_get_service_rank(rank_dict, serviceID));
 }
 
-static __inline__ unsigned int
-IPv6RankedListComputeSize(int n)
-{
-       return (offsetof(IPv6RankedList, elem[n]));
-
-}
-
 static void
 update_interface_rank(CFDictionaryRef services_info, CFStringRef ifname)
 {
 static void
 update_interface_rank(CFDictionaryRef services_info, CFStringRef ifname)
 {
@@ -4362,8 +5374,9 @@ append_serviceIDs_for_interface(CFMutableArrayRef services_changed,
            interface = ipv4_dict_get_ifname(ipv4);
            if (interface != NULL && CFEqual(interface, ifname)) {
                if (S_IPMonitor_debug & kDebugFlag1) {
            interface = ipv4_dict_get_ifname(ipv4);
            if (interface != NULL && CFEqual(interface, ifname)) {
                if (S_IPMonitor_debug & kDebugFlag1) {
-                   SCLog(TRUE, LOG_NOTICE, CFSTR("Found ipv4 service %@ on interface %@."),
-                         serviceID, ifname);
+                   my_log(LOG_DEBUG,
+                          "Found ipv4 service %@ on interface %@.",
+                          serviceID, ifname);
                }
 
                my_CFArrayAppendUniqueValue(services_changed, serviceID);
                }
 
                my_CFArrayAppendUniqueValue(services_changed, serviceID);
@@ -4379,8 +5392,8 @@ append_serviceIDs_for_interface(CFMutableArrayRef services_changed,
            interface = CFDictionaryGetValue(proto_dict, kSCPropInterfaceName);
            if (interface != NULL && CFEqual(interface, ifname)) {
                if (S_IPMonitor_debug & kDebugFlag1) {
            interface = CFDictionaryGetValue(proto_dict, kSCPropInterfaceName);
            if (interface != NULL && CFEqual(interface, ifname)) {
                if (S_IPMonitor_debug & kDebugFlag1) {
-                   SCLog(TRUE, LOG_NOTICE, CFSTR("Found ipv6 service %@ on interface %@."),
-                         serviceID, ifname);
+                   my_log(LOG_DEBUG, "Found ipv6 service %@ on interface %@.",
+                          serviceID, ifname);
                }
 
                my_CFArrayAppendUniqueValue(services_changed, serviceID);
                }
 
                my_CFArrayAppendUniqueValue(services_changed, serviceID);
@@ -4393,31 +5406,7 @@ append_serviceIDs_for_interface(CFMutableArrayRef services_changed,
     }
 }
 
     }
 }
 
-static const CFStringRef *statusEntityNames[] = {
-    &kSCEntNetIPSec,
-    &kSCEntNetPPP,
-    &kSCEntNetVPN,
-};
-
-static void
-add_status_keys(CFMutableArrayRef patterns)
-{
-    int            i;
-
-    for (i = 0; i < sizeof(statusEntityNames)/sizeof(statusEntityNames[0]); i++) {
-       CFStringRef     pattern;
-
-       pattern = state_service_key(kSCCompAnyRegex, *statusEntityNames[i]);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-    }
-
-    return;
-}
-
-static
-inline
-const char *
+static __inline__ const char *
 get_changed_str(CFStringRef serviceID, CFStringRef entity, CFDictionaryRef old_dict)
 {
     CFDictionaryRef new_dict    = NULL;
 get_changed_str(CFStringRef serviceID, CFStringRef entity, CFDictionaryRef old_dict)
 {
     CFDictionaryRef new_dict    = NULL;
@@ -4522,7 +5511,7 @@ generate_log_changes(nwi_state_t  changes_state,
            str = "*";      // dnsinfo change w/no change to primary
        }
        CFStringAppendFormat(log_output, NULL, CFSTR(" DNS%s"), str);
            str = "*";      // dnsinfo change w/no change to primary
        }
        CFStringAppendFormat(log_output, NULL, CFSTR(" DNS%s"), str);
-    } else if (S_primary_dns != NULL){
+    } else if (S_primary_dns != NULL) {
        CFStringAppendFormat(log_output, NULL, CFSTR(" DNS"));
     }
 
        CFStringAppendFormat(log_output, NULL, CFSTR(" DNS"));
     }
 
@@ -4549,11 +5538,161 @@ generate_log_changes(nwi_state_t       changes_state,
     return log_output;
 }
 
     return log_output;
 }
 
+#pragma mark -
+#pragma mark Network changed notification
+
+static dispatch_queue_t
+__network_change_queue()
+{
+    static dispatch_once_t     once;
+    static dispatch_queue_t    q;
+
+    dispatch_once(&once, ^{
+       q = dispatch_queue_create("network change queue", NULL);
+    });
+
+    return q;
+}
+
+// Note: must run on __network_change_queue()
+static void
+post_network_change_when_ready()
+{
+    int                    status;
+
+    if (S_network_change_needed == 0) {
+       return;
+    }
+
+    if (!S_network_change_timeout &&
+       (!S_dnsinfo_synced || !S_nwi_synced)) {
+       // if we [still] need to wait for the DNS configuration
+       // or network information changes to be ack'd
+
+       if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
+           my_log(LOG_DEBUG,
+                  "Defer \"" _SC_NOTIFY_NETWORK_CHANGE "\" (%s, %s)",
+                  S_dnsinfo_synced ? "DNS" : "!DNS",
+                  S_nwi_synced     ? "nwi" : "!nwi");
+       }
+       return;
+    }
+
+    // cancel any running timer
+    if (S_network_change_timer != NULL) {
+       dispatch_source_cancel(S_network_change_timer);
+       dispatch_release(S_network_change_timer);
+       S_network_change_timer = NULL;
+       S_network_change_timeout = FALSE;
+    }
+
+    // set (and log?) the post time
+    if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
+       struct timeval  elapsed;
+       struct timeval  end;
+
+       (void) gettimeofday(&end, NULL);
+       timersub(&end, &S_network_change_start, &elapsed);
+
+#define        QUERY_TIME__FMT "%d.%6.6d"
+#define        QUERY_TIME__DIV 1
+
+       my_log(LOG_DEBUG,
+              "Post \"" _SC_NOTIFY_NETWORK_CHANGE "\" (%s: " QUERY_TIME__FMT ": 0x%x)",
+              S_network_change_timeout ? "timeout" : "delayed",
+              elapsed.tv_sec,
+              elapsed.tv_usec / QUERY_TIME__DIV,
+              S_network_change_needed);
+    }
+
+    if ((S_network_change_needed & NETWORK_CHANGE_NET) != 0) {
+       status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_NWI);
+       if (status != NOTIFY_STATUS_OK) {
+           my_log(LOG_ERR,
+                  "IPMonitor: notify_post(" _SC_NOTIFY_NETWORK_CHANGE_NWI ") failed: error=%ld", status);
+       }
+    }
+
+    if ((S_network_change_needed & NETWORK_CHANGE_DNS) != 0) {
+       status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_DNS);
+       if (status != NOTIFY_STATUS_OK) {
+           my_log(LOG_ERR,
+                  "IPMonitor: notify_post(" _SC_NOTIFY_NETWORK_CHANGE_DNS ") failed: error=%ld", status);
+       }
+    }
+
+    if ((S_network_change_needed & NETWORK_CHANGE_PROXY) != 0) {
+       status = notify_post(_SC_NOTIFY_NETWORK_CHANGE_PROXY);
+       if (status != NOTIFY_STATUS_OK) {
+           my_log(LOG_ERR,
+                  "IPMonitor: notify_post(" _SC_NOTIFY_NETWORK_CHANGE_PROXY ") failed: error=%ld", status);
+       }
+    }
+
+    status = notify_post(_SC_NOTIFY_NETWORK_CHANGE);
+    if (status != NOTIFY_STATUS_OK) {
+       my_log(LOG_ERR,
+              "IPMonitor: notify_post(" _SC_NOTIFY_NETWORK_CHANGE ") failed: error=%ld", status);
+    }
+
+    S_network_change_needed = 0;
+    return;
+}
+
+#define TRAILING_EDGE_TIMEOUT_NSEC     5 * NSEC_PER_SEC    // 5s
+
+// Note: must run on __network_change_queue()
+static void
+post_network_change(uint32_t change)
+{
+    if (S_network_change_needed == 0) {
+       // set the start time
+       (void) gettimeofday(&S_network_change_start, NULL);
+    }
+
+    // indicate that we need to post a change for ...
+    S_network_change_needed |= change;
+
+    // cancel any running timer
+    if (S_network_change_timer != NULL) {
+       dispatch_source_cancel(S_network_change_timer);
+       dispatch_release(S_network_change_timer);
+       S_network_change_timer = NULL;
+       S_network_change_timeout = FALSE;
+    }
+
+    // if needed, start new timer
+    if (!S_dnsinfo_synced || !S_nwi_synced) {
+       S_network_change_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
+                                                       0,
+                                                       0,
+                                                       __network_change_queue());
+       dispatch_source_set_event_handler(S_network_change_timer, ^{
+           S_network_change_timeout = TRUE;
+           post_network_change_when_ready();
+       });
+       dispatch_source_set_timer(S_network_change_timer,
+                                 dispatch_time(DISPATCH_TIME_NOW,
+                                               TRAILING_EDGE_TIMEOUT_NSEC),    // start
+                                 0,                                            // interval
+                                 10 * NSEC_PER_MSEC);                          // leeway
+       dispatch_resume(S_network_change_timer);
+    }
+
+    post_network_change_when_ready();
+
+    return;
+}
+
+#pragma mark -
+#pragma mark Process network (SCDynamicStore) changes
+
 static void
 IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
                void * not_used)
 {
     CFIndex            count;
 static void
 IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
                void * not_used)
 {
     CFIndex            count;
+    uint32_t           changes                 = 0;
     nwi_state_t                changes_state           = NULL;
     boolean_t          dns_changed             = FALSE;
     boolean_t          dnsinfo_changed         = FALSE;
     nwi_state_t                changes_state           = NULL;
     boolean_t          dns_changed             = FALSE;
     boolean_t          dnsinfo_changed         = FALSE;
@@ -4563,7 +5702,7 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
     CFMutableArrayRef  if_rank_changes         = NULL;
     keyChangeList      keys;
     CFIndex            n;
     CFMutableArrayRef  if_rank_changes         = NULL;
     keyChangeList      keys;
     CFIndex            n;
-    CFStringRef                network_change_msg;
+    CFStringRef                network_change_msg      = NULL;
     int                        n_services;
     int                        n_service_order         = 0;
     nwi_state_t                old_nwi_state           = NULL;
     int                        n_services;
     int                        n_service_order         = 0;
     nwi_state_t                old_nwi_state           = NULL;
@@ -4573,6 +5712,7 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
     CFDictionaryRef    old_primary_smb         = NULL;
 #endif // !TARGET_OS_IPHONE
     boolean_t          proxies_changed         = FALSE;
     CFDictionaryRef    old_primary_smb         = NULL;
 #endif // !TARGET_OS_IPHONE
     boolean_t          proxies_changed         = FALSE;
+    boolean_t          reachability_changed    = FALSE;
     CFArrayRef         service_order;
     CFMutableArrayRef  service_changes         = NULL;
     CFDictionaryRef    services_info           = NULL;
     CFArrayRef         service_order;
     CFMutableArrayRef  service_changes         = NULL;
     CFDictionaryRef    services_info           = NULL;
@@ -4586,8 +5726,8 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
     }
 
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     }
 
     if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-       SCLog(TRUE, LOG_NOTICE,
-             CFSTR("IPMonitor: changes %@ (%d)"), changed_keys, count);
+       my_log(LOG_DEBUG,
+              "IPMonitor: changes %@ (%d)", changed_keys, count);
     }
 
     if (S_primary_dns != NULL) {
     }
 
     if (S_primary_dns != NULL) {
@@ -4636,32 +5776,43 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
 #endif /* !TARGET_OS_IPHONE */
        else if (CFStringHasPrefix(change, S_state_service_prefix)) {
            int         i;
 #endif /* !TARGET_OS_IPHONE */
        else if (CFStringHasPrefix(change, S_state_service_prefix)) {
            int         i;
-           boolean_t   status_changed = FALSE;
+           CFStringRef serviceID;
 
            for (i = 0; i < sizeof(statusEntityNames)/sizeof(statusEntityNames[0]); i++) {
                if (CFStringHasSuffix(change, *statusEntityNames[i])) {
 
            for (i = 0; i < sizeof(statusEntityNames)/sizeof(statusEntityNames[0]); i++) {
                if (CFStringHasSuffix(change, *statusEntityNames[i])) {
-                   status_changed = TRUE;
                    dnsinfo_changed = TRUE;
                    break;
                }
            }
 
                    dnsinfo_changed = TRUE;
                    break;
                }
            }
 
-           if (!status_changed) {
-               CFStringRef serviceID = parse_component(change,
-                                                       S_state_service_prefix);
-               if (serviceID) {
-                   my_CFArrayAppendUniqueValue(service_changes, serviceID);
-                   CFRelease(serviceID);
-               }
+           serviceID = parse_component(change, S_state_service_prefix);
+           if (serviceID) {
+               my_CFArrayAppendUniqueValue(service_changes, serviceID);
+               CFRelease(serviceID);
            }
        }
        else if (CFStringHasPrefix(change, S_setup_service_prefix)) {
            }
        }
        else if (CFStringHasPrefix(change, S_setup_service_prefix)) {
+           int j;
+
            CFStringRef serviceID = parse_component(change,
                                                    S_setup_service_prefix);
            if (serviceID) {
                my_CFArrayAppendUniqueValue(service_changes, serviceID);
                CFRelease(serviceID);
            }
            CFStringRef serviceID = parse_component(change,
                                                    S_setup_service_prefix);
            if (serviceID) {
                my_CFArrayAppendUniqueValue(service_changes, serviceID);
                CFRelease(serviceID);
            }
+
+           for (j = 0; j < sizeof(transientInterfaceEntityNames)/sizeof(transientInterfaceEntityNames[0]); j++) {
+               if (CFStringHasSuffix(change, *transientInterfaceEntityNames[j])) {
+                   reachability_changed = TRUE;
+                   break;
+               }
+           }
+
+           if (CFStringHasSuffix(change, kSCEntNetInterface)) {
+                reachability_changed = TRUE;
+           }
+
+
        }
        else if (CFStringHasSuffix(change, kSCEntNetService)) {
            CFStringRef ifname = my_CFStringCopyComponent(change, CFSTR("/"), 3);
        }
        else if (CFStringHasSuffix(change, kSCEntNetService)) {
            CFStringRef ifname = my_CFStringCopyComponent(change, CFSTR("/"), 3);
@@ -4684,8 +5835,8 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
            CFStringRef ifname = CFArrayGetValueAtIndex(if_rank_changes, i);
 
            if (S_IPMonitor_debug & kDebugFlag1) {
            CFStringRef ifname = CFArrayGetValueAtIndex(if_rank_changes, i);
 
            if (S_IPMonitor_debug & kDebugFlag1) {
-               SCLog(TRUE, LOG_NOTICE, CFSTR("Interface rank changed %@"),
-                     ifname);
+               my_log(LOG_DEBUG, "Interface rank changed %@",
+                      ifname);
            }
            append_serviceIDs_for_interface(service_changes, ifname);
        }
            }
            append_serviceIDs_for_interface(service_changes, ifname);
        }
@@ -4698,8 +5849,8 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
     if (service_order != NULL) {
        n_service_order = CFArrayGetCount(service_order);
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
     if (service_order != NULL) {
        n_service_order = CFArrayGetCount(service_order);
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: service_order %@ "), service_order);
+           my_log(LOG_DEBUG,
+                  "IPMonitor: service_order %@ ", service_order);
        }
     }
 
        }
     }
 
@@ -4736,7 +5887,7 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
        }
        if ((changes & (1 << kEntityTypeDNS)) != 0) {
            if (S_primary_dns != NULL && CFEqual(S_primary_dns, serviceID)) {
        }
        if ((changes & (1 << kEntityTypeDNS)) != 0) {
            if (S_primary_dns != NULL && CFEqual(S_primary_dns, serviceID)) {
-               update_dns(services_info, serviceID, &keys);
+               dns_changed = TRUE;
            }
            dnsinfo_changed = TRUE;
        }
            }
            dnsinfo_changed = TRUE;
        }
@@ -4746,74 +5897,75 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
 #if    !TARGET_OS_IPHONE
        if ((changes & (1 << kEntityTypeSMB)) != 0) {
            if (S_primary_smb != NULL && CFEqual(S_primary_smb, serviceID)) {
 #if    !TARGET_OS_IPHONE
        if ((changes & (1 << kEntityTypeSMB)) != 0) {
            if (S_primary_smb != NULL && CFEqual(S_primary_smb, serviceID)) {
-               update_smb(services_info, serviceID, &keys);
+               smb_changed = TRUE;
            }
        }
            }
        }
-#endif /* !TARGET_OS_IPHONE */
+#endif
     }
 
     }
 
+       if ((changes & (1 <<kEntityTypeVPNStatus)) != 0) {
+           global_ipv4_changed = TRUE;
+           global_ipv6_changed = TRUE;
+       }
+
     /* ensure S_nwi_state can hold as many services as we have currently */
     n_services = CFDictionaryGetCount(S_service_state_dict);
     old_nwi_state = nwi_state_copy_priv(S_nwi_state);
     S_nwi_state = nwi_state_new(S_nwi_state, n_services);
 
     /* ensure S_nwi_state can hold as many services as we have currently */
     n_services = CFDictionaryGetCount(S_service_state_dict);
     old_nwi_state = nwi_state_copy_priv(S_nwi_state);
     S_nwi_state = nwi_state_new(S_nwi_state, n_services);
 
-    if (global_ipv4_changed || dnsinfo_changed) {
-       IPv4RouteListRef        new_routelist = NULL;
-       CFStringRef             new_primary;
-
+    if (global_ipv4_changed) {
+       if (S_ipv4_results != NULL) {
+           ElectionResultsRelease(S_ipv4_results);
+       }
+       S_ipv4_results
+           = ElectionResultsCopy(elect_ipv4, service_order, n_service_order);
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: IPv4 service election"));
+           ElectionResultsLog(LOG_DEBUG, S_ipv4_results, "IPv4");
        }
        }
-       new_primary = elect_new_primary(&elect_ipv4, &new_routelist,
-                                       service_order, n_service_order);
-       update_nwi_state_ipv4(S_nwi_state, new_routelist);
-
-       if (global_ipv4_changed) {
-           (void)set_new_primary(&S_primary_ipv4, new_primary, "IPv4");
-           update_ipv4(S_primary_ipv4, new_routelist, &keys);
+    }
+    if (global_ipv6_changed) {
+       if (S_ipv6_results != NULL) {
+           ElectionResultsRelease(S_ipv6_results);
        }
        }
-       else if (new_routelist != NULL) {
-           free(new_routelist);
-           new_routelist = NULL;
+       S_ipv6_results
+           = ElectionResultsCopy(elect_ipv6, service_order, n_service_order);
+       if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
+           ElectionResultsLog(LOG_DEBUG, S_ipv6_results, "IPv6");
        }
        }
-       my_CFRelease(&new_primary);
     }
     }
-    if (global_ipv6_changed || dnsinfo_changed) {
-       IPv6RankedListRef       list = NULL;
+    if (global_ipv4_changed || global_ipv6_changed || dnsinfo_changed) {
        CFStringRef             new_primary;
        CFStringRef             new_primary;
-       int                     size;
-
-       size = (n_services != 0)
-           ? (sizeof(IPv6RankedList)
-              + IPv6RankedListComputeSize(n_services)) : 0;
-
-       if (size != 0) {
-           list = malloc(size);
-       }
-       if (list != NULL) {
-           list->count = 0;
-           list->size = size;
-       }
+       IPv4RouteListRef        new_routelist = NULL;
 
 
+       /* IPv4 */
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
        if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-           SCLog(TRUE, LOG_NOTICE,
-                 CFSTR("IPMonitor: IPv6 service election"));
-       }
-       new_primary = elect_new_primary(&elect_ipv6, list,
-                                       service_order, n_service_order);
-       update_nwi_state_ipv6(S_nwi_state, list);
-
-       if (global_ipv6_changed) {
-           (void)set_new_primary(&S_primary_ipv6, new_primary, "IPv6");
-           update_ipv6(services_info, S_primary_ipv6, &keys);
-       }
+           my_log(LOG_DEBUG,
+                  "IPMonitor: electing IPv4 primary");
+       }
+       new_primary = ElectionResultsCopyPrimary(S_ipv4_results,
+                                                S_ipv6_results,
+                                                S_nwi_state, AF_INET,
+                                                &new_routelist,
+                                                services_info);
+       (void)set_new_primary(&S_primary_ipv4, new_primary, "IPv4");
+       update_ipv4(S_primary_ipv4, new_routelist, &keys);
+       my_CFRelease(&new_primary);
 
 
-       if (list != NULL) {
-           free(list);
-       }
+       /* IPv6 */
+       if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
+           my_log(LOG_DEBUG,
+                  "IPMonitor: electing IPv6 primary");
+       }
+       new_primary = ElectionResultsCopyPrimary(S_ipv6_results,
+                                                S_ipv4_results,
+                                                S_nwi_state, AF_INET6,
+                                                NULL,
+                                                services_info);
+       (void)set_new_primary(&S_primary_ipv6, new_primary, "IPv6");
+       update_ipv6(S_primary_ipv6, &keys);
        my_CFRelease(&new_primary);
     }
        my_CFRelease(&new_primary);
     }
+
     if (global_ipv4_changed || global_ipv6_changed) {
        CFStringRef     new_primary_dns     = NULL;
        CFStringRef     new_primary_proxies = NULL;
     if (global_ipv4_changed || global_ipv6_changed) {
        CFStringRef     new_primary_dns     = NULL;
        CFStringRef     new_primary_proxies = NULL;
@@ -4870,7 +6022,6 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
        }
 
        if (set_new_primary(&S_primary_dns, new_primary_dns, "DNS")) {
        }
 
        if (set_new_primary(&S_primary_dns, new_primary_dns, "DNS")) {
-           update_dns(services_info, S_primary_dns, &keys);
            dns_changed = TRUE;
            dnsinfo_changed = TRUE;
        }
            dns_changed = TRUE;
            dnsinfo_changed = TRUE;
        }
@@ -4879,62 +6030,122 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
        }
 #if    !TARGET_OS_IPHONE
        if (set_new_primary(&S_primary_smb, new_primary_smb, "SMB")) {
        }
 #if    !TARGET_OS_IPHONE
        if (set_new_primary(&S_primary_smb, new_primary_smb, "SMB")) {
-           update_smb(services_info, S_primary_smb, &keys);
            smb_changed = TRUE;
        }
 #endif /* !TARGET_OS_IPHONE */
     }
            smb_changed = TRUE;
        }
 #endif /* !TARGET_OS_IPHONE */
     }
-    if (dnsinfo_changed || global_ipv4_changed || global_ipv6_changed) {
+
+    if (!proxies_changed && dnsinfo_changed &&
+       ((G_supplemental_proxies_follow_dns != NULL) && CFBooleanGetValue(G_supplemental_proxies_follow_dns))) {
+       proxies_changed = TRUE;
+    }
+
+    changes_state = nwi_state_diff(old_nwi_state, S_nwi_state);
+
+    if (global_ipv4_changed || global_ipv6_changed || dnsinfo_changed || reachability_changed) {
        if (S_nwi_state != NULL) {
            S_nwi_state->generation_count = mach_absolute_time();
        if (S_nwi_state != NULL) {
            S_nwi_state->generation_count = mach_absolute_time();
-           if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
-               syslog(LOG_NOTICE, "Updating network information");
-               _nwi_state_dump(LOG_NOTICE, S_nwi_state);
-           }
-           if (_nwi_state_store(S_nwi_state) == FALSE) {
-               SCLog(TRUE, LOG_ERR, CFSTR("Notifying nwi_state_store failed"));
+           if (global_ipv4_changed || global_ipv6_changed || reachability_changed) {
+               SCNetworkReachabilityFlags reach_flags_v4 = 0;
+               SCNetworkReachabilityFlags reach_flags_v6 = 0;
+
+               GetReachabilityFlagsFromTransientServices(services_info,
+                                                         &reach_flags_v4,
+                                                         &reach_flags_v6);
+
+               _nwi_state_set_reachability_flags(S_nwi_state, reach_flags_v4, reach_flags_v6);
            }
            }
+
+           /* Update the per-interface generation count */
+           _nwi_state_update_interface_generations(old_nwi_state, S_nwi_state, changes_state);
+       }
+
+       if (update_nwi(S_nwi_state)) {
+           changes |= NETWORK_CHANGE_NET;
+
+           /*
+            * the DNS configuration includes per-resolver configuration
+            * reachability flags that are based on the nwi state.  Let's
+            * make sure that we check for changes
+            */
+           dnsinfo_changed = TRUE;
+       }
+    }
+    if (dns_changed) {
+       if (update_dns(services_info, S_primary_dns, &keys)) {
+           changes |= NETWORK_CHANGE_DNS;
+           dnsinfo_changed = TRUE;
+       } else {
+           dns_changed = FALSE;
        }
     }
     if (dnsinfo_changed) {
        }
     }
     if (dnsinfo_changed) {
-       update_dnsinfo(services_info, S_primary_dns, &keys, service_order);
+       if (update_dnsinfo(services_info, S_primary_dns, &keys, service_order)) {
+           changes |= NETWORK_CHANGE_DNS;
+       } else {
+           dnsinfo_changed = FALSE;
+       }
     }
     }
-    if (proxies_changed ||
-       (dnsinfo_changed && (G_supplemental_proxies_follow_dns != NULL) && CFBooleanGetValue(G_supplemental_proxies_follow_dns))
-       ) {
+    if (proxies_changed) {
        // if proxy change OR supplemental Proxies follow supplemental DNS
        // if proxy change OR supplemental Proxies follow supplemental DNS
-       update_proxies(services_info, S_primary_proxies, &keys, service_order);
-       proxies_changed = TRUE;
+       if (update_proxies(services_info, S_primary_proxies, &keys, service_order)) {
+           changes |= NETWORK_CHANGE_PROXY;
+       } else {
+           proxies_changed = FALSE;
+       }
+    }
+#if    !TARGET_OS_IPHONE
+    if (smb_changed) {
+       if (update_smb(services_info, S_primary_smb, &keys)) {
+           changes |= NETWORK_CHANGE_SMB;
+       } else {
+           smb_changed = FALSE;
+       }
     }
     }
+#endif /* !TARGET_OS_IPHONE */
     my_CFRelease(&service_changes);
     my_CFRelease(&services_info);
     my_CFRelease(&if_rank_changes);
     my_CFRelease(&service_changes);
     my_CFRelease(&services_info);
     my_CFRelease(&if_rank_changes);
-    changes_state = nwi_state_diff(old_nwi_state, S_nwi_state);
-    if ((S_IPMonitor_debug & kDebugFlag2) != 0) {
-       syslog(LOG_NOTICE, "network information diffs: ");
-       _nwi_state_dump(LOG_NOTICE, changes_state);
-    }
-    network_change_msg =
-       generate_log_changes(changes_state,
-                            dns_changed,
-                            dnsinfo_changed,
-                            old_primary_dns,
-                            proxies_changed,
-                            old_primary_proxy,
+
+    if (changes != 0) {
+       network_change_msg =
+           generate_log_changes(changes_state,
+                                dns_changed,
+                                dnsinfo_changed,
+                                old_primary_dns,
+                                proxies_changed,
+                                old_primary_proxy,
 #if    !TARGET_OS_IPHONE
 #if    !TARGET_OS_IPHONE
-                            smb_changed,
-                            old_primary_smb
+                                smb_changed,
+                                old_primary_smb
 #else  // !TARGET_OS_IPHONE
 #else  // !TARGET_OS_IPHONE
-                            FALSE,
-                            NULL
+                                FALSE,         // smb_changed
+                                NULL           // old_primary_smb
 #endif // !TARGET_OS_IPHONE
 #endif // !TARGET_OS_IPHONE
-                            );
-    keyChangeListApplyToStore(&keys, session, network_change_msg);
+                                );
+    }
+
+    keyChangeListApplyToStore(&keys, session);
     my_CFRelease(&old_primary_dns);
     my_CFRelease(&old_primary_proxy);
 #if    !TARGET_OS_IPHONE
     my_CFRelease(&old_primary_smb);
 #endif // !TARGET_OS_IPHONE
     my_CFRelease(&old_primary_dns);
     my_CFRelease(&old_primary_proxy);
 #if    !TARGET_OS_IPHONE
     my_CFRelease(&old_primary_smb);
 #endif // !TARGET_OS_IPHONE
+
+    if (changes != 0) {
+       dispatch_async(__network_change_queue(), ^{
+           post_network_change(changes);
+       });
+    }
+
+    if ((network_change_msg != NULL) && (CFStringGetLength(network_change_msg) != 0)) {
+       my_log(LOG_NOTICE, "network changed:%@", network_change_msg);
+    } else if (keyChangeListActive(&keys)) {
+       my_log(LOG_NOTICE, "network changed.");
+    } else {
+       my_log(LOG_DEBUG, "network event w/no changes");
+    }
+
     my_CFRelease(&network_change_msg);
 
     if (changes_state != NULL) {
     my_CFRelease(&network_change_msg);
 
     if (changes_state != NULL) {
@@ -4947,6 +6158,78 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys,
     return;
 }
 
     return;
 }
 
+static void
+watch_proxies()
+{
+#if    !TARGET_OS_IPHONE
+    const _scprefs_observer_type type = scprefs_observer_type_mcx;
+#else
+    const _scprefs_observer_type type = scprefs_observer_type_global;
+#endif
+    static dispatch_queue_t proxy_cb_queue;
+
+    proxy_cb_queue = dispatch_queue_create("com.apple.SystemConfiguration.IPMonitor.proxy", NULL);
+    _scprefs_observer_watch(type,
+                            "com.apple.SystemConfiguration.plist",
+                            proxy_cb_queue,
+                            ^{
+                                SCDynamicStoreNotifyValue(NULL, S_state_global_proxies);
+                                notify_post(_SC_NOTIFY_NETWORK_CHANGE_PROXY);
+                                my_log(LOG_DEBUG, "IPMonitor: Notifying:\n%@",
+                                       S_state_global_proxies);
+                            });
+    return;
+}
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+#include "IPMonitorControlPrefs.h"
+
+__private_extern__ SCLoggerRef
+my_log_get_logger()
+{
+    return (S_IPMonitor_logger);
+}
+
+static void
+prefs_changed(__unused SCPreferencesRef prefs)
+{
+    if (S_bundle_logging_verbose || IPMonitorControlPrefsIsVerbose()) {
+       S_IPMonitor_debug = kDebugFlagDefault;
+       S_IPMonitor_verbose = TRUE;
+       SCLoggerSetFlags(S_IPMonitor_logger, kSCLoggerFlagsFile | kSCLoggerFlagsDefault);
+       my_log(LOG_DEBUG, "IPMonitor: Setting logging verbose mode on.");
+    } else {
+       my_log(LOG_DEBUG, "IPMonitor: Setting logging verbose mode off.");
+       S_IPMonitor_debug = 0;
+       S_IPMonitor_verbose = FALSE;
+       SCLoggerSetFlags(S_IPMonitor_logger, kSCLoggerFlagsDefault);
+    }
+    return;
+}
+
+#define LOGGER_ID CFSTR("com.apple.networking.IPMonitor")
+static void
+my_log_init()
+{
+    if (S_IPMonitor_logger != NULL) {
+       return;
+    }
+    S_IPMonitor_logger = SCLoggerCreate(LOGGER_ID);
+    return;
+
+}
+
+#else  // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+static void
+my_log_init()
+{
+    return;
+}
+
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+
 static void
 ip_plugin_init()
 {
 static void
 ip_plugin_init()
 {
@@ -4972,9 +6255,9 @@ ip_plugin_init()
     S_session = SCDynamicStoreCreate(NULL, CFSTR("IPMonitor"),
                                   IPMonitorNotify, NULL);
     if (S_session == NULL) {
     S_session = SCDynamicStoreCreate(NULL, CFSTR("IPMonitor"),
                                   IPMonitorNotify, NULL);
     if (S_session == NULL) {
-       SCLog(TRUE, LOG_ERR,
-             CFSTR("IPMonitor ip_plugin_init SCDynamicStoreCreate failed: %s"),
-             SCErrorString(SCError()));
+       my_log(LOG_ERR,
+              "IPMonitor ip_plugin_init SCDynamicStoreCreate failed: %s",
+              SCErrorString(SCError()));
        return;
     }
     S_state_global_ipv4
        return;
     }
     S_state_global_ipv4
@@ -5034,8 +6317,20 @@ ip_plugin_init()
     /* register for State: and Setup: per-service notifications */
     add_service_keys(kSCCompAnyRegex, keys, patterns);
 
     /* register for State: and Setup: per-service notifications */
     add_service_keys(kSCCompAnyRegex, keys, patterns);
 
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetPPP);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetVPN);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
+    pattern = setup_service_key(kSCCompAnyRegex, kSCEntNetInterface);
+    CFArrayAppendValue(patterns, pattern);
+    CFRelease(pattern);
+
     /* register for State: per-service PPP/VPN/IPSec status notifications */
     /* register for State: per-service PPP/VPN/IPSec status notifications */
-    add_status_keys(patterns);
+    add_status_keys(kSCCompAnyRegex, patterns);
 
     /* register for interface rank notifications */
     pattern = if_rank_key_copy(kSCCompAnyRegex);
 
     /* register for interface rank notifications */
     pattern = if_rank_key_copy(kSCCompAnyRegex);
@@ -5060,19 +6355,19 @@ ip_plugin_init()
     CFArrayAppendValue(keys, S_private_resolvers);
 
     if (!SCDynamicStoreSetNotificationKeys(S_session, keys, patterns)) {
     CFArrayAppendValue(keys, S_private_resolvers);
 
     if (!SCDynamicStoreSetNotificationKeys(S_session, keys, patterns)) {
-       SCLog(TRUE, LOG_ERR,
-             CFSTR("IPMonitor ip_plugin_init "
-                   "SCDynamicStoreSetNotificationKeys failed: %s"),
+       my_log(LOG_ERR,
+              "IPMonitor ip_plugin_init "
+              "SCDynamicStoreSetNotificationKeys failed: %s",
              SCErrorString(SCError()));
        goto done;
     }
 
     rls = SCDynamicStoreCreateRunLoopSource(NULL, S_session, 0);
     if (rls == NULL) {
              SCErrorString(SCError()));
        goto done;
     }
 
     rls = SCDynamicStoreCreateRunLoopSource(NULL, S_session, 0);
     if (rls == NULL) {
-       SCLog(TRUE, LOG_ERR,
-             CFSTR("IPMonitor ip_plugin_init "
-                   "SCDynamicStoreCreateRunLoopSource failed: %s"),
-             SCErrorString(SCError()));
+       my_log(LOG_ERR,
+              "IPMonitor ip_plugin_init "
+              "SCDynamicStoreCreateRunLoopSource failed: %s",
+              SCErrorString(SCError()));
        goto done;
     }
 
        goto done;
     }
 
@@ -5092,6 +6387,7 @@ ip_plugin_init()
 #endif /* !TARGET_OS_IPHONE */
 
     if_rank_dict_init();
 #endif /* !TARGET_OS_IPHONE */
 
     if_rank_dict_init();
+    watch_proxies();
 
   done:
     my_CFRelease(&keys);
 
   done:
     my_CFRelease(&keys);
@@ -5129,6 +6425,7 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose)
     CFDictionaryRef    info_dict;
 
     info_dict = CFBundleGetInfoDictionary(bundle);
     CFDictionaryRef    info_dict;
 
     info_dict = CFBundleGetInfoDictionary(bundle);
+
     if (info_dict != NULL) {
        S_append_state
            = S_get_plist_boolean(info_dict,
     if (info_dict != NULL) {
        S_append_state
            = S_get_plist_boolean(info_dict,
@@ -5137,10 +6434,51 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose)
     }
     if (bundleVerbose) {
        S_IPMonitor_debug = kDebugFlagDefault;
     }
     if (bundleVerbose) {
        S_IPMonitor_debug = kDebugFlagDefault;
-    }
+       S_bundle_logging_verbose = bundleVerbose;
+       S_IPMonitor_verbose = TRUE;
+    }
+
+    my_log_init();
+
+#if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+    /* register to receive changes to verbose and read the initial setting  */
+    IPMonitorControlPrefsInit(CFRunLoopGetCurrent(), prefs_changed);
+    prefs_changed(NULL);
+
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+    load_DNSConfiguration(bundle,                      // bundle
+                         S_IPMonitor_logger,           // SCLogger
+                         &S_IPMonitor_verbose,         // bundleVerbose
+                         ^(Boolean inSync) {           // syncHandler
+                             dispatch_async(__network_change_queue(), ^{
+                                 S_dnsinfo_synced = inSync;
+
+                                 if (inSync &&
+                                     ((S_network_change_needed & NETWORK_CHANGE_DNS) == 0)) {
+                                     // all of the mDNSResponder ack's should result
+                                     // in a [new] network change being posted
+                                     post_network_change(NETWORK_CHANGE_DNS);
+                                 } else {
+                                     post_network_change_when_ready();
+                                 }
+                             });
+                         });
+
+    load_NetworkInformation(bundle,                    // bundle
+                           S_IPMonitor_logger,         // SCLogger
+                           &S_IPMonitor_verbose,       // bundleVerbose
+                           ^(Boolean inSync) {         // syncHandler
+                               dispatch_async(__network_change_queue(), ^{
+                                   S_nwi_synced = inSync;
+                                   post_network_change_when_ready();
+                               });
+                           });
 
     dns_configuration_init(bundle);
 
     dns_configuration_init(bundle);
+
     proxy_configuration_init(bundle);
     proxy_configuration_init(bundle);
+
     ip_plugin_init();
 
 #if    !TARGET_OS_IPHONE
     ip_plugin_init();
 
 #if    !TARGET_OS_IPHONE
@@ -5149,7 +6487,10 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose)
     }
 #endif /* !TARGET_OS_IPHONE */
 
     }
 #endif /* !TARGET_OS_IPHONE */
 
+#if    !TARGET_IPHONE_SIMULATOR
     load_hostname((S_IPMonitor_debug & kDebugFlag1) != 0);
     load_hostname((S_IPMonitor_debug & kDebugFlag1) != 0);
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
 #if    !TARGET_OS_IPHONE
     load_smb_configuration((S_IPMonitor_debug & kDebugFlag1) != 0);
 #endif /* !TARGET_OS_IPHONE */
 #if    !TARGET_OS_IPHONE
     load_smb_configuration((S_IPMonitor_debug & kDebugFlag1) != 0);
 #endif /* !TARGET_OS_IPHONE */
@@ -5163,8 +6504,12 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose)
 
 
 #ifdef TEST_IPMONITOR
 
 
 #ifdef TEST_IPMONITOR
+
 #include "dns-configuration.c"
 #include "dns-configuration.c"
+
+#if    !TARGET_IPHONE_SIMULATOR
 #include "set-hostname.c"
 #include "set-hostname.c"
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 int
 main(int argc, char **argv)
 
 int
 main(int argc, char **argv)
@@ -5178,6 +6523,7 @@ main(int argc, char **argv)
 
     load_IPMonitor(CFBundleGetMainBundle(), FALSE);
     prime_IPMonitor();
 
     load_IPMonitor(CFBundleGetMainBundle(), FALSE);
     prime_IPMonitor();
+    S_IPMonitor_debug = kDebugFlag1;
     CFRunLoopRun();
     /* not reached */
     exit(0);
     CFRunLoopRun();
     /* not reached */
     exit(0);
@@ -5186,8 +6532,12 @@ main(int argc, char **argv)
 #endif /* TEST_IPMONITOR */
 
 #ifdef TEST_IPV4_ROUTELIST
 #endif /* TEST_IPMONITOR */
 
 #ifdef TEST_IPV4_ROUTELIST
+
 #include "dns-configuration.c"
 #include "dns-configuration.c"
+
+#if    !TARGET_IPHONE_SIMULATOR
 #include "set-hostname.c"
 #include "set-hostname.c"
+#endif /* !TARGET_IPHONE_SIMULATOR */
 
 struct ipv4_service_contents {
     const char *       addr;
 
 struct ipv4_service_contents {
     const char *       addr;
@@ -5293,6 +6643,10 @@ struct ipv4_service_contents en1_20_never = {
     "10.0.0.20", "255.255.255.0", NULL,                "10.0.0.1",     "en1",  20,  &kSCValNetServicePrimaryRankNever
 };
 
     "10.0.0.20", "255.255.255.0", NULL,                "10.0.0.1",     "en1",  20,  &kSCValNetServicePrimaryRankNever
 };
 
+struct ipv4_service_contents en0_linklocal = {
+    "169.254.22.44", "255.255.0.0", NULL,      NULL,           "en0",  0xfffff,  NULL
+};
+
 struct ipv4_service_contents * test1[] = {
     &en0_40,
     &en0_15,
 struct ipv4_service_contents * test1[] = {
     &en0_40,
     &en0_15,
@@ -5407,6 +6761,11 @@ struct ipv4_service_contents * test14[] = {
     NULL
 };
 
     NULL
 };
 
+struct ipv4_service_contents * test15[] = {
+    &en0_linklocal,
+    NULL
+};
+
 static void
 dict_add_string(CFMutableDictionaryRef dict, CFStringRef prop_name,
                const char * str)
 static void
 dict_add_string(CFMutableDictionaryRef dict, CFStringRef prop_name,
                const char * str)
@@ -5548,7 +6907,7 @@ run_test(const char * name, struct ipv4_service_contents * * this_test)
        }
        if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
            descr = IPv4RouteListCopyDescription(r);
        }
        if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
            descr = IPv4RouteListCopyDescription(r);
-           SCLog(TRUE, LOG_NOTICE, CFSTR("test: Adding %@"), descr);
+           SCPrint(TRUE, stdout, CFSTR("test: Adding %@\n"), descr);
            CFRelease(descr);
        }
 
            CFRelease(descr);
        }
 
@@ -5568,7 +6927,7 @@ run_test(const char * name, struct ipv4_service_contents * * this_test)
     if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
        if (routes1 != NULL) {
            descr = IPv4RouteListCopyDescription(routes1);
     if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
        if (routes1 != NULL) {
            descr = IPv4RouteListCopyDescription(routes1);
-           SCLog(TRUE, LOG_NOTICE, CFSTR("Routes are %@"), descr);
+           SCPrint(TRUE, stdout, CFSTR("Routes are %@\n"), descr);
            CFRelease(descr);
        }
     }
            CFRelease(descr);
        }
     }
@@ -5591,7 +6950,7 @@ run_test(const char * name, struct ipv4_service_contents * * this_test)
        }
        if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
            descr = IPv4RouteListCopyDescription(r);
        }
        if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
            descr = IPv4RouteListCopyDescription(r);
-           SCLog(TRUE, LOG_NOTICE, CFSTR("test: Adding %@"), descr);
+           SCPrint(TRUE, stdout, CFSTR("test: Adding %@\n"), descr);
            CFRelease(descr);
        }
        if ((*scan_test)->primaryRank != NULL) {
            CFRelease(descr);
        }
        if ((*scan_test)->primaryRank != NULL) {
@@ -5608,7 +6967,7 @@ run_test(const char * name, struct ipv4_service_contents * * this_test)
     if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
        if (routes2 != NULL) {
            descr = IPv4RouteListCopyDescription(routes2);
     if ((S_IPMonitor_debug & kDebugFlag4) != 0) {
        if (routes2 != NULL) {
            descr = IPv4RouteListCopyDescription(routes2);
-           SCLog(TRUE, LOG_NOTICE, CFSTR("Routes are %@"), descr);
+           SCPrint(TRUE, stdout, CFSTR("Routes are %@\n"), descr);
            CFRelease(descr);
        }
     }
            CFRelease(descr);
        }
     }
@@ -5736,6 +7095,11 @@ main(int argc, char **argv)
        fprintf(stderr, "test5 failed\n");
        exit(1);
     }
        fprintf(stderr, "test5 failed\n");
        exit(1);
     }
+    if (run_test("test15", test15) == FALSE) {
+       fprintf(stderr, "test15 failed\n");
+       exit(1);
+    }
+
 
     printf("\nCompare 1 to 2:\n");
     compare_tests(test1, test2);
 
     printf("\nCompare 1 to 2:\n");
     compare_tests(test1, test2);
diff --git a/Plugins/IPMonitor/ip_plugin.h b/Plugins/IPMonitor/ip_plugin.h
new file mode 100644 (file)
index 0000000..ab52f1f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, 2013 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@
+ */
+
+/*
+ * ip_plugin.h
+ * - header for IPMonitor.bundle
+ */
+
+#ifndef        _IP_PLUGIN_H
+#define        _IP_PLUGIN_H
+
+#include <SystemConfiguration/SCPrivate.h>
+
+#define kIsNULL                                CFSTR("IsNULL") /* CFBoolean */
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+#define my_log(__level, fmt, ...)      SCLoggerLog(my_log_get_logger(), __level, CFSTR(fmt), ## __VA_ARGS__)
+SCLoggerRef my_log_get_logger();
+
+/*
+ * IPv4 Service Dict keys: IPv4DictRoutes, IPv4DictService
+ *
+ * The IPv4 service dictionary contains two sub-dictionaries:
+ *     Routes          IPv4RouteList
+ *      Service                dictionary containing kSCEntNetIPv4 keys
+ */
+#define kIPv4DictRoutes                CFSTR("Routes")
+#define        kIPv4DictService                CFSTR("Service")
+
+boolean_t
+cfstring_to_ip(CFStringRef str, struct in_addr * ip_p);
+
+boolean_t
+cfstring_to_ip6(CFStringRef str, struct in6_addr * ip6_p);
+
+#else  // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+#define my_log(__level, fmt, ...)      SCLog(TRUE, __level, CFSTR(fmt), ## __VA_ARGS__)
+
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+#endif // _IP_PLUGIN_H
index 76d60fac9f07fc09d1321439df1cfb98c64a5953..f8ac69c31aef2b73c8fee4a58c06572799d062d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -323,8 +323,8 @@ copy_supplemental_proxies(CFArrayRef proxies, Boolean skip)
 }
 
 
 }
 
 
-static CFDictionaryRef
-copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
+static CFArrayRef
+service_order_copy_all(CFDictionaryRef services, CFArrayRef service_order)
 {
        const void *            keys_q[N_QUICK];
        const void **           keys    = keys_q;
 {
        const void *            keys_q[N_QUICK];
        const void **           keys    = keys_q;
@@ -332,11 +332,12 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
        CFIndex                 n_order;
        CFIndex                 n_services;
        CFMutableArrayRef       order;
        CFIndex                 n_order;
        CFIndex                 n_services;
        CFMutableArrayRef       order;
-       CFMutableDictionaryRef  scoped  = NULL;
 
 
+       // ensure that we process all services in order
        n_services = isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0;
        if (n_services == 0) {
        n_services = isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0;
        if (n_services == 0) {
-               return NULL;            // if no services
+               // if no services
+               return NULL;
        }
 
        // ensure that we process all services in order
        }
 
        // ensure that we process all services in order
@@ -344,7 +345,7 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
        n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;
        if (n_order > 0) {
                order = CFArrayCreateMutableCopy(NULL, 0, service_order);
        n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;
        if (n_order > 0) {
                order = CFArrayCreateMutableCopy(NULL, 0, service_order);
-       } else{
+       } else {
                order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
 
                order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
 
@@ -353,7 +354,7 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
        }
        CFDictionaryGetKeysAndValues(services, keys, NULL);
        for (i = 0; i < n_services; i++) {
        }
        CFDictionaryGetKeysAndValues(services, keys, NULL);
        for (i = 0; i < n_services; i++) {
-               CFStringRef     serviceID = (CFStringRef)keys[i];
+               CFStringRef     serviceID       = (CFStringRef)keys[i];
 
                if (!CFArrayContainsValue(order, CFRangeMake(0, n_order), serviceID)) {
                        CFArrayAppendValue(order, serviceID);
 
                if (!CFArrayContainsValue(order, CFRangeMake(0, n_order), serviceID)) {
                        CFArrayAppendValue(order, serviceID);
@@ -364,13 +365,96 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
                CFAllocatorDeallocate(NULL, keys);
        }
 
                CFAllocatorDeallocate(NULL, keys);
        }
 
+       return order;
+}
+
+
+static CFDictionaryRef
+copy_app_layer_vpn_proxies(CFDictionaryRef services, CFArrayRef order, CFDictionaryRef services_info)
+{
+       CFMutableDictionaryRef  app_layer_proxies       = NULL;
+       CFIndex                 i;
+       CFIndex                 n_order;
+
+       if (!isA_CFDictionary(services_info)) {
+               return NULL;
+       }
+
        // iterate over services
 
        // iterate over services
 
+       n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0;
        for (i = 0; i < n_order; i++) {
        for (i = 0; i < n_order; i++) {
+               CFMutableDictionaryRef  newProxy;
                CFDictionaryRef         proxy;
                CFDictionaryRef         proxy;
+               CFDictionaryRef         service;
+               CFStringRef             serviceID;
+               CFDictionaryRef         vpn;
+               CFStringRef             vpn_key;
+
+               serviceID = CFArrayGetValueAtIndex(order, i);
+               service = CFDictionaryGetValue(services, serviceID);
+               if (!isA_CFDictionary(service)) {
+                       // if no service
+                       continue;
+               }
+
+               proxy = CFDictionaryGetValue(service, kSCEntNetProxies);
+               if (!isA_CFDictionary(proxy)) {
+                       // if no proxy
+                       continue;
+               }
+
+               vpn_key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     serviceID,
+                                                                     kSCEntNetVPN);
+               vpn = CFDictionaryGetValue(services_info, vpn_key);
+               CFRelease(vpn_key);
+
+               if (!isA_CFDictionary(vpn) || !CFDictionaryContainsKey(vpn, kSCPropNetVPNAppRules)) {
+                       // if not app-layer vpn
+                       continue;
+               }
+
+               if ((app_layer_proxies != NULL) &&
+                   CFDictionaryContainsKey(app_layer_proxies, serviceID)) {
+                       // if we've already processed this [app_layer_proxies] interface
+                       continue;
+               }
+
+               // add [app_layer_proxies] proxy entry
+               newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
+               CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchDomains);
+               CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchOrders);
+               if (app_layer_proxies == NULL) {
+                       app_layer_proxies = CFDictionaryCreateMutable(NULL,
+                                                                     0,
+                                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                                     &kCFTypeDictionaryValueCallBacks);
+               }
+               CFDictionarySetValue(app_layer_proxies, serviceID, newProxy);
+               CFRelease(newProxy);
+       }
+
+       return app_layer_proxies;
+}
+
+
+static CFDictionaryRef
+copy_scoped_proxies(CFDictionaryRef services, CFArrayRef order)
+{
+       CFIndex                 i;
+       CFIndex                 n_order;
+       CFMutableDictionaryRef  scoped  = NULL;
+
+       // iterate over services
+
+       n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0;
+       for (i = 0; i < n_order; i++) {
                char                    if_name[IF_NAMESIZE];
                CFStringRef             interface;
                CFMutableDictionaryRef  newProxy;
                char                    if_name[IF_NAMESIZE];
                CFStringRef             interface;
                CFMutableDictionaryRef  newProxy;
+               CFDictionaryRef         proxy;
                CFDictionaryRef         service;
                CFStringRef             serviceID;
 
                CFDictionaryRef         service;
                CFStringRef             serviceID;
 
@@ -425,7 +509,6 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order)
                CFRelease(interface);
        }
 
                CFRelease(interface);
        }
 
-       CFRelease(order);
        return scoped;
 }
 
        return scoped;
 }
 
@@ -548,7 +631,8 @@ __private_extern__
 CF_RETURNS_RETAINED CFDictionaryRef
 proxy_configuration_update(CFDictionaryRef     defaultProxy,
                           CFDictionaryRef      services,
 CF_RETURNS_RETAINED CFDictionaryRef
 proxy_configuration_update(CFDictionaryRef     defaultProxy,
                           CFDictionaryRef      services,
-                          CFArrayRef           serviceOrder)
+                          CFArrayRef           serviceOrder,
+                          CFDictionaryRef      servicesInfo)
 {
        CFIndex                 i;
        CFMutableDictionaryRef  myDefault;
 {
        CFIndex                 i;
        CFMutableDictionaryRef  myDefault;
@@ -618,8 +702,10 @@ proxy_configuration_update(CFDictionaryRef defaultProxy,
        // establish proxy configuration
 
        if (n_proxies > 0) {
        // establish proxy configuration
 
        if (n_proxies > 0) {
+               CFDictionaryRef         app_layer;
                CFDictionaryRef         scoped;
                CFDictionaryRef         scoped;
-               Boolean                 skip    = FALSE;
+               CFArrayRef              serviceOrderAll;
+               Boolean                 skip            = FALSE;
                CFArrayRef              supplemental;
 
                proxy = CFArrayGetValueAtIndex(proxies, 0);
                CFArrayRef              supplemental;
 
                proxy = CFArrayGetValueAtIndex(proxies, 0);
@@ -636,6 +722,8 @@ proxy_configuration_update(CFDictionaryRef  defaultProxy,
                                                             &kCFTypeDictionaryValueCallBacks);
                }
 
                                                             &kCFTypeDictionaryValueCallBacks);
                }
 
+               serviceOrderAll = service_order_copy_all(services, serviceOrder);
+
                // collect (and add) any "supplemental" proxy configurations
 
                supplemental = copy_supplemental_proxies(proxies, skip);
                // collect (and add) any "supplemental" proxy configurations
 
                supplemental = copy_supplemental_proxies(proxies, skip);
@@ -646,11 +734,23 @@ proxy_configuration_update(CFDictionaryRef        defaultProxy,
 
                // collect (and add) any "scoped" proxy configurations
 
 
                // collect (and add) any "scoped" proxy configurations
 
-               scoped = copy_scoped_proxies(services, serviceOrder);
+               scoped = copy_scoped_proxies(services, serviceOrderAll);
                if (scoped != NULL) {
                        CFDictionarySetValue(newProxy, kSCPropNetProxiesScoped, scoped);
                        CFRelease(scoped);
                }
                if (scoped != NULL) {
                        CFDictionarySetValue(newProxy, kSCPropNetProxiesScoped, scoped);
                        CFRelease(scoped);
                }
+
+               // collect (and add) any "services" based proxy configurations
+
+               app_layer = copy_app_layer_vpn_proxies(services, serviceOrderAll, servicesInfo);
+               if (app_layer != NULL) {
+                       CFDictionarySetValue(newProxy, kSCPropNetProxiesServices, app_layer);
+                       CFRelease(app_layer);
+               }
+
+               if (serviceOrderAll != NULL) {
+                       CFRelease(serviceOrderAll);
+               }
        } else {
                newProxy = NULL;
        }
        } else {
                newProxy = NULL;
        }
@@ -866,7 +966,8 @@ main(int argc, char **argv)
        proxy_configuration_init(CFBundleGetMainBundle());
        newProxy = proxy_configuration_update(primary_proxy,
                                              service_state_dict,
        proxy_configuration_init(CFBundleGetMainBundle());
        newProxy = proxy_configuration_update(primary_proxy,
                                              service_state_dict,
-                                             service_order);
+                                             service_order,
+                                             NULL);
        if (newProxy != NULL) {
                SCPrint(TRUE, stdout, CFSTR("%@\n"), newProxy);
                CFRelease(newProxy);
        if (newProxy != NULL) {
                SCPrint(TRUE, stdout, CFSTR("%@\n"), newProxy);
                CFRelease(newProxy);
index fbb233c0c8d27065e1e467baae518d31e01cace4..e86bd535df4be7de1681d9526658ffee4f3e9bf7 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -34,16 +34,15 @@ CFBooleanRef        G_supplemental_proxies_follow_dns;
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void
 proxy_configuration_init       (CFBundleRef            bundle);
 
 
 void
 proxy_configuration_init       (CFBundleRef            bundle);
 
 
-__private_extern__
 CF_RETURNS_RETAINED CFDictionaryRef
 proxy_configuration_update     (CFDictionaryRef        defaultProxy,
                                 CFDictionaryRef        services,
 CF_RETURNS_RETAINED CFDictionaryRef
 proxy_configuration_update     (CFDictionaryRef        defaultProxy,
                                 CFDictionaryRef        services,
-                                CFArrayRef             serviceOrder);
+                                CFArrayRef             serviceOrder,
+                                CFDictionaryRef        servicesInfo);
 
 __END_DECLS
 
 
 __END_DECLS
 
index 6ebcafd1c6ec1ece56f79fdaa2fc232197e0010f..b9ff91321d0808a5e83da185d46ef49ca401ab66 100644 (file)
@@ -40,6 +40,7 @@
 #include <SystemConfiguration/SCPrivate.h>
 
 #include <notify.h>
 #include <SystemConfiguration/SCPrivate.h>
 
 #include <notify.h>
+#include "ip_plugin.h"
 
 static SCDynamicStoreRef       store           = NULL;
 static CFRunLoopSourceRef      rls             = NULL;
 
 static SCDynamicStoreRef       store           = NULL;
 static CFRunLoopSourceRef      rls             = NULL;
@@ -63,7 +64,7 @@ set_hostname(CFStringRef hostname)
                char    new_name[MAXHOSTNAMELEN];
 
                if (gethostname(old_name, sizeof(old_name)) == -1) {
                char    new_name[MAXHOSTNAMELEN];
 
                if (gethostname(old_name, sizeof(old_name)) == -1) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("gethostname() failed: %s"), strerror(errno));
+                       my_log(LOG_ERR, "gethostname() failed: %s", strerror(errno));
                        old_name[0] = '\0';
                }
 
                        old_name[0] = '\0';
                }
 
@@ -71,7 +72,7 @@ set_hostname(CFStringRef hostname)
                                            new_name,
                                            sizeof(new_name),
                                            kCFStringEncodingUTF8) == NULL) {
                                            new_name,
                                            sizeof(new_name),
                                            kCFStringEncodingUTF8) == NULL) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("could not convert [new] hostname"));
+                       my_log(LOG_ERR, "could not convert [new] hostname");
                        new_name[0] = '\0';
                }
 
                        new_name[0] = '\0';
                }
 
@@ -81,22 +82,22 @@ set_hostname(CFStringRef hostname)
                        if (sethostname(new_name, strlen(new_name)) == 0) {
                                uint32_t        status;
 
                        if (sethostname(new_name, strlen(new_name)) == 0) {
                                uint32_t        status;
 
-                               SCLog(TRUE, LOG_NOTICE,
-                                     CFSTR("setting hostname to \"%s\""),
-                                     new_name);
+                               my_log(LOG_NOTICE,
+                                      "setting hostname to \"%s\"",
+                                      new_name);
 
                                status = notify_post(HOSTNAME_NOTIFY_KEY);
                                if (status != NOTIFY_STATUS_OK) {
 
                                status = notify_post(HOSTNAME_NOTIFY_KEY);
                                if (status != NOTIFY_STATUS_OK) {
-                                       SCLog(TRUE, LOG_ERR,
-                                             CFSTR("notify_post(" HOSTNAME_NOTIFY_KEY ") failed: error=%lu"),
-                                             status);
+                                       my_log(LOG_ERR,
+                                              "notify_post(" HOSTNAME_NOTIFY_KEY ") failed: error=%lu",
+                                              status);
                                }
                        } else {
                                }
                        } else {
-                               SCLog(TRUE, LOG_ERR,
-                                     CFSTR("sethostname(%s, %d) failed: %s"),
-                                     new_name,
-                                     strlen(new_name),
-                                     strerror(errno));
+                               my_log(LOG_ERR,
+                                      "sethostname(%s, %d) failed: %s",
+                                      new_name,
+                                      strlen(new_name),
+                                      strerror(errno));
                        }
                }
        }
                        }
                }
        }
@@ -319,11 +320,12 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
 
        (void) gettimeofday(&dnsQueryComplete, NULL);
        timersub(&dnsQueryComplete, &dnsQueryStart, &dnsQueryElapsed);
 
        (void) gettimeofday(&dnsQueryComplete, NULL);
        timersub(&dnsQueryComplete, &dnsQueryStart, &dnsQueryElapsed);
-       SCLog(_verbose, LOG_INFO,
-             CFSTR("async DNS complete%s (query time = %d.%3.3d)"),
-             ((status == 0) && (host != NULL)) ? "" : ", host not found",
-             dnsQueryElapsed.tv_sec,
-             dnsQueryElapsed.tv_usec / 1000);
+       if (_verbose) {
+               my_log(LOG_INFO, "async DNS complete%s (query time = %d.%3.3d)",
+                      ((status == 0) && (host != NULL)) ? "" : ", host not found",
+                      dnsQueryElapsed.tv_sec,
+                      dnsQueryElapsed.tv_usec / 1000);
+       }
 
        // use reverse DNS name, if available
 
 
        // use reverse DNS name, if available
 
@@ -335,7 +337,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
                        if (host != NULL) {
                                hostname = CFStringCreateWithCString(NULL, host, kCFStringEncodingUTF8);
                                if (hostname != NULL) {
                        if (host != NULL) {
                                hostname = CFStringCreateWithCString(NULL, host, kCFStringEncodingUTF8);
                                if (hostname != NULL) {
-                                       SCLog(TRUE, LOG_INFO, CFSTR("hostname (reverse DNS query) = %@"), hostname);
+                                       my_log(LOG_INFO, "hostname (reverse DNS query) = %@", hostname);
                                        set_hostname(hostname);
                                        CFRelease(hostname);
                                        goto done;
                                        set_hostname(hostname);
                                        CFRelease(hostname);
                                        goto done;
@@ -356,7 +358,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
                        /*
                         * Hmmmm...
                         */
                        /*
                         * Hmmmm...
                         */
-                       SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo() failed: %s"), gai_strerror(status));
+                       my_log(LOG_ERR, "getnameinfo() failed: %s", gai_strerror(status));
        }
 
        // get local (multicast DNS) name, if available
        }
 
        // get local (multicast DNS) name, if available
@@ -365,8 +367,9 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
        if (hostname != NULL) {
                CFMutableStringRef      localName;
 
        if (hostname != NULL) {
                CFMutableStringRef      localName;
 
-               SCLog(TRUE, LOG_INFO, CFSTR("hostname (multicast DNS) = %@"), hostname);
+               my_log(LOG_INFO, "hostname (multicast DNS) = %@", hostname);
                localName = CFStringCreateMutableCopy(NULL, 0, hostname);
                localName = CFStringCreateMutableCopy(NULL, 0, hostname);
+               assert(localName != NULL);
                CFStringAppend(localName, CFSTR(".local"));
                set_hostname(localName);
                CFRelease(localName);
                CFStringAppend(localName, CFSTR(".local"));
                set_hostname(localName);
                CFRelease(localName);
@@ -409,7 +412,7 @@ getnameinfo_async_handleCFReply(CFMachPortRef port, void *msg, CFIndex size, voi
                // we've received a callback on the async DNS port but since the
                // associated CFMachPort doesn't match than the request must have
                // already been cancelled.
                // we've received a callback on the async DNS port but since the
                // associated CFMachPort doesn't match than the request must have
                // already been cancelled.
-               SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo_async_handleCFReply(): port != dnsPort"));
+               my_log(LOG_ERR, "getnameinfo_async_handleCFReply(): port != dnsPort");
                return;
        }
 
                return;
        }
 
@@ -459,13 +462,13 @@ start_dns_query(SCDynamicStoreRef store, CFStringRef address)
        Boolean                         ok;
 
        if (_SC_cfstring_to_cstring(address, buf, sizeof(buf), kCFStringEncodingASCII) == NULL) {
        Boolean                         ok;
 
        if (_SC_cfstring_to_cstring(address, buf, sizeof(buf), kCFStringEncodingASCII) == NULL) {
-               SCLog(TRUE, LOG_ERR, CFSTR("could not convert [primary] address"));
+               my_log(LOG_ERR, "could not convert [primary] address");
                return;
        }
 
        if (_SC_string_to_sockaddr(buf, AF_UNSPEC, (void *)&addr, sizeof(addr)) == NULL) {
                /* if not an IP[v6] address */
                return;
        }
 
        if (_SC_string_to_sockaddr(buf, AF_UNSPEC, (void *)&addr, sizeof(addr)) == NULL) {
                /* if not an IP[v6] address */
-               SCLog(TRUE, LOG_ERR, CFSTR("could not parse [primary] address"));
+               my_log(LOG_ERR, "could not parse [primary] address");
                return;
        }
 
                return;
        }
 
@@ -543,7 +546,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 
        hostname = copy_static_name();
        if (hostname != NULL) {
 
        hostname = copy_static_name();
        if (hostname != NULL) {
-               SCLog(TRUE, LOG_INFO, CFSTR("hostname (static) = %@"), hostname);
+               my_log(LOG_INFO, "hostname (static) = %@", hostname);
                set_hostname(hostname);
                goto done;
        }
                set_hostname(hostname);
                goto done;
        }
@@ -552,7 +555,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 
        hostname = copy_prefs_hostname(store);
        if (hostname != NULL) {
 
        hostname = copy_prefs_hostname(store);
        if (hostname != NULL) {
-               SCLog(TRUE, LOG_INFO, CFSTR("hostname (prefs) = %@"), hostname);
+               my_log(LOG_INFO, "hostname (prefs) = %@", hostname);
                set_hostname(hostname);
                goto done;
        }
                set_hostname(hostname);
                goto done;
        }
@@ -568,7 +571,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 
        hostname = copy_dhcp_hostname(serviceID);
        if (hostname != NULL) {
 
        hostname = copy_dhcp_hostname(serviceID);
        if (hostname != NULL) {
-               SCLog(TRUE, LOG_INFO, CFSTR("hostname (DHCP) = %@"), hostname);
+               my_log(LOG_INFO, "hostname (DHCP) = %@", hostname);
                set_hostname(hostname);
                goto done;
        }
                set_hostname(hostname);
                goto done;
        }
@@ -590,8 +593,9 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
        if (hostname != NULL) {
                CFMutableStringRef      localName;
 
        if (hostname != NULL) {
                CFMutableStringRef      localName;
 
-               SCLog(TRUE, LOG_INFO, CFSTR("hostname (multicast DNS) = %@"), hostname);
+               my_log(LOG_INFO, "hostname (multicast DNS) = %@", hostname);
                localName = CFStringCreateMutableCopy(NULL, 0, hostname);
                localName = CFStringCreateMutableCopy(NULL, 0, hostname);
+               assert(localName != NULL);
                CFStringAppend(localName, CFSTR(".local"));
                set_hostname(localName);
                CFRelease(localName);
                CFStringAppend(localName, CFSTR(".local"));
                set_hostname(localName);
                CFRelease(localName);
@@ -628,9 +632,9 @@ load_hostname(Boolean verbose)
 
        store = SCDynamicStoreCreate(NULL, CFSTR("set-hostname"), update_hostname, NULL);
        if (store == NULL) {
 
        store = SCDynamicStoreCreate(NULL, CFSTR("set-hostname"), update_hostname, NULL);
        if (store == NULL) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreCreate() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreCreate() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
 
                goto error;
        }
 
@@ -673,17 +677,17 @@ load_hostname(Boolean verbose)
 
        /* register the keys/patterns */
        if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
 
        /* register the keys/patterns */
        if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreSetNotificationKeys() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
 
        rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
        if (!rls) {
                goto error;
        }
 
        rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
        if (!rls) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreCreateRunLoopSource() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
                goto error;
        }
        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
index 3315cce2ef281477bda21455cf773a568c384f82..c8a686e92bae34fae412ff4dfd91d1ee28549cde 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -29,7 +29,6 @@
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   load_hostname           (Boolean        verbose);
 
 __END_DECLS
 void   load_hostname           (Boolean        verbose);
 
 __END_DECLS
index 8c06cd69d528668989842983319dc047350155f8..01027ee679e849dc4856fbb73a0a4b76b5572cab 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -51,6 +51,8 @@
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>             // for SCLog(), SCPrint()
 
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>             // for SCLog(), SCPrint()
 
+#include "ip_plugin.h"
+
 #define        HW_MODEL_LEN            64                      // Note: must be >= NETBIOS_NAME_LEN (below)
 
 #define        NETBIOS_NAME_LEN        16
 #define        HW_MODEL_LEN            64                      // Note: must be >= NETBIOS_NAME_LEN (below)
 
 #define        NETBIOS_NAME_LEN        16
@@ -98,7 +100,7 @@ boottime(void)
                size_t          tv_len  = sizeof(tv);
 
                if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &tv, &tv_len, NULL, 0) == -1) {
                size_t          tv_len  = sizeof(tv);
 
                if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &tv, &tv_len, NULL, 0) == -1) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("sysctl() CTL_KERN/KERN_BOOTTIME failed: %s"), strerror(errno));
+                       my_log(LOG_ERR, "sysctl() CTL_KERN/KERN_BOOTTIME failed: %s", strerror(errno));
                        return kCFAbsoluteTimeIntervalSince1970;
                }
 
                        return kCFAbsoluteTimeIntervalSince1970;
                }
 
@@ -125,7 +127,7 @@ copy_default_name(void)
        bzero(&hwModel, sizeof(hwModel));
        ret = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &hwModel, &n, NULL, 0);
        if (ret != 0) {
        bzero(&hwModel, sizeof(hwModel));
        ret = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &hwModel, &n, NULL, 0);
        if (ret != 0) {
-               SCLog(TRUE, LOG_ERR, CFSTR("sysctl() CTL_HW/HW_MODEL failed: %s"), strerror(errno));
+               my_log(LOG_ERR, "sysctl() CTL_HW/HW_MODEL failed: %s", strerror(errno));
                return NULL;
        }
 
                return NULL;
        }
 
@@ -278,17 +280,17 @@ smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict)
 
        prefs = SCPreferencesCreate(NULL, CFSTR("smb-configuration"), CFSTR(kSMBPreferencesAppID));
        if (prefs == NULL) {
 
        prefs = SCPreferencesCreate(NULL, CFSTR("smb-configuration"), CFSTR(kSMBPreferencesAppID));
        if (prefs == NULL) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("smb_set_configuration: SCPreferencesCreate() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "smb_set_configuration: SCPreferencesCreate() failed: %s",
+                      SCErrorString(SCError()));
                return;
        }
 
        ok = SCPreferencesLock(prefs, TRUE);
        if (!ok) {
                return;
        }
 
        ok = SCPreferencesLock(prefs, TRUE);
        if (!ok) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("smb_set_configuration: SCPreferencesLock() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "smb_set_configuration: SCPreferencesLock() failed: %s",
+                      SCErrorString(SCError()));
                goto done;
        }
 
                goto done;
        }
 
@@ -329,7 +331,8 @@ smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict)
                        __CFStringGetInstallationEncodingAndRegion((uint32_t *)&macEncoding, &macRegion);
                }
                _SC_dos_encoding_and_codepage(macEncoding, macRegion, &dosEncoding, &dosCodepage);
                        __CFStringGetInstallationEncodingAndRegion((uint32_t *)&macEncoding, &macRegion);
                }
                _SC_dos_encoding_and_codepage(macEncoding, macRegion, &dosEncoding, &dosCodepage);
-               str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), dosCodepage);
+               str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), (unsigned int)dosCodepage);
+               assert(str != NULL);
                update_pref(prefs, CFSTR(kSMBPrefDOSCodePage), str, &changed);
                CFRelease(str);
        }
                update_pref(prefs, CFSTR(kSMBPrefDOSCodePage), str, &changed);
                CFRelease(str);
        }
@@ -381,17 +384,19 @@ smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict)
        if (changed) {
                ok = SCPreferencesCommitChanges(prefs);
                if (!ok) {
        if (changed) {
                ok = SCPreferencesCommitChanges(prefs);
                if (!ok) {
-                       SCLog((SCError() != EROFS), LOG_ERR,
-                             CFSTR("smb_set_configuration: SCPreferencesCommitChanges() failed: %s"),
-                             SCErrorString(SCError()));
+                       if ((SCError() != EROFS)) {
+                               my_log(LOG_ERR,
+                                      "smb_set_configuration: SCPreferencesCommitChanges() failed: %s",
+                                      SCErrorString(SCError()));
+                       }
                        goto done;
                }
 
                ok = SCPreferencesApplyChanges(prefs);
                if (!ok) {
                        goto done;
                }
 
                ok = SCPreferencesApplyChanges(prefs);
                if (!ok) {
-                       SCLog(TRUE, LOG_ERR,
-                             CFSTR("smb_set_configuration: SCPreferencesApplyChanges() failed: %s"),
-                             SCErrorString(SCError()));
+                       my_log(LOG_ERR,
+                              "smb_set_configuration: SCPreferencesApplyChanges() failed: %s",
+                              SCErrorString(SCError()));
                        goto done;
                }
        }
                        goto done;
                }
        }
@@ -479,11 +484,13 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
 
        (void) gettimeofday(&dnsQueryComplete, NULL);
        timersub(&dnsQueryComplete, &dnsQueryStart, &dnsQueryElapsed);
 
        (void) gettimeofday(&dnsQueryComplete, NULL);
        timersub(&dnsQueryComplete, &dnsQueryStart, &dnsQueryElapsed);
-       SCLog(_verbose, LOG_INFO,
-             CFSTR("async DNS complete%s (query time = %d.%3.3d)"),
-             ((status == 0) && (host != NULL)) ? "" : ", host not found",
-             dnsQueryElapsed.tv_sec,
-             dnsQueryElapsed.tv_usec / 1000);
+       if (_verbose) {
+               my_log(LOG_INFO,
+                      "async DNS complete%s (query time = %d.%3.3d)",
+                      ((status == 0) && (host != NULL)) ? "" : ", host not found",
+                      dnsQueryElapsed.tv_sec,
+                      dnsQueryElapsed.tv_usec / 1000);
+       }
 
        // get network configuration
        dict = smb_copy_global_configuration(store);
 
        // get network configuration
        dict = smb_copy_global_configuration(store);
@@ -491,7 +498,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
        // use NetBIOS name from network configuration (if available)
        name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
        if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) {
        // use NetBIOS name from network configuration (if available)
        name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
        if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) {
-               SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (network configuration) = %@"), name);
+               my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name);
                goto set;
        }
 
                goto set;
        }
 
@@ -514,7 +521,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
                                        if (_SC_CFStringIsValidNetBIOSName(name)) {
                                                CFMutableDictionaryRef  newDict;
 
                                        if (_SC_CFStringIsValidNetBIOSName(name)) {
                                                CFMutableDictionaryRef  newDict;
 
-                                               SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (reverse DNS query) = %@"), name);
+                                               my_log(LOG_INFO, "NetBIOS name (reverse DNS query) = %@", name);
                                                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                                                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                                                CFRelease(dict);
                                                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                                                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                                                CFRelease(dict);
@@ -541,7 +548,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
                        /*
                         * Hmmmm...
                         */
                        /*
                         * Hmmmm...
                         */
-                       SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo() failed: %s"), gai_strerror(status));
+                       my_log(LOG_ERR,"getnameinfo() failed: %s", gai_strerror(status));
        }
 
        // try local (multicast DNS) name, if available
        }
 
        // try local (multicast DNS) name, if available
@@ -550,7 +557,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
                if (_SC_CFStringIsValidNetBIOSName(name)) {
                        CFMutableDictionaryRef  newDict;
 
                if (_SC_CFStringIsValidNetBIOSName(name)) {
                        CFMutableDictionaryRef  newDict;
 
-                       SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (multicast DNS) = %@"), name);
+                       my_log(LOG_INFO, "NetBIOS name (multicast DNS) = %@", name);
                        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                        CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                        CFRelease(dict);
                        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                        CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                        CFRelease(dict);
@@ -566,7 +573,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context)
        if (name != NULL) {
                CFMutableDictionaryRef  newDict;
 
        if (name != NULL) {
                CFMutableDictionaryRef  newDict;
 
-               SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (default) = %@"), name);
+               my_log(LOG_INFO, "NetBIOS name (default) = %@", name);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                CFRelease(dict);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                CFRelease(dict);
@@ -609,7 +616,7 @@ getnameinfo_async_handleCFReply(CFMachPortRef port, void *msg, CFIndex size, voi
                // we've received a callback on the async DNS port but since the
                // associated CFMachPort doesn't match than the request must have
                // already been cancelled.
                // we've received a callback on the async DNS port but since the
                // associated CFMachPort doesn't match than the request must have
                // already been cancelled.
-               SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo_async_handleCFReply(): port != dnsPort"));
+               my_log(LOG_ERR, "getnameinfo_async_handleCFReply(): port != dnsPort");
                return;
        }
 
                return;
        }
 
@@ -656,13 +663,13 @@ start_dns_query(SCDynamicStoreRef store, CFStringRef address)
        Boolean                         ok      = FALSE;
 
        if (_SC_cfstring_to_cstring(address, buf, sizeof(buf), kCFStringEncodingASCII) == NULL) {
        Boolean                         ok      = FALSE;
 
        if (_SC_cfstring_to_cstring(address, buf, sizeof(buf), kCFStringEncodingASCII) == NULL) {
-               SCLog(TRUE, LOG_ERR, CFSTR("could not convert [primary] address"));
+               my_log(LOG_ERR, "could not convert [primary] address");
                return FALSE;
        }
 
        if (_SC_string_to_sockaddr(buf, AF_UNSPEC, (void *)&addr, sizeof(addr)) == NULL) {
                /* if not an IP[v6] address */
                return FALSE;
        }
 
        if (_SC_string_to_sockaddr(buf, AF_UNSPEC, (void *)&addr, sizeof(addr)) == NULL) {
                /* if not an IP[v6] address */
-               SCLog(TRUE, LOG_ERR, CFSTR("could not parse [primary] address"));
+               my_log(LOG_ERR, "could not parse [primary] address");
                return FALSE;
        }
 
                return FALSE;
        }
 
@@ -730,7 +737,7 @@ smb_update_configuration(__unused CFRunLoopTimerRef _timer, void *info)
        // use NetBIOS name from network configuration (if available)
        name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
        if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) {
        // use NetBIOS name from network configuration (if available)
        name = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
        if ((name != NULL) && _SC_CFStringIsValidNetBIOSName(name)) {
-               SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (network configuration) = %@"), name);
+               my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name);
                goto set;
        }
 
                goto set;
        }
 
@@ -763,7 +770,7 @@ smb_update_configuration(__unused CFRunLoopTimerRef _timer, void *info)
                if (_SC_CFStringIsValidNetBIOSName(name)) {
                        CFMutableDictionaryRef  newDict;
 
                if (_SC_CFStringIsValidNetBIOSName(name)) {
                        CFMutableDictionaryRef  newDict;
 
-                       SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (multicast DNS) = %@"), name);
+                       my_log(LOG_INFO, "NetBIOS name (multicast DNS) = %@", name);
                        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                        CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                        CFRelease(dict);
                        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                        CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                        CFRelease(dict);
@@ -779,7 +786,7 @@ smb_update_configuration(__unused CFRunLoopTimerRef _timer, void *info)
        if (name != NULL) {
                CFMutableDictionaryRef  newDict;
 
        if (name != NULL) {
                CFMutableDictionaryRef  newDict;
 
-               SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (default) = %@"), name);
+               my_log(LOG_INFO, "NetBIOS name (default) = %@", name);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                CFRelease(dict);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropNetSMBNetBIOSName, name);
                CFRelease(dict);
@@ -867,9 +874,9 @@ load_smb_configuration(Boolean verbose)
 
        store = SCDynamicStoreCreate(NULL, CFSTR("smb-configuration"), configuration_changed, NULL);
        if (store == NULL) {
 
        store = SCDynamicStoreCreate(NULL, CFSTR("smb-configuration"), configuration_changed, NULL);
        if (store == NULL) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreCreate() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreCreate() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
 
                goto error;
        }
 
@@ -911,17 +918,17 @@ load_smb_configuration(Boolean verbose)
 
        /* register the keys/patterns */
        if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
 
        /* register the keys/patterns */
        if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreSetNotificationKeys() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
 
        rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
        if (!rls) {
                goto error;
        }
 
        rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
        if (!rls) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"),
-                     SCErrorString(SCError()));
+               my_log(LOG_ERR,
+                      "SCDynamicStoreCreateRunLoopSource() failed: %s",
+                      SCErrorString(SCError()));
                goto error;
        }
        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
                goto error;
        }
        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
index d1fdf3ae95af5c96aa020768a6ba11029e09914e..babfb1bd6e6540d4f6a5428b820006e46080c55e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -28,7 +28,6 @@
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   load_smb_configuration          (Boolean        verbose);
 
 __END_DECLS
 void   load_smb_configuration          (Boolean        verbose);
 
 __END_DECLS
index 924de28662b8476e173d8fb572b69026e44e0e32..90cb275ccef652b6a348e7f7288e8298a6392628 100644 (file)
@@ -1,2 +1,9 @@
 #!/bin/sh
 #!/bin/sh
-sed '/Process [0-9][0-9]*: [0-9][0-9]* nodes malloced/d; s/^\(Process \)[0-9][0-9]*:\(.*\)/\1XXXX\2/'
+sed -e 's/^\(Process:.*\[\)[0-9][0-9]*/\1XXXX/'                        \
+    -e 's/^\(Load Address:.*0x\)[0-9a-f][0-9a-f]*/\1XXXX/'     \
+    -e 's/^\(Parent Process:.*\[\)[0-9][0-9]*/\1XXXX/'         \
+    -e 's/^\(Date\/Time: *\)[0-9].*/\1XXXX/'                   \
+    -e '/Process [0-9][0-9]*: [0-9][0-9]* nodes malloced/d'    \
+    -e 's/^\(Process \)[0-9][0-9]*:\(.*\)/\1XXXX\2/'           \
+    -e 's/^\(Path: \)\(.*$\)/\1XXXX/'                          \
+    -e 's/^\(OS Version: \)\(.*$\)/\1XXXX/'
index 410103d5248adb5b08261dac42cf070e8ba4d98a..aaadc627b33863d84c87723699ba9676f288e324 100644 (file)
@@ -4,37 +4,30 @@ test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.19
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.19 Ifp en0 Ifa 10.0.0.19
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.19
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.19 Ifp en0 Ifa 10.0.0.19
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
@@ -43,42 +36,34 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.19
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.19 Ifp en0 Ifa 10.0.0.19
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.19
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.19 Ifp en0 Ifa 10.0.0.19
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
@@ -87,7 +72,6 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 routes1 and routes2 are the same
 
 Starting test test2
 routes1 and routes2 are the same
 
 Starting test test2
@@ -95,32 +79,26 @@ test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
@@ -129,37 +107,30 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.13
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.13 Ifp en0 Ifa 10.0.0.13
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 192.168.2.1 Ifp fw0 Ifa 192.168.2.30
  1. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20 [SCOPED]
@@ -168,7 +139,6 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
  4. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20 [SCOPED]
  5. Dest 192.168.2.0 Mask 255.255.255.0 Gate 192.168.2.30 Ifp fw0 Ifa 192.168.2.30
 }
-
 routes1 and routes2 are the same
 
 Starting test test3
 routes1 and routes2 are the same
 
 Starting test test3
@@ -176,27 +146,22 @@ test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
@@ -205,32 +170,26 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
@@ -239,7 +198,6 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
-
 routes1 and routes2 are the same
 
 Starting test test4
 routes1 and routes2 are the same
 
 Starting test test4
@@ -247,27 +205,22 @@ test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
@@ -276,32 +229,26 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
 Routes are <IPv4RouteList[6]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local] [SCOPED]
@@ -310,39 +257,32 @@ Routes are <IPv4RouteList[6]> = {
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  4. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
-
 routes1 and routes2 are the same
 
 Starting test test5
 test: Adding <IPv4RouteList[1]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
 }
 routes1 and routes2 are the same
 
 Starting test test5
 test: Adding <IPv4RouteList[1]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 Routes are <IPv4RouteList[7]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local] [SCOPED]
 Routes are <IPv4RouteList[7]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local] [SCOPED]
@@ -352,36 +292,29 @@ Routes are <IPv4RouteList[7]> = {
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  6. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  6. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en1 Ifa 17.202.42.24 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en1 Ifa 10.0.0.20
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.20 Ifp en1 Ifa 10.0.0.20
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.11
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.11 Ifp en0 Ifa 10.0.0.11
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.12
  1. Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.12 Ifp en0 Ifa 10.0.0.12
 }
-
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
 test: Adding <IPv4RouteList[2]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local]
  1. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
 }
-
 test: Adding <IPv4RouteList[1]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
 }
 test: Adding <IPv4RouteList[1]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
 }
-
 Routes are <IPv4RouteList[7]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local] [SCOPED]
 Routes are <IPv4RouteList[7]> = {
  0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.219.156.1 Ifp ppp0 Ifa 17.219.156.22
  1. Dest 0.0.0.0 Mask 0.0.0.0 Gate 17.202.20.1 Ifp en0 Ifa 17.202.40.191 [non-local] [SCOPED]
@@ -391,7 +324,21 @@ Routes are <IPv4RouteList[7]> = {
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  6. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
  5. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.40.191 Ifp en0 Ifa 17.202.40.191
  6. Dest 17.202.40.0 Mask 255.255.252.0 Gate 17.202.42.24 Ifp en1 Ifa 17.202.42.24 [SCOPED]
 }
+routes1 and routes2 are the same
 
 
+Starting test test15
+test: Adding <IPv4RouteList[1]> = {
+ 0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 169.254.22.44 Ifp en0 Ifa 169.254.22.44 [direct] [never] [SCOPED]
+}
+Routes are <IPv4RouteList[1]> = {
+ 0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 169.254.22.44 Ifp en0 Ifa 169.254.22.44 [direct] [SCOPED]
+}
+test: Adding <IPv4RouteList[1]> = {
+ 0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 169.254.22.44 Ifp en0 Ifa 169.254.22.44 [direct] [never] [SCOPED]
+}
+Routes are <IPv4RouteList[1]> = {
+ 0. Dest 0.0.0.0 Mask 0.0.0.0 Gate 169.254.22.44 Ifp en0 Ifa 169.254.22.44 [direct] [SCOPED]
+}
 routes1 and routes2 are the same
 
 Compare 1 to 2:
 routes1 and routes2 are the same
 
 Compare 1 to 2:
@@ -765,4 +712,17 @@ Remove old[0] = Dest 0.0.0.0 Mask 0.0.0.0 Gate 10.0.0.1 Ifp en0 Ifa 10.0.0.10
 Remove old[2] = Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 
 Checking for leaks
 Remove old[2] = Dest 10.0.0.0 Mask 255.255.255.0 Gate 10.0.0.10 Ifp en0 Ifa 10.0.0.10
 
 Checking for leaks
+Process:         test_ipv4_routelist [XXXX]
+Path: XXXX
+Load Address:    0xXXXX
+Identifier:      test_ipv4_routelist
+Version:         ??? (???)
+Code Type:       X86-64 (Native)
+Parent Process:  sh [XXXX]
+
+Date/Time:       XXXX
+OS Version: XXXX
+Report Version:  7
+
+leaks Report Version:  2.0
 Process XXXX 0 leaks for 0 total leaked bytes.
 Process XXXX 0 leaks for 0 total leaked bytes.
index c4df41f9279b4665f04ea4a4502964a3c525262b..b21ea5e1bfb2bfa4d5b82ccc11d9b19915ca2327 100644 (file)
@@ -11,7 +11,7 @@ cleanup()
     exit 1
 }
 
     exit 1
 }
 
-trap cleanup 1 2 3 15 
+trap cleanup 1 2 3 15
 
 run_program()
 {
 
 run_program()
 {
@@ -84,4 +84,4 @@ else
     usage "${0}"
 fi
 
     usage "${0}"
 fi
 
-exit 0
\ No newline at end of file
+exit 0
index bd0a96004c83f6cb0dce1ce82bdeb02b19bf54c1..7e483e35797167523369ffbf682efdd76a17dbb7 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
 </dict>
 </plist>
 </dict>
 </plist>
index 639f9aea694f6810020688567b5115e3aa9dec23..4ba2a566aa47165431e3135bd93e3ad733e0e30b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2001-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2001-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/param.h>
 #include <mach/mach.h>
 #include <net/ethernet.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/param.h>
 #include <mach/mach.h>
 #include <net/ethernet.h>
-#include <net/if.h>
 #include <net/if_types.h>
 #include <pthread.h>
 #include <vproc.h>
 #include <net/if_types.h>
 #include <pthread.h>
 #include <vproc.h>
@@ -590,6 +587,40 @@ updateVirtualNetworkInterfaceConfiguration(SCPreferencesRef                prefs,
     return;
 }
 
     return;
 }
 
+#if    !TARGET_OS_EMBEDDED
+
+#define        BT_PAN_NAME "Bluetooth PAN"
+
+static void
+updateBTPANInformation(const void *value, void *context)
+{   CFDictionaryRef dict    = (CFDictionaryRef)value;
+    CFStringRef            if_name;
+    CFDictionaryRef info;
+    CFStringRef            name;
+
+    if_name = CFDictionaryGetValue(dict, CFSTR(kIOBSDNameKey));
+    if (!isA_CFString(if_name)) {
+       // if no BSD name
+       return;
+    }
+
+    info = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceInfo));
+    if (!isA_CFDictionary(info)) {
+       // if no SCNetworkInterface info
+       return;
+    }
+
+    name = CFDictionaryGetValue(info, kSCPropUserDefinedName);
+    if (!isA_CFString(name) || !CFEqual(name, CFSTR(BT_PAN_NAME))) {
+       // if not BT-PAN interface
+       return;
+    }
+
+    CFDictionaryAddValue(S_state, CFSTR("_" BT_PAN_NAME "_"), if_name);
+    return;
+}
+#endif // !TARGET_OS_EMBEDDED
+
 static CFDictionaryRef
 createInterfaceDict(SCNetworkInterfaceRef interface)
 {
 static CFDictionaryRef
 createInterfaceDict(SCNetworkInterfaceRef interface)
 {
@@ -612,6 +643,11 @@ createInterfaceDict(SCNetworkInterfaceRef interface)
        CFDictionarySetValue(new_if, CFSTR(kIOPathMatchKey), val);
     }
 
        CFDictionarySetValue(new_if, CFSTR(kIOPathMatchKey), val);
     }
 
+    val = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
+    if (val != NULL) {
+       CFDictionarySetValue(new_if, CFSTR(kIOInterfaceNamePrefix), val);
+    }
+
     val = _SCNetworkInterfaceGetIOInterfaceType(interface);
     if (val != NULL) {
        CFDictionarySetValue(new_if, CFSTR(kIOInterfaceType), val);
     val = _SCNetworkInterfaceGetIOInterfaceType(interface);
     if (val != NULL) {
        CFDictionarySetValue(new_if, CFSTR(kIOInterfaceType), val);
@@ -767,8 +803,8 @@ matchInterfaceInfo(CFDictionaryRef known_info, CFDictionaryRef match_info)
        known_info = thinInterfaceInfo(known_info);
        match_info = thinInterfaceInfo(match_info);
        match = _SC_CFEqual(known_info, match_info);
        known_info = thinInterfaceInfo(known_info);
        match_info = thinInterfaceInfo(match_info);
        match = _SC_CFEqual(known_info, match_info);
-       CFRelease(known_info);
-       CFRelease(match_info);
+       if (known_info != NULL) CFRelease(known_info);
+       if (match_info != NULL) CFRelease(match_info);
     }
 
     return match;
     }
 
     return match;
@@ -873,6 +909,83 @@ matchUnnamed(const void *value, void *context)
     return;
 }
 
     return;
 }
 
+static Boolean
+interfaceExists(CFStringRef prefix, CFNumberRef unit)
+{
+    Boolean            found       = FALSE;
+    CFDictionaryRef    match_dict;
+    CFStringRef                match_keys[2];
+    CFTypeRef          match_vals[2];
+    CFDictionaryRef    matching;
+
+
+
+    io_registry_entry_t        entry           = MACH_PORT_NULL;
+    io_iterator_t              iterator        = MACH_PORT_NULL;
+    kern_return_t              kr;
+    mach_port_t                        masterPort      = MACH_PORT_NULL;
+
+    kr = IOMasterPort(bootstrap_port, &masterPort);
+    if (kr != KERN_SUCCESS) {
+       SCLog(TRUE, LOG_ERR,
+             CFSTR(MY_PLUGIN_NAME ": IOMasterPort returned 0x%x"),
+             kr);
+       goto error;
+    }
+
+    // look for kIONetworkInterface with matching prefix and unit
+    match_keys[0] = CFSTR(kIOInterfaceNamePrefix);
+    match_vals[0] = prefix;
+    match_keys[1] = CFSTR(kIOInterfaceUnit);
+    match_vals[1] = unit;
+    match_dict = CFDictionaryCreate(NULL,
+                                   (const void **)match_keys,
+                                   (const void **)match_vals,
+                                   2,
+                                   &kCFTypeDictionaryKeyCallBacks,
+                                   &kCFTypeDictionaryValueCallBacks);
+
+    match_keys[0] = CFSTR(kIOProviderClassKey);
+    match_vals[0] = CFSTR(kIONetworkInterfaceClass);
+    match_keys[1] = CFSTR(kIOPropertyMatchKey);
+    match_vals[1] = match_dict;
+    matching = CFDictionaryCreate(NULL,
+                                 (const void **)match_keys,
+                                 (const void **)match_vals,
+                                 sizeof(match_keys)/sizeof(match_keys[0]),
+                                 &kCFTypeDictionaryKeyCallBacks,
+                                 &kCFTypeDictionaryValueCallBacks);
+    CFRelease(match_dict);
+
+    // note: the "matching" dictionary will be consumed by the following
+    kr = IOServiceGetMatchingServices(masterPort, matching, &iterator);
+    if ((kr != kIOReturnSuccess) || (iterator == MACH_PORT_NULL)) {
+       // if no interface
+       goto error;
+    }
+
+    entry = IOIteratorNext(iterator);
+    if (entry == MACH_PORT_NULL) {
+       // if no interface
+       goto error;
+    }
+
+    found = TRUE;
+
+error:
+    if (masterPort != MACH_PORT_NULL) {
+       mach_port_deallocate(mach_task_self(), masterPort);
+    }
+    if (entry != MACH_PORT_NULL) {
+       IOObjectRelease(entry);
+    }
+    if (iterator != MACH_PORT_NULL) {
+       IOObjectRelease(iterator);
+    }
+
+    return (found);
+}
+
 /*
  * lookupMatchingInterface
  *
 /*
  * lookupMatchingInterface
  *
@@ -908,8 +1021,8 @@ lookupMatchingInterface(SCNetworkInterfaceRef      interface,
     match_context.match_builtin        = builtin;
     match_context.matches      = NULL;
 
     match_context.match_builtin        = builtin;
     match_context.matches      = NULL;
 
-    // check for matches to already named interfaces
-    // ... and appends each match that we find to match_context.matches
+    // check for matches to interfaces that have already been named
+    // ... and append each match that we find to match_context.matches
     if (db_list != NULL) {
        CFArrayApplyFunction(db_list,
                             CFRangeMake(0, CFArrayGetCount(db_list)),
     if (db_list != NULL) {
        CFArrayApplyFunction(db_list,
                             CFRangeMake(0, CFArrayGetCount(db_list)),
@@ -917,8 +1030,8 @@ lookupMatchingInterface(SCNetworkInterfaceRef      interface,
                             &match_context);
     }
 
                             &match_context);
     }
 
-    // check for matches to to be named interfaces
-    // ... and CFReleases match_context.matches if we find another network
+    // check for matches to interfaces that will be named
+    // ... and CFRelease match_context.matches if we find another network
     //     interface of the same type that also needs to be named
     if (if_list != NULL) {
        CFIndex    if_list_count;
     //     interface of the same type that also needs to be named
     if (if_list != NULL) {
        CFIndex    if_list_count;
@@ -946,18 +1059,15 @@ lookupMatchingInterface(SCNetworkInterfaceRef    interface,
 
        name = CFDictionaryGetValue(match, CFSTR(kIOBSDNameKey));
        if (isA_CFString(name)) {
 
        name = CFDictionaryGetValue(match, CFSTR(kIOBSDNameKey));
        if (isA_CFString(name)) {
-           int         sock;
+           CFStringRef     prefix;
+           CFNumberRef     unit;
 
 
-           sock = socket(AF_INET, SOCK_DGRAM, 0);
-           if (sock != -1) {
-               struct ifreq    ifr;
-
-               (void)_SC_cfstring_to_cstring(name, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII);
-               if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
-                   // if interface name not currently in-use
+           prefix = CFDictionaryGetValue(match, CFSTR(kIOInterfaceNamePrefix));
+           unit   = CFDictionaryGetValue(match, CFSTR(kIOInterfaceUnit));
+           if (isA_CFString(prefix) && isA_CFNumber(unit)) {
+               if (!interfaceExists(prefix, unit)) {
                    active = FALSE;
                }
                    active = FALSE;
                }
-               close(sock);
            }
        }
 
            }
        }
 
@@ -1013,6 +1123,11 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface)
     }
 
     CFArrayAppendValue(S_dblist, if_dict);
     }
 
     CFArrayAppendValue(S_dblist, if_dict);
+
+#if    !TARGET_OS_EMBEDDED
+    updateBTPANInformation(if_dict, NULL);
+#endif // !TARGET_OS_EMBEDDED
+
     CFRelease(if_dict);
     return;
 }
     CFRelease(if_dict);
     return;
 }
@@ -1179,7 +1294,6 @@ copyInterfaceForIORegistryEntryID(uint64_t entryID)
        IOObjectRelease(iterator);
     }
     return (interface);
        IOObjectRelease(iterator);
     }
     return (interface);
-
 }
 
 static SCNetworkInterfaceRef
 }
 
 static SCNetworkInterfaceRef
@@ -1295,6 +1409,47 @@ displayInterface(SCNetworkInterfaceRef interface)
          addr);
 }
 
          addr);
 }
 
+static Boolean
+builtinAvailable(SCNetworkInterfaceRef interface,      // new interface
+                CFNumberRef            if_unit)        // desired unit
+{
+    CFIndex    i;
+    CFNumberRef if_type        = _SCNetworkInterfaceGetIOInterfaceType(interface);
+    CFIndex    n;
+
+    n = (S_dblist != NULL) ? CFArrayGetCount(S_dblist) : 0;
+    for (i = 0; i < n; i++) {
+       CFStringRef         if_path;
+       CFDictionaryRef     known_dict      = CFArrayGetValueAtIndex(S_dblist, i);
+       CFStringRef         known_path;
+       CFNumberRef         known_type;
+       CFNumberRef         known_unit;
+
+       known_type = CFDictionaryGetValue(known_dict, CFSTR(kIOInterfaceType));
+       if (!_SC_CFEqual(if_type, known_type)) {
+           continue;   // if not the same interface type
+       }
+
+       known_unit = CFDictionaryGetValue(known_dict, CFSTR(kIOInterfaceUnit));
+       if (!_SC_CFEqual(if_unit, known_unit)) {
+           continue;   // if not the same interface unit
+       }
+
+       if_path    = _SCNetworkInterfaceGetIOPath(interface);
+       known_path = CFDictionaryGetValue(known_dict, CFSTR(kIOPathMatchKey));
+       if (!_SC_CFEqual(if_path, known_path)) {
+           // if different IORegistry path
+           return FALSE;
+       }
+
+       // if same type, same unit, same path
+       return TRUE;
+    }
+
+    // if interface type/unit not found
+    return TRUE;
+}
+
 static int
 builtinCount(CFArrayRef if_list, CFIndex last, CFNumberRef if_type)
 {
 static int
 builtinCount(CFArrayRef if_list, CFIndex last, CFNumberRef if_type)
 {
@@ -1418,10 +1573,31 @@ nameInterfaces(CFMutableArrayRef if_list)
                int             next_unit       = 0;
 
                if (is_builtin) {
                int             next_unit       = 0;
 
                if (is_builtin) {
-                   // built-in interface, use the reserved slots
+                   // built-in interface, try to use the reserved slots
                    next_unit = builtinCount(if_list, i, type);
                    next_unit = builtinCount(if_list, i, type);
-               } else {
-                   // not built-in, skip over the reserved slots
+
+                   // But, before claiming a reserved slot we check to see if the
+                   // slot had previously been used.  If so, and if the slot had been
+                   // assigned to the same type of interface, then we will perform a
+                   // replacement (e.g. assume that this was a board swap).  But, if
+                   // the new interface is a different type then we assume that the
+                   // built-in configuration has changed and allocate a new unit from
+                   // the non-reserved slots.
+
+                   unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
+                   if (!builtinAvailable(interface, unit)) {
+                       // if [built-in] unit not available
+                       SCLog(S_debug, LOG_INFO,
+                             CFSTR(MY_PLUGIN_NAME ": Interface not assigned [built-in] unit %@"),
+                             unit);
+                       CFRelease(unit);
+                       unit = NULL;
+                   }
+               }
+
+               if (unit == NULL) {
+                   // not built-in (or built-in unit not available), allocate from
+                   // the non-reserved slots
                    next_unit = builtinCount(if_list, n, type);
 
                    unit = getHighestUnitForType(type);
                    next_unit = builtinCount(if_list, n, type);
 
                    unit = getHighestUnitForType(type);
@@ -1433,8 +1609,9 @@ nameInterfaces(CFMutableArrayRef if_list)
                            next_unit = high_unit + 1;
                        }
                    }
                            next_unit = high_unit + 1;
                        }
                    }
+
+                   unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
                }
                }
-               unit = CFNumberCreate(NULL, kCFNumberIntType, &next_unit);
 
                SCLog(S_debug, LOG_INFO,
                      CFSTR(MY_PLUGIN_NAME ": Interface assigned unit %@ (%s)"),
 
                SCLog(S_debug, LOG_INFO,
                      CFSTR(MY_PLUGIN_NAME ": Interface assigned unit %@ (%s)"),
@@ -1563,6 +1740,73 @@ nameInterfaces(CFMutableArrayRef if_list)
     return;
 }
 
     return;
 }
 
+#if    !TARGET_OS_IPHONE
+static void
+updateNetworkConfiguration(CFArrayRef if_list)
+{
+    Boolean            do_commit       = FALSE;
+    CFIndex            i;
+    CFIndex            n;
+    SCPreferencesRef   prefs           = NULL;
+    SCNetworkSetRef    set             = NULL;
+
+    prefs = SCPreferencesCreate(NULL, CFSTR("SCMonitor"), NULL);
+
+    set = SCNetworkSetCopyCurrent(prefs);
+    if (set == NULL) {
+       SCLog(TRUE, LOG_ERR, CFSTR(MY_PLUGIN_NAME ": No current set"));
+       goto done;
+    }
+
+    n = CFArrayGetCount(if_list);
+    for (i = 0; i < n; i++) {
+       SCNetworkInterfaceRef   interface;
+
+       interface = CFArrayGetValueAtIndex(if_list, i);
+       if (SCNetworkSetEstablishDefaultInterfaceConfiguration(set, interface)) {
+           SCLog(TRUE, LOG_INFO,
+                 CFSTR(MY_PLUGIN_NAME ": adding default configuration for %s"),
+                 SCNetworkInterfaceGetBSDName(interface));
+           do_commit = TRUE;
+       }
+    }
+
+    if (do_commit) {
+       Boolean ok;
+
+       ok = SCPreferencesCommitChanges(prefs);
+       if (!ok) {
+           SCLog(TRUE, LOG_INFO,
+                 CFSTR(MY_PLUGIN_NAME ": updateNetworkConfiguration: SCPreferencesCommitChanges() failed: %s"),
+                 SCErrorString(SCError()));
+           goto done;
+       }
+
+       ok = SCPreferencesApplyChanges(prefs);
+       if (!ok) {
+           SCLog(TRUE, LOG_INFO,
+                 CFSTR(MY_PLUGIN_NAME ": updateNetworkConfiguration: SCPreferencesApplyChanges() failed: %s"),
+                 SCErrorString(SCError()));
+           goto done;
+       }
+    }
+
+  done :
+
+    if (set != NULL) {
+       CFRelease(set);
+       set = NULL;
+    }
+
+    if (prefs != NULL) {
+       CFRelease(prefs);
+       prefs = NULL;
+    }
+
+    return;
+}
+#endif // !TARGET_OS_IPHONE
+
 static void
 updateInterfaces()
 {
 static void
 updateInterfaces()
 {
@@ -1592,6 +1836,19 @@ updateInterfaces()
         */
        writeInterfaceList(S_dblist);
        updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL);
         */
        writeInterfaceList(S_dblist);
        updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL);
+
+#if    !TARGET_OS_IPHONE
+       if (access("/usr/libexec/UserEventAgent",  X_OK) == -1
+           && errno == ENOENT) {
+           /*
+            * We are most likely booted into the Recovery OS with no "SCMonitor"
+            * UserEventAgent plugin running so let's make sure we update the
+            * network configuration for new interfaces.
+            */
+           updateNetworkConfiguration(S_iflist);
+       }
+#endif // !TARGET_OS_IPHONE
+
        updateStore();
 
        if (S_iflist != NULL) {
        updateStore();
 
        if (S_iflist != NULL) {
@@ -1961,6 +2218,7 @@ iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef
        } else {
            newNodes = CFArrayCreateMutableCopy(NULL, 0, nodes);
        }
        } else {
            newNodes = CFArrayCreateMutableCopy(NULL, 0, nodes);
        }
+       assert(newNodes != NULL);
 
        kr = IORegistryEntryGetName(obj, name);
        if (kr != kIOReturnSuccess) {
 
        kr = IORegistryEntryGetName(obj, name);
        if (kr != kIOReturnSuccess) {
@@ -2257,6 +2515,16 @@ setup_IOKit(CFBundleRef bundle)
     }
 #endif /* WAIT_PREVIOUS_BOOT_INTERFACES_OR_QUIET */
 
     }
 #endif /* WAIT_PREVIOUS_BOOT_INTERFACES_OR_QUIET */
 
+#if    !TARGET_OS_EMBEDDED
+    if (S_dblist != NULL) {
+       // apply special handling for the BT-PAN interface (if present)
+       CFArrayApplyFunction(S_dblist,
+                            CFRangeMake(0, CFArrayGetCount(S_dblist)),
+                            updateBTPANInformation,
+                            NULL);
+    }
+#endif // !TARGET_OS_EMBEDDED
+
     ok = TRUE;
 
  done:
     ok = TRUE;
 
  done:
index dd4142696bb100a74efef3774347841ae718d3fd..a138cb79ec5bac8d190f180483bc00fd2a568ab0 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
index 0830019a5a1e1c3516d43adaf662f589e387223b..364fd6db4fecd7d9af813835f7cc0d0c6344a862 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2006, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2006, 2009, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -189,6 +189,66 @@ done:
 #endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
 
 
 #endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
 
 
+#ifdef KEV_DL_ISSUES
+static CFStringRef
+create_link_issues_key(const char * if_name)
+{
+       CFStringRef     interface;
+       CFStringRef     key;
+
+       interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
+       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                           kSCDynamicStoreDomainState,
+                                                           interface,
+                                                           kSCEntNetLinkIssues);
+       CFRelease(interface);
+       return (key);
+}
+
+
+__private_extern__
+void
+interface_update_link_issues(const char                *if_name,
+                            uint64_t           timestamp,
+                            uint8_t            *modid,
+                            size_t             modid_size,
+                            uint8_t            *info,
+                            size_t             info_size)
+{
+       CFDataRef               infoData;
+       CFStringRef             key;
+       CFDataRef               modidData;
+       CFMutableDictionaryRef  newDict;
+       CFDateRef               timeStamp;
+
+       key = create_link_issues_key(if_name);
+
+       newDict = copy_entity(key);
+
+       modidData = CFDataCreate(NULL, modid, modid_size);
+       CFDictionarySetValue(newDict, kSCPropNetLinkIssuesModuleID, modidData);
+       CFRelease(modidData);
+
+       if (info_size != 0) {
+               infoData = CFDataCreate(NULL, info, info_size);
+               CFDictionarySetValue(newDict, kSCPropNetLinkIssuesInfo, infoData);
+               CFRelease(infoData);
+       } else {
+               CFDictionaryRemoveValue(newDict, kSCPropNetLinkIssuesInfo);
+       }
+
+       timeStamp = CFDateCreate(NULL, timestamp);
+       CFDictionarySetValue(newDict, kSCPropNetLinkIssuesTimeStamp, timeStamp);
+       CFRelease(timeStamp);
+
+       cache_SCDynamicStoreSetValue(store, key, newDict);
+       CFRelease(newDict);
+       CFRelease(key);
+       return;
+}
+#endif /* KEV_DL_ISSUES */
+
+
 __private_extern__
 void
 interface_detaching(const char *if_name)
 __private_extern__
 void
 interface_detaching(const char *if_name)
@@ -206,6 +266,7 @@ interface_detaching(const char *if_name)
        return;
 }
 
        return;
 }
 
+
 static void
 interface_remove(const char *if_name)
 {
 static void
 interface_remove(const char *if_name)
 {
@@ -215,11 +276,17 @@ interface_remove(const char *if_name)
        cache_SCDynamicStoreRemoveValue(store, key);
        CFRelease(key);
 
        cache_SCDynamicStoreRemoveValue(store, key);
        CFRelease(key);
 
-#ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED
+#ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED
        key = create_linkquality_key(if_name);
        cache_SCDynamicStoreRemoveValue(store, key);
        CFRelease(key);
        key = create_linkquality_key(if_name);
        cache_SCDynamicStoreRemoveValue(store, key);
        CFRelease(key);
-#endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
+#endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
+
+#ifdef KEV_DL_ISSUES
+       key = create_link_issues_key(if_name);
+       cache_SCDynamicStoreRemoveValue(store, key);
+       CFRelease(key);
+#endif /* KEV_DL_ISSUES */
 
        return;
 }
 
        return;
 }
@@ -269,7 +336,6 @@ link_update_status(const char *if_name, boolean_t attach)
        return;
 }
 
        return;
 }
 
-
 __private_extern__
 void
 link_add(const char *if_name)
 __private_extern__
 void
 link_add(const char *if_name)
index f78ce84634512c685d42912f83873b152ad6eb64..ae3b00128161e4f7a27f56c507b3797c9a060d1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002, 2004, 2005, 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002, 2004, 2005, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   interface_detaching             (const char *if_name);
 
 void   interface_detaching             (const char *if_name);
 
-__private_extern__
 void   interface_update_idle_state     (const char *if_name);
 
 void   interface_update_idle_state     (const char *if_name);
 
-__private_extern__
+void   interface_update_link_issues    (const char     *if_name,
+                                        uint64_t       timestamp,
+                                        uint8_t        *modid,
+                                        size_t         modid_size,
+                                        uint8_t        *info,
+                                        size_t         info_size);
+
 void   interface_update_quality_metric (const char *if_name, int quality);
 
 void   interface_update_quality_metric (const char *if_name, int quality);
 
-__private_extern__
 void   link_add                        (const char *if_name);
 
 void   link_add                        (const char *if_name);
 
-__private_extern__
 void   link_remove                     (const char *if_name);
 
 void   link_remove                     (const char *if_name);
 
-__private_extern__
 void   link_update_status              (const char *if_name, boolean_t attach);
 
 __END_DECLS
 void   link_update_status              (const char *if_name, boolean_t attach);
 
 __END_DECLS
index 0e75b21a4b567c0f54bd342b5f29e4834a6c56bb..241d41f4218b14085c8c62b4166f41cb185e1b87 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2005, 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2005, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   interface_update_ipv4   (struct ifaddrs *ifap, const char *if_name);
 
 void   interface_update_ipv4   (struct ifaddrs *ifap, const char *if_name);
 
-__private_extern__
 void   interface_collision_ipv4(const char *if_name,
                                 struct in_addr ip_addr,
                                 int hw_len, const void * hw_addr);
 
 #if    !TARGET_OS_IPHONE
 void   interface_collision_ipv4(const char *if_name,
                                 struct in_addr ip_addr,
                                 int hw_len, const void * hw_addr);
 
 #if    !TARGET_OS_IPHONE
-__private_extern__
 void   port_in_use_ipv4        (uint16_t port, pid_t req_pid);
 #endif /* !TARGET_OS_IPHONE */
 
 void   port_in_use_ipv4        (uint16_t port, pid_t req_pid);
 #endif /* !TARGET_OS_IPHONE */
 
index abe37ff59596d268511764080e4e9623cc9787b2..f30d3a70d9985c85fee29451ac968bb620868c14 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2007, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -344,7 +344,8 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
                appendFlags    (newDict, flags6);
 
 
                appendFlags    (newDict, flags6);
 
 
-               if (ifa->ifa_flags & IFF_POINTOPOINT) {
+               if (ifa->ifa_flags & IFF_POINTOPOINT
+                   && ifa->ifa_dstaddr != NULL) {
                        struct sockaddr_in6     *dst6;
 
                        /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */
                        struct sockaddr_in6     *dst6;
 
                        /* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */
index 4cdd37803f673e98ba3b74785c07b82a3883e3d1..a00925524b46effe3ebd4cdaa2dd23028175b320 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002, 2004, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002, 2004, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -36,7 +36,6 @@
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 void   interface_update_ipv6   (struct ifaddrs *ifap, const char *if_name);
 
 __END_DECLS
 void   interface_update_ipv6   (struct ifaddrs *ifap, const char *if_name);
 
 __END_DECLS
index c2cad274232cbc7d19cd99bfdd07c86709d001c3..231b763d2d536a946c93f9474341e97a41416cf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -103,6 +103,18 @@ static const char *dlEventName[] = {
 #ifdef  KEV_DL_LINK_QUALITY_METRIC_CHANGED
        "KEV_DL_LINK_QUALITY_METRIC_CHANGED",
 #endif
 #ifdef  KEV_DL_LINK_QUALITY_METRIC_CHANGED
        "KEV_DL_LINK_QUALITY_METRIC_CHANGED",
 #endif
+#ifdef KEV_DL_NODE_PRESENCE
+       "KEV_DL_NODE_PRESENCE"
+#endif
+#ifdef KEV_DL_NODE_ABSENCE
+       "KEV_DL_NODE_ABSENCE"
+#endif
+#ifdef KEV_DL_MASTER_ELECTED
+       "KEV_DL_MASTER_ELECTED"
+#endif
+#ifdef KEV_DL_ISSUES
+       "KEV_DL_ISSUES",
+#endif
 };
 
 static const char *inet6EventName[] = {
 };
 
 static const char *inet6EventName[] = {
@@ -191,7 +203,7 @@ post_network_changed(void)
        if (network_changed) {
                uint32_t        status;
 
        if (network_changed) {
                uint32_t        status;
 
-               status = notify_post("com.apple.system.config.network_change");
+               status = notify_post(_SC_NOTIFY_NETWORK_CHANGE);
                if (status != NOTIFY_STATUS_OK) {
                        SCLog(TRUE, LOG_ERR, CFSTR("notify_post() failed: error=%ld"), status);
                }
                if (status != NOTIFY_STATUS_OK) {
                        SCLog(TRUE, LOG_ERR, CFSTR("notify_post() failed: error=%ld"), status);
                }
@@ -260,6 +272,8 @@ copy_if_name(struct net_event_data * ev, char * ifr_name, int ifr_len)
        return;
 }
 
        return;
 }
 
+static uint8_t info_zero[DLIL_MODARGLEN];
+
 static void
 processEvent_Apple_Network(struct kern_event_msg *ev_msg)
 {
 static void
 processEvent_Apple_Network(struct kern_event_msg *ev_msg)
 {
@@ -455,6 +469,28 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                }
 #endif  // KEV_DL_LINK_QUALITY_METRIC_CHANGED
 
                                }
 #endif  // KEV_DL_LINK_QUALITY_METRIC_CHANGED
 
+#ifdef KEV_DL_ISSUES
+                               case KEV_DL_ISSUES: {
+                                       struct kev_dl_issues *issues;
+
+                                       issues = (struct kev_dl_issues *)event_data;
+                                       if (dataLen < sizeof(*ev)) {
+                                               handled = FALSE;
+                                               break;
+                                       }
+                                       copy_if_name(ev, ifr_name, sizeof(ifr_name));
+                                       interface_update_link_issues(ifr_name,
+                                                                    issues->timestamp,
+                                                                    issues->modid,
+                                                                    DLIL_MODIDLEN,
+                                                                    issues->info,
+                                                                    (bcmp(issues->info, info_zero, DLIL_MODIDLEN) != 0)
+                                                                       ?DLIL_MODARGLEN
+                                                                       :0);
+                                       break;
+                               }
+#endif // KEV_DL_ISSUES
+
                                case KEV_DL_SIFFLAGS :
                                case KEV_DL_SIFMETRICS :
                                case KEV_DL_SIFMTU :
                                case KEV_DL_SIFFLAGS :
                                case KEV_DL_SIFMETRICS :
                                case KEV_DL_SIFMTU :
index af70ff1dbcf05ccebf7ab2f13f2d3f93ac25bed0..9bce032d29678a3bf3fefe52887f47325111f843 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002, 2004, 2005, 2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002, 2004, 2005, 2007, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -63,7 +63,6 @@ extern Boolean                        _verbose;
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
 int    dgram_socket            (int    domain);
 
 __END_DECLS
 int    dgram_socket            (int    domain);
 
 __END_DECLS
index 788c103b2e7c99cafc20a47b03c39198235d0f29..ebb5b271dbb64384f1207afa775ac8b3cdef80c5 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
index 619bac49946b98cc191674b41f1f55a739309711..aa11307f7216f14e638b2c1efd4708b5f379bb86 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2007, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -40,7 +40,6 @@
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
-#include <SystemConfiguration/LinkConfiguration.h>
 #include <SystemConfiguration/SCDPlugin.h>             // for _SCDPluginExecCommand
 
 #include "SCNetworkConfigurationInternal.h"
 #include <SystemConfiguration/SCDPlugin.h>             // for _SCDPluginExecCommand
 
 #include "SCNetworkConfigurationInternal.h"
@@ -785,7 +784,7 @@ main(int argc, char **argv)
                                        service = CFArrayGetValueAtIndex(services, i);
                                        interface = SCNetworkServiceGetInterface(service);
                                        if ((interface != NULL) &&
                                        service = CFArrayGetValueAtIndex(services, i);
                                        interface = SCNetworkServiceGetInterface(service);
                                        if ((interface != NULL) &&
-                                           !CFSetContainsValue(seen, interface)){
+                                           !CFSetContainsValue(seen, interface)) {
                                                CFDictionaryRef capabilities;
 
                                                capabilities = SCNetworkInterfaceCopyCapability(interface, NULL);
                                                CFDictionaryRef capabilities;
 
                                                capabilities = SCNetworkInterfaceCopyCapability(interface, NULL);
index 55b61a52c98708076ca6d288932c2e83fcc2056f..7963f2da6d4bbf3c3855d15b3b0a2cd76bb71141 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Enabled</key>
        <false/>
        <key>Verbose</key>
        <key>Enabled</key>
        <false/>
        <key>Verbose</key>
index be89fdead1181da0815ef118e94bf0aa4ce904ef..3a86ea740a6357f60108f012a5eb585b04adff63 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Enabled</key>
        <false/>
        <key>Verbose</key>
        <key>Enabled</key>
        <false/>
        <key>Verbose</key>
index 81b7c6ee446e9c5fc886ce3cdc1c05145dbfa8cc..ff5ea319e2d78eebaceb5b506e0975ea2b42f0cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -1259,7 +1259,7 @@ console_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *cont
                        sessionUserName  = CFDictionaryGetValue(session, kSCConsoleSessionUserName);
                        sessionOnConsole = CFDictionaryGetValue(session, kSCConsoleSessionOnConsole);
 
                        sessionUserName  = CFDictionaryGetValue(session, kSCConsoleSessionUserName);
                        sessionOnConsole = CFDictionaryGetValue(session, kSCConsoleSessionOnConsole);
 
-                       CFStringAppendFormat(str, NULL, CFSTR("\n%d : id=%@, user=%@, console=%s"),
+                       CFStringAppendFormat(str, NULL, CFSTR("\n%ld : id=%@, user=%@, console=%s"),
                                             i,
                                             sessionID,
                                             sessionUserName  != NULL ? sessionUserName : CFSTR("?"),
                                             i,
                                             sessionID,
                                             sessionUserName  != NULL ? sessionUserName : CFSTR("?"),
@@ -1512,8 +1512,6 @@ add_nwi_notification()
 #pragma mark Network Configuration Change Events
 
 
 #pragma mark Network Configuration Change Events
 
 
-#define        NETWORKCHANGED_NOTIFY_KEY       "com.apple.system.config.network_change"
-
 static void
 network_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
 static void
 network_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
@@ -1534,7 +1532,7 @@ add_network_notification()
        CFRunLoopSourceRef      rls;
        uint32_t                status;
 
        CFRunLoopSourceRef      rls;
        uint32_t                status;
 
-       status = notify_register_mach_port(NETWORKCHANGED_NOTIFY_KEY,
+       status = notify_register_mach_port(_SC_NOTIFY_NETWORK_CHANGE,
                                           &notify_port,
                                           0,
                                           &notify_token);
                                           &notify_port,
                                           0,
                                           &notify_token);
index 4648c9d2106631aac0de061bfe52fbb2a3d646eb..f7ba56307c137ab7061a74473689d835ab4d127c 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>Builtin</key>
        <true/>
        <key>Requires</key>
        <key>Builtin</key>
        <true/>
        <key>Requires</key>
index 0200299eb35e2024525e36343d96a3ed317de29d..d11aa6deb170a066758f5045cceacd9f19233200 100644 (file)
@@ -135,7 +135,11 @@ establishNewPreferences()
                                        new_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"),
                                                                           old_model, existing_key);
                                        SCPreferencesSetValue(prefs, new_key, value);
                                        new_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"),
                                                                           old_model, existing_key);
                                        SCPreferencesSetValue(prefs, new_key, value);
-                                       SCPreferencesRemoveValue(prefs, existing_key);
+                                       
+                                       /* Let's preserve existing host names */
+                                       if (!CFEqual(existing_key, kSCPrefSystem)) {
+                                               SCPreferencesRemoveValue(prefs, existing_key);
+                                       }
                                        CFRelease(new_key);
                                }
                        }
                                        CFRelease(new_key);
                                }
                        }
@@ -144,7 +148,6 @@ establishNewPreferences()
                                CFRelease(keys);
                        }
                }
                                CFRelease(keys);
                        }
                }
-
                /* Set the new model */
                SCPreferencesSetValue(prefs, MODEL, new_model);
        }
                /* Set the new model */
                SCPreferencesSetValue(prefs, MODEL, new_model);
        }
@@ -299,6 +302,9 @@ watchQuietEnable()
        return;
 }
 
        return;
 }
 
+
+
+
 static void
 watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 {
 static void
 watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 {
index 6b407f5d515c5300a8cca9f4ee112382746dc679..e2077df3fcdbf2221045f38015cea8b97d3c2f7b 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
 </dict>
 </plist>
 </dict>
 </plist>
diff --git a/Plugins/SimulatorSupport/Info.plist b/Plugins/SimulatorSupport/Info.plist
new file mode 100644 (file)
index 0000000..72ccafd
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Builtin</key>
+       <true/>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>SimulatorSupport</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.SystemConfiguration.SimulatorSupport</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>com.apple.SystemConfiguration.SimulatorSupport</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.13</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.13</string>
+</dict>
+</plist>
diff --git a/Plugins/SimulatorSupport/simulator_support.c b/Plugins/SimulatorSupport/simulator_support.c
new file mode 100644 (file)
index 0000000..529dcb8
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2013 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 15, 2013              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/SCValidation.h>
+
+#include <dns_sd.h>
+#ifndef        kDNSServiceCompMulticastDNS
+#define        kDNSServiceCompMulticastDNS     "MulticastDNS"
+#endif
+#ifndef        kDNSServiceCompPrivateDNS
+#define        kDNSServiceCompPrivateDNS       "PrivateDNS"
+#endif
+
+#include "cache.h"
+
+
+static Boolean                 _verbose        = FALSE;
+static CFMutableArrayRef       mirror_keys     = NULL;
+static CFMutableArrayRef       mirror_patterns = NULL;
+static SCDynamicStoreRef       store_host      = NULL;
+static SCDynamicStoreRef       store_sim       = NULL;
+
+
+#pragma mark -
+#pragma mark iOS Simulator Support
+
+
+static void
+mirror(SCDynamicStoreRef store, CFArrayRef changes, void *info)
+{
+       CFDictionaryRef content_host;
+       CFDictionaryRef content_sim;
+       CFIndex         i;
+       CFIndex         n;
+
+       n = CFArrayGetCount(changes);
+       if (n == 0) {
+               // if no changes
+               return;
+       }
+
+       // capture "host" content
+       if (info == NULL) {
+               content_host = SCDynamicStoreCopyMultiple(store_host, changes, NULL);
+       } else {
+               content_host = (CFDictionaryRef)info;
+       }
+
+       // capture [current] "sim" content
+       content_sim = SCDynamicStoreCopyMultiple(store_sim, changes, NULL);
+
+       // update
+       cache_open();
+       for (i = 0; i < n; i++) {
+               CFStringRef             key;
+               CFPropertyListRef       val;
+
+               key = CFArrayGetValueAtIndex(changes, i);
+               val = (content_host != NULL) ? CFDictionaryGetValue(content_host, key) : NULL;
+               if (val != NULL) {
+                       // if "host" content changed
+                       cache_SCDynamicStoreSetValue(store_sim, key, val);
+               } else {
+                       // if no "host" content
+                       val = (content_sim != NULL) ? CFDictionaryGetValue(content_sim, key) : NULL;
+                       if (val != NULL) {
+                               // if we need to remove the "sim" content
+                               cache_SCDynamicStoreRemoveValue(store_sim, key);
+                       } else {
+                               // if no "sim" content to remove, just notify
+                               cache_SCDynamicStoreNotifyValue(store_sim, key);
+                       }
+               }
+       }
+       cache_write(store_sim);
+       cache_close();
+
+       // cleanup
+       if ((info == NULL) && (content_host != NULL)) {
+               CFRelease(content_host);
+       }
+       if (content_sim != NULL) {
+               CFRelease(content_sim);
+       }
+
+       return;
+}
+
+
+static void
+mirror_setup()
+{
+       CFStringRef     key;
+       CFStringRef     pattern;
+
+       mirror_keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       mirror_patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       // Plugin:InterfaceNamer
+       key = SCDynamicStoreKeyCreate(NULL,
+                                     CFSTR("%@" "InterfaceNamer"),
+                                     kSCDynamicStoreDomainPlugin);
+       CFArrayAppendValue(mirror_keys, key);
+       CFRelease(key);
+
+       // Setup:/System
+//     key = SCDynamicStoreKeyCreateComputerName(NULL);
+//     CFArrayAppendValue(mirror_keys, key);
+//     CFRelease(key);
+
+       // Setup:/Network
+//     key = SCDynamicStoreKeyCreateHostNames(NULL);
+//     CFArrayAppendValue(mirror_keys, key);
+//     CFRelease(key);
+
+       // Setup:/Network/Global/.*
+       pattern = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                            kSCDynamicStoreDomainSetup,
+                                                            kSCCompAnyRegex);
+       CFArrayAppendValue(mirror_patterns, pattern);
+       CFRelease(pattern);
+
+       // Setup:/Network/Service/.*
+       // State:/Network/Service/.*
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCCompAnyRegex,
+                                                             CFSTR(".*"),
+                                                             NULL);
+       CFArrayAppendValue(mirror_patterns, pattern);
+       CFRelease(pattern);
+
+       // Setup:/Network/Interface/.*
+       // State:/Network/Interface/.*
+       pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                               kSCCompAnyRegex,
+                                                               CFSTR(".*"),
+                                                               NULL);
+       CFArrayAppendValue(mirror_patterns, pattern);
+       CFRelease(pattern);
+
+       // State:/Network/MulticastDNS
+       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
+                                     kSCDynamicStoreDomainState,
+                                     kSCCompNetwork,
+                                     CFSTR(kDNSServiceCompMulticastDNS));
+       CFArrayAppendValue(mirror_keys, key);
+       CFRelease(key);
+
+       // State:/Network/PrivateDNS
+       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@/%@/%@"),
+                                     kSCDynamicStoreDomainState,
+                                     kSCCompNetwork,
+                                     CFSTR(kDNSServiceCompPrivateDNS));
+       CFArrayAppendValue(mirror_keys, key);
+       CFRelease(key);
+
+       return;
+}
+
+
+#define        N_QUICK 64
+
+
+__private_extern__
+void
+prime_SimulatorSupport()
+{
+       CFDictionaryRef content_host;
+       CFIndex         n;
+
+       SCLog(_verbose, LOG_DEBUG, CFSTR("prime() called"));
+
+       // copy current content from base OS store to _Sim store
+       content_host = SCDynamicStoreCopyMultiple(store_host, mirror_keys, mirror_patterns);
+       CFRelease(mirror_keys);
+       mirror_keys = NULL;
+       CFRelease(mirror_patterns);
+       mirror_patterns = NULL;
+
+       if (content_host == NULL) {
+               return;
+       }
+
+       n = CFDictionaryGetCount(content_host);
+       if (n > 0) {
+               CFArrayRef      changes;
+               const void *    keys_host_q[N_QUICK];
+               const void **   keys_host       = keys_host_q;
+
+               if (n > (CFIndex)(sizeof(keys_host_q) / sizeof(CFStringRef))) {
+                       keys_host = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
+               }
+
+               CFDictionaryGetKeysAndValues(content_host, keys_host, NULL);
+
+               changes = CFArrayCreate(NULL, keys_host, n, &kCFTypeArrayCallBacks);
+               mirror(store_host, changes, (void *)content_host);
+               CFRelease(changes);
+
+               if (keys_host != keys_host_q) {
+                       CFAllocatorDeallocate(NULL, keys_host);
+               }
+       }
+
+       CFRelease(content_host);
+       return;
+}
+
+
+__private_extern__
+void
+load_SimulatorSupport(CFBundleRef bundle, Boolean bundleVerbose)
+{
+       Boolean                 ok;
+       CFMutableDictionaryRef  options;
+       CFRunLoopSourceRef      rls;
+
+       if (bundleVerbose) {
+               _verbose = TRUE;
+       }
+
+       SCLog(_verbose, LOG_DEBUG, CFSTR("load() called"));
+       SCLog(_verbose, LOG_DEBUG, CFSTR("  bundle ID = %@"), CFBundleGetIdentifier(bundle));
+
+       // setup
+       mirror_setup();
+
+       // setup SCDynamicStore mirroring (from "host")
+       options = CFDictionaryCreateMutable(NULL,
+                                           0,
+                                           &kCFTypeDictionaryKeyCallBacks,
+                                           &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(options, kSCDynamicStoreUseHostServer, kCFBooleanTrue);
+       store_host = SCDynamicStoreCreateWithOptions(NULL,
+                                                    CFSTR("SimulatorSupport(host)"),
+                                                    options,
+                                                    mirror,
+                                                    NULL);
+       CFRelease(options);
+       assert(store_host != NULL);
+
+       ok = SCDynamicStoreSetNotificationKeys(store_host, mirror_keys, mirror_patterns);
+       assert(ok);
+
+       rls = SCDynamicStoreCreateRunLoopSource(NULL, store_host, 0);
+       assert(rls != NULL);
+
+       CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+       CFRelease(rls);
+
+       // setup SCDynamicStore mirroring (to "iOS Simulator")
+       store_sim = SCDynamicStoreCreate(NULL,
+                                        CFSTR("SimulatorSupport(sim)"),
+                                        NULL,
+                                        NULL);
+
+       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_SimulatorSupport(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE);
+       prime_SimulatorSupport();
+       CFRunLoopRun();
+       // not reached
+       exit(0);
+       return 0;
+}
+#endif
diff --git a/Plugins/common/IPMonitorControlPrefs.c b/Plugins/common/IPMonitorControlPrefs.c
new file mode 100644 (file)
index 0000000..c82153e
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+/*
+ * IPMonitorControlPrefs.c
+ * - definitions for accessing IPMonitor control preferences
+ */
+
+/*
+ * Modification History
+ *
+ * January 14, 2013    Dieter Siegmund (dieter@apple)
+ * - created
+ */
+
+#include <SystemConfiguration/SCPreferences.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/scprefs_observer.h>
+#include <TargetConditionals.h>
+#include "IPMonitorControlPrefs.h"
+
+/*
+ * kIPMonitorControlPrefsID
+ * - identifies the IPMonitor preferences file that contains 'Verbose'
+ */
+#define kIPMonitorControlPrefsIDStr    "com.apple.IPMonitor.control.plist"
+#define kIPMonitorControlPrefsID       CFSTR(kIPMonitorControlPrefsIDStr)
+
+/*
+ * kVerbose
+ * - indicates whether IPMonitor is verbose or not
+ */
+#define kVerbose                       CFSTR("Verbose")
+
+static SCPreferencesRef                        S_prefs;
+static IPMonitorControlPrefsCallBack   S_callback;
+
+static SCPreferencesRef
+IPMonitorControlPrefsGet(void)
+{
+    if (S_prefs == NULL) {
+       IPMonitorControlPrefsInit(NULL, NULL);
+    }
+    return (S_prefs);
+}
+
+static void
+prefs_changed(__unused void * arg)
+{
+    /* get the current value */
+    if (S_callback != NULL) {
+       (*S_callback)(S_prefs);
+    }
+    return;
+}
+
+#if    TARGET_OS_IPHONE
+/*
+ * kIPMonitorControlManangedPrefsID
+ * - identifies the location of the managed preferences file
+ */
+#define kManagedPrefsDirStr            "/Library/Managed Preferences/mobile/"
+#define kIPMonitorControlManagedPrefsID        CFSTR(kManagedPrefsDirStr       \
+                                             kIPMonitorControlPrefsIDStr)
+static SCPreferencesRef                S_managed_prefs;
+
+static SCPreferencesRef
+IPMonitorControlManagedPrefsGet(void)
+{
+    if (S_managed_prefs == NULL) {
+       S_managed_prefs
+           = SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
+                                 kIPMonitorControlManagedPrefsID);
+    }
+    return (S_managed_prefs);
+}
+
+static void
+enable_prefs_observer(CFRunLoopRef runloop)
+{
+    CFRunLoopSourceContext     context;
+    dispatch_block_t           handler;
+    dispatch_queue_t           queue;
+    CFRunLoopSourceRef         source;
+
+    bzero(&context, sizeof(context));
+    context.perform = prefs_changed;
+    source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
+    CFRunLoopAddSource(runloop, source, kCFRunLoopCommonModes);
+    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    handler = ^{
+       if (source != NULL) {
+           CFRunLoopSourceSignal(source);
+           if (runloop != NULL) {
+               CFRunLoopWakeUp(runloop);
+           }
+       };
+    };
+    _scprefs_observer_watch(scprefs_observer_type_global,
+                           kIPMonitorControlPrefsIDStr,
+                           queue, handler);
+    return;
+}
+
+#else  /* TARGET_OS_IPHONE */
+
+static void
+enable_prefs_observer(CFRunLoopRef runloop)
+{
+    return;
+}
+
+#endif /* TARGET_OS_IPHONE */
+
+static void
+IPMonitorControlPrefsChanged(SCPreferencesRef prefs,
+                            SCPreferencesNotification type,
+                            void * info)
+{
+    prefs_changed(NULL);
+    return;
+}
+
+__private_extern__ SCPreferencesRef
+IPMonitorControlPrefsInit(CFRunLoopRef runloop,
+                         IPMonitorControlPrefsCallBack callback)
+{
+    S_prefs = SCPreferencesCreate(NULL, CFSTR("IPMonitorControlPrefs"),
+                                 kIPMonitorControlPrefsID);
+    if (runloop != NULL && callback != NULL) {
+       S_callback = callback;
+       SCPreferencesSetCallback(S_prefs, IPMonitorControlPrefsChanged, NULL);
+       SCPreferencesScheduleWithRunLoop(S_prefs, runloop,
+                                        kCFRunLoopCommonModes);
+       enable_prefs_observer(runloop);
+    }
+    return (S_prefs);
+}
+
+static Boolean
+IPMonitorControlPrefsSave(void)
+{
+    Boolean            saved = FALSE;
+
+    if (S_prefs != NULL) {
+       saved = SCPreferencesCommitChanges(S_prefs);
+       SCPreferencesSynchronize(S_prefs);
+    }
+    return (saved);
+}
+
+static CFBooleanRef
+prefs_get_boolean(CFStringRef key)
+{
+    CFBooleanRef       b = NULL;
+
+#if    TARGET_OS_IPHONE
+    b = SCPreferencesGetValue(IPMonitorControlManagedPrefsGet(), key);
+    b = isA_CFBoolean(b);
+#endif /* TARGET_OS_IPHONE */
+    if (b == NULL) {
+       b = SCPreferencesGetValue(IPMonitorControlPrefsGet(), key);
+       b = isA_CFBoolean(b);
+    }
+    return (b);
+}
+
+static void
+prefs_set_boolean(CFStringRef key, CFBooleanRef b)
+{
+    SCPreferencesRef   prefs = IPMonitorControlPrefsGet();
+
+    if (prefs != NULL) {
+       if (isA_CFBoolean(b) == NULL) {
+           SCPreferencesRemoveValue(prefs, key);
+       }
+       else {
+           SCPreferencesSetValue(prefs, key, b);
+       }
+    }
+    return;
+}
+
+static void
+IPMonitorControlPrefsRefresh(void)
+{
+    if (S_prefs != NULL) {
+       SCPreferencesSynchronize(S_prefs);
+    }
+#if    TARGET_OS_IPHONE
+    if (S_managed_prefs != NULL) {
+       SCPreferencesSynchronize(S_managed_prefs);
+    }
+#endif /* TARGET_OS_IPHONE */
+    return;
+}
+
+/**
+ ** Get
+ **/
+__private_extern__ Boolean
+IPMonitorControlPrefsIsVerbose(void)
+{
+    CFBooleanRef       b;
+    Boolean            verbose = FALSE;
+
+    b = prefs_get_boolean(kVerbose);
+    if (b != NULL) {
+       verbose = CFBooleanGetValue(b);
+    }
+    /* flush the backing store */
+    IPMonitorControlPrefsRefresh();
+    return (verbose);
+}
+
+/**
+ ** Set
+ **/
+__private_extern__ Boolean
+IPMonitorControlPrefsSetVerbose(Boolean verbose)
+{
+    if (verbose == FALSE) {
+       prefs_set_boolean(kVerbose, NULL);
+    }
+    else {
+       prefs_set_boolean(kVerbose, kCFBooleanTrue);
+    }
+    return (IPMonitorControlPrefsSave());
+}
+
+#ifdef TEST_IPMONITORCONTROLPREFS
+int
+main(int argc, char * argv[])
+{
+    Boolean    need_usage = FALSE;
+    Boolean    success = FALSE;
+
+    if (argc < 2) {
+       need_usage = TRUE;
+    }
+    else if (strcasecmp(argv[1], "on") == 0) {
+       success = IPMonitorControlPrefsSetVerbose(TRUE);
+    }
+    else if (strcasecmp(argv[1], "off") == 0) {
+       success = IPMonitorControlPrefsSetVerbose(FALSE);
+    }
+    else {
+       need_usage = TRUE;
+    }
+    if (need_usage) {
+       fprintf(stderr, "usage: %s ( on | off )\n", argv[0]);
+       exit(1);
+    }
+    if (success == FALSE) {
+       fprintf(stderr, "failed to save prefs\n");
+       exit(2);
+    }
+    exit(0);
+    return (0);
+}
+
+#endif /* TEST_IPMONITORCONTROLPREFS */
diff --git a/Plugins/common/IPMonitorControlPrefs.h b/Plugins/common/IPMonitorControlPrefs.h
new file mode 100644 (file)
index 0000000..e34d378
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013 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 _EAP8021X_EAPOLCONTROLPREFS_H
+#define _EAP8021X_EAPOLCONTROLPREFS_H
+
+/*
+ * IPMonitorControlPrefs.h
+ * - definitions for accessing IPMonitor control preferences and being notified
+ *   when they change
+ */
+
+/*
+ * Modification History
+ *
+ * January 14, 2013    Dieter Siegmund (dieter@apple)
+ * - created
+ */
+#include <CoreFoundation/CFRunLoop.h>
+#include <SystemConfiguration/SCPreferences.h>
+
+typedef void (*IPMonitorControlPrefsCallBack)(SCPreferencesRef prefs);
+
+SCPreferencesRef
+IPMonitorControlPrefsInit(CFRunLoopRef runloop,
+                         IPMonitorControlPrefsCallBack callback);
+
+Boolean
+IPMonitorControlPrefsIsVerbose(void);
+
+Boolean
+IPMonitorControlPrefsSetVerbose(Boolean verbose);
+
+#endif /* _COMMON_IPMONITORCONTROLPREFS_H */
index 22482f249427be2fa4a95cee425a8ebf5b4b535f..e930da3edbcc259cfd7c95d7e0aef850097e09f0 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFPlugInDynamicRegistration</key>
        <string>NO</string>
        <key>CFPlugInFactories</key>
        <key>CFPlugInDynamicRegistration</key>
        <string>NO</string>
        <key>CFPlugInFactories</key>
index 27d67de5faaff14f8368af80b64d632384619d67..7f34e34127ad962fce1d0d311362ed1a319e19a6 100644 (file)
@@ -63,7 +63,7 @@
  *
  *   Note: automatic configuration may not be possible if the logged in user
  *         is NOT "root" (eUID==0) or if the authorization right that governs
  *
  *   Note: automatic configuration may not be possible if the logged in user
  *         is NOT "root" (eUID==0) or if the authorization right that governs
- *         SCHelper write operations (kSCPreferencesWriteAuthorizationRight)
+ *         SCHelper write operations (kSCPreferencesAuthorizationRight_write)
  *         is not currently available.
  *
  * An [older] "User Intervention" key is also supported.  That CFBoolean
  *         is not currently available.
  *
  * An [older] "User Intervention" key is also supported.  That CFBoolean
@@ -145,7 +145,7 @@ hasAuthorization(MyType *myInstance)
                AuthorizationRights     rights;
                OSStatus                status;
 
                AuthorizationRights     rights;
                OSStatus                status;
 
-               items[0].name        = kSCPreferencesWriteAuthorizationRight;
+               items[0].name        = kSCPreferencesAuthorizationRight_write;
                items[0].value       = NULL;
                items[0].valueLength = 0;
                items[0].flags       = 0;
                items[0].value       = NULL;
                items[0].valueLength = 0;
                items[0].flags       = 0;
@@ -722,7 +722,7 @@ watcher_add_lan(MyType *myInstance)
                           myInstance->monitorRls,
                           kCFRunLoopDefaultMode);
 
                           myInstance->monitorRls,
                           kCFRunLoopDefaultMode);
 
-       // check if we already have the "admin" (kSCPreferencesWriteAuthorizationRight)
+       // check if we already have the "admin" (kSCPreferencesAuthorizationRight_write)
        // right.  If so, we can automatically configure (without user intervention) any
        // "new" network interfaces that are present at login (e.g. a USB ethernet
        // dongle that was plugged in before login).
        // right.  If so, we can automatically configure (without user intervention) any
        // "new" network interfaces that are present at login (e.g. a USB ethernet
        // dongle that was plugged in before login).
@@ -1041,7 +1041,7 @@ watcher_add_serial(MyType *myInstance)
 
        if (myInstance->notifyNodes != NULL) {
                // if we have any serial nodes, check if we already have the
 
        if (myInstance->notifyNodes != NULL) {
                // if we have any serial nodes, check if we already have the
-               // "admin" (kSCPreferencesWriteAuthorizationRight) right.  If
+               // "admin" (kSCPreferencesAuthorizationRight_write) right.  If
                // so, we can automatically configure (without user intervention)
                // any "new" network interfaces that are present at login (e.g. a
                // USB modem that was plugged in before login).
                // so, we can automatically configure (without user intervention)
                // any "new" network interfaces that are present at login (e.g. a
                // USB modem that was plugged in before login).
index 4b4891084d6d00287849f263a3dea8f49cfdd3bf..d3c5960f79b59715977b0373855847fc6832cd4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -228,135 +228,27 @@ add_configured_interface(const void *key, const void *value, void *context)
 }
 
 
 }
 
 
-static void
-add_legacy_configuration(addContextRef myContext)
-{
-       CFArrayRef              bonds;
-       CFIndex                 i;
-       CFIndex                 n_bonds;
-       SCPreferencesRef        prefs;
-
-#define BOND_PREFERENCES_ID            CFSTR("VirtualNetworkInterfaces.plist")
-#define        BOND_PREFERENCES_BONDS          CFSTR("Bonds")
-#define        __kBondInterface_interface      CFSTR("interface")      // e.g. bond0, bond1, ...
-#define        __kBondInterface_devices        CFSTR("devices")        // e.g. en0, en1, ...
-#define __kBondInterface_options       CFSTR("options")        // e.g. UserDefinedName
-
-       prefs = SCPreferencesCreate(NULL, CFSTR("SCBondInterfaceCopyAll"), BOND_PREFERENCES_ID);
-       if (prefs == NULL) {
-               return;
-       }
-
-       bonds = SCPreferencesGetValue(prefs, BOND_PREFERENCES_BONDS);
-       if ((bonds != NULL) && !isA_CFArray(bonds)) {
-               CFRelease(prefs);       // if the prefs are confused
-               return;
-       }
-
-       n_bonds = (bonds != NULL) ? CFArrayGetCount(bonds) : 0;
-       for (i = 0; i < n_bonds; i++) {
-               SCBondInterfaceRef              bond;
-               CFDictionaryRef                 bond_dict;
-               CFStringRef                     bond_if;
-               CFDictionaryRef                 dict;
-               CFArrayRef                      interfaces;
-               SCNetworkInterfacePrivateRef    interfacePrivate;
-               CFIndex                         j;
-               CFMutableArrayRef               members         = NULL;
-               CFMutableDictionaryRef          newDict;
-               CFArrayRef                      newInterfaces;
-               CFIndex                         n_interfaces;
-               Boolean                         ok;
-               CFDictionaryRef                 options;
-               CFStringRef                     path;
-
-               bond_dict = CFArrayGetValueAtIndex(bonds, i);
-               if (!isA_CFDictionary(bond_dict)) {
-                       continue;       // if the prefs are confused
-               }
-
-               bond_if = CFDictionaryGetValue(bond_dict, __kBondInterface_interface);
-               if (!isA_CFString(bond_if)) {
-                       continue;       // if the prefs are confused
-               }
-
-               // check if this bond has already been allocated
-               path = CFStringCreateWithFormat(NULL,
-                                               NULL,
-                                               CFSTR("/%@/%@/%@"),
-                                               kSCPrefVirtualNetworkInterfaces,
-                                               kSCNetworkInterfaceTypeBond,
-                                               bond_if);
-               dict = SCPreferencesPathGetValue(myContext->prefs, path);
-               if (dict != NULL) {
-                       // if bond interface name not available
-                       CFRelease(path);
-                       continue;
-               }
-
-               // add a placeholder for the bond in the stored preferences
-               newDict = CFDictionaryCreateMutable(NULL,
-                                                   0,
-                                                   &kCFTypeDictionaryKeyCallBacks,
-                                                   &kCFTypeDictionaryValueCallBacks);
-               newInterfaces = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
-               CFDictionaryAddValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newInterfaces);
-               CFRelease(newInterfaces);
-               ok = SCPreferencesPathSetValue(myContext->prefs, path, newDict);
-               CFRelease(newDict);
-               CFRelease(path);
-               if (!ok) {
-                       // if the bond could not be saved
-                       continue;
-               }
-
-               // create the bond interface
-               bond = (SCBondInterfaceRef)_SCBondInterfaceCreatePrivate(NULL, bond_if);
-
-               // estabish link to the stored configuration
-               interfacePrivate = (SCNetworkInterfacePrivateRef)bond;
-               interfacePrivate->prefs = CFRetain(myContext->prefs);
-
-               // add member interfaces
-               interfaces = CFDictionaryGetValue(bond_dict, __kBondInterface_devices);
-               n_interfaces = isA_CFArray(interfaces) ? CFArrayGetCount(interfaces) : 0;
-               for (j = 0; j < n_interfaces; j++) {
-                       CFStringRef     member;
 
 
-                       member = CFArrayGetValueAtIndex(interfaces, j);
-                       if (isA_CFString(member)) {
-                               add_interface(&members, member);
-                       }
-               }
-               if (members != NULL) {
-                       _SCBondInterfaceSetMemberInterfaces(bond, members);
-                       CFRelease(members);
-               }
+#pragma mark -
+#pragma mark SCBondInterface APIs
 
 
-               // set display name
-               options = CFDictionaryGetValue(bond_dict, __kBondInterface_options);
-               if (isA_CFDictionary(options)) {
-                       CFStringRef     name;
 
 
-                       name = CFDictionaryGetValue(options, kSCPropUserDefinedName);
-                       if (isA_CFString(name)) {
-                               SCBondInterfaceSetLocalizedDisplayName(bond, name);
-                       }
-               }
-
-               CFArrayAppendValue(myContext->bonds, bond);
-               CFRelease(bond);
-       }
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef                   theDict,
+                            CFDictionaryApplierFunction        applier,
+                            void                               *context)
+{
+       CFAllocatorRef  myAllocator;
+       CFDictionaryRef myDict;
 
 
-       CFRelease(prefs);
+       myAllocator = CFGetAllocator(theDict);
+       myDict      = CFDictionaryCreateCopy(myAllocator, theDict);
+       CFDictionaryApplyFunction(myDict, applier, context);
+       CFRelease(myDict);
        return;
 }
 
 
        return;
 }
 
 
-#pragma mark -
-#pragma mark SCBondInterface APIs
-
-
 CFArrayRef
 SCBondInterfaceCopyAll(SCPreferencesRef prefs)
 {
 CFArrayRef
 SCBondInterfaceCopyAll(SCPreferencesRef prefs)
 {
@@ -373,20 +265,10 @@ SCBondInterfaceCopyAll(SCPreferencesRef prefs)
                                        kSCPrefVirtualNetworkInterfaces,
                                        kSCNetworkInterfaceTypeBond);
        dict = SCPreferencesPathGetValue(prefs, path);
                                        kSCPrefVirtualNetworkInterfaces,
                                        kSCNetworkInterfaceTypeBond);
        dict = SCPreferencesPathGetValue(prefs, path);
+       CFRelease(path);
        if (isA_CFDictionary(dict)) {
        if (isA_CFDictionary(dict)) {
-               CFDictionaryApplyFunction(dict, add_configured_interface, &context);
-       } else {
-               // no bond configuration, upgrade from legacy configuration
-               dict = CFDictionaryCreate(NULL,
-                                         NULL, NULL, 0,
-                                         &kCFTypeDictionaryKeyCallBacks,
-                                         &kCFTypeDictionaryValueCallBacks);
-               (void) SCPreferencesPathSetValue(prefs, path, dict);
-               CFRelease(dict);
-
-               add_legacy_configuration(&context);
+               my_CFDictionaryApplyFunction(dict, add_configured_interface, &context);
        }
        }
-       CFRelease(path);
 
        return context.bonds;
 }
 
        return context.bonds;
 }
@@ -563,6 +445,7 @@ _SCBondInterfaceCopyActive(void)
                // set the mode
                int_val = ibsr_p->ibsr_mode;
                mode = CFNumberCreate(NULL, kCFNumberIntType, &int_val);
                // set the mode
                int_val = ibsr_p->ibsr_mode;
                mode = CFNumberCreate(NULL, kCFNumberIntType, &int_val);
+               assert(mode != NULL);
                _SCBondInterfaceSetMode(bond, mode);
                CFRelease(mode);
 
                _SCBondInterfaceSetMode(bond, mode);
                CFRelease(mode);
 
@@ -595,7 +478,9 @@ _SCBondInterfaceCopyActive(void)
 
     done :
 
 
     done :
 
-       (void) close(s);
+       if (s != -1) {
+               (void) close(s);
+       }
        freeifaddrs(ifap);
        return bonds;
 }
        freeifaddrs(ifap);
        return bonds;
 }
@@ -625,7 +510,7 @@ SCBondInterfaceCreate(SCPreferencesRef prefs)
                Boolean                         ok;
                CFStringRef                     path;
 
                Boolean                         ok;
                CFStringRef                     path;
 
-               bond_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("bond%d"), i);
+               bond_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("bond%ld"), i);
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
@@ -774,8 +659,9 @@ _SCBondInterfaceSetMemberInterfaces(SCBondInterfaceRef bond, CFArrayRef members)
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newMembers);
                CFRelease(newMembers);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondInterfaces, newMembers);
                CFRelease(newMembers);
-
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -925,7 +811,9 @@ SCBondInterfaceSetLocalizedDisplayName(SCBondInterfaceRef bond, CFStringRef newN
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -987,7 +875,9 @@ SCBondInterfaceSetOptions(SCBondInterfaceRef bond, CFDictionaryRef newOptions)
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBondOptions);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBondOptions);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -1014,6 +904,8 @@ _SCBondInterfaceSetMode(SCBondInterfaceRef bond, CFNumberRef mode)
        Boolean                         needs_release           = FALSE;
        Boolean                         ok                      = TRUE;
 
        Boolean                         needs_release           = FALSE;
        Boolean                         ok                      = TRUE;
 
+       assert(bond != NULL);
+
        if (mode == NULL) {
                int     mode_num        = IF_BOND_MODE_LACP;
 
        if (mode == NULL) {
                int     mode_num        = IF_BOND_MODE_LACP;
 
@@ -1043,8 +935,9 @@ _SCBondInterfaceSetMode(SCBondInterfaceRef bond, CFNumberRef mode)
                }
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondMode, mode);
                }
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBondMode, mode);
-
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
index 3124eb15106f23d70b4602b26db8f47170d16d08..d291a3cef83db4bba23cb805a524d3fc020ddf6e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -155,7 +155,7 @@ static void
 add_configured_interface(const void *key, const void *value, void *context)
 {
        SCBridgeInterfaceRef            bridge;
 add_configured_interface(const void *key, const void *value, void *context)
 {
        SCBridgeInterfaceRef            bridge;
-       CFStringRef                     bridge_if               = (CFStringRef)key;
+       CFStringRef                     bridge_if       = (CFStringRef)key;
        CFDictionaryRef                 bridge_info     = (CFDictionaryRef)value;
        CFDictionaryRef                 bridge_options;
        CFIndex                         i;
        CFDictionaryRef                 bridge_info     = (CFDictionaryRef)value;
        CFDictionaryRef                 bridge_options;
        CFIndex                         i;
@@ -164,10 +164,16 @@ add_configured_interface(const void *key, const void *value, void *context)
        CFMutableArrayRef               members         = NULL;
        addContextRef                   myContext       = (addContextRef)context;
        CFStringRef                     name;
        CFMutableArrayRef               members         = NULL;
        addContextRef                   myContext       = (addContextRef)context;
        CFStringRef                     name;
+       CFStringRef                     name_auto       = NULL;
        CFIndex                         n;
 
        // create the bridge interface
        bridge = (SCBridgeInterfaceRef)_SCBridgeInterfaceCreatePrivate(NULL, bridge_if);
        CFIndex                         n;
 
        // create the bridge interface
        bridge = (SCBridgeInterfaceRef)_SCBridgeInterfaceCreatePrivate(NULL, bridge_if);
+       assert(bridge != NULL);
+
+       // estabish link to the stored configuration
+       interfacePrivate = (SCNetworkInterfacePrivateRef)bridge;
+       interfacePrivate->prefs = CFRetain(myContext->prefs);
 
        // add member interfaces
        interfaces = CFDictionaryGetValue(bridge_info, kSCPropVirtualNetworkInterfacesBridgeInterfaces);
 
        // add member interfaces
        interfaces = CFDictionaryGetValue(bridge_info, kSCPropVirtualNetworkInterfacesBridgeInterfaces);
@@ -185,21 +191,24 @@ add_configured_interface(const void *key, const void *value, void *context)
                CFRelease(members);
        }
 
                CFRelease(members);
        }
 
-       // set display name
-       name = CFDictionaryGetValue(bridge_info, kSCPropUserDefinedName);
-       if (isA_CFString(name)) {
-               SCBridgeInterfaceSetLocalizedDisplayName(bridge, name);
-       }
-
        // set options
        bridge_options = CFDictionaryGetValue(bridge_info, kSCPropVirtualNetworkInterfacesBridgeOptions);
        if (isA_CFDictionary(bridge_options)) {
                SCBridgeInterfaceSetOptions(bridge, bridge_options);
        // set options
        bridge_options = CFDictionaryGetValue(bridge_info, kSCPropVirtualNetworkInterfacesBridgeOptions);
        if (isA_CFDictionary(bridge_options)) {
                SCBridgeInterfaceSetOptions(bridge, bridge_options);
+               name_auto = CFDictionaryGetValue(bridge_options, CFSTR("__AUTO__"));
        }
 
        }
 
-       // estabish link to the stored configuration
-       interfacePrivate = (SCNetworkInterfacePrivateRef)bridge;
-       interfacePrivate->prefs = CFRetain(myContext->prefs);
+       // set display name
+       name = CFDictionaryGetValue(bridge_info, kSCPropUserDefinedName);
+       if (isA_CFString(name)) {
+               SCBridgeInterfaceSetLocalizedDisplayName(bridge, name);
+       } else if (isA_CFString(name_auto)) {
+               interfacePrivate->localized_key = name_auto;
+               if (interfacePrivate->localized_arg1 != NULL) {
+                       CFRelease(interfacePrivate->localized_arg1);
+                       interfacePrivate->localized_arg1 = NULL;
+               }
+       }
 
        CFArrayAppendValue(myContext->bridges, bridge);
        CFRelease(bridge);
 
        CFArrayAppendValue(myContext->bridges, bridge);
        CFRelease(bridge);
@@ -212,6 +221,22 @@ add_configured_interface(const void *key, const void *value, void *context)
 #pragma mark SCBridgeInterface APIs
 
 
 #pragma mark SCBridgeInterface APIs
 
 
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef                   theDict,
+                            CFDictionaryApplierFunction        applier,
+                            void                               *context)
+{
+       CFAllocatorRef  myAllocator;
+       CFDictionaryRef myDict;
+
+       myAllocator = CFGetAllocator(theDict);
+       myDict      = CFDictionaryCreateCopy(myAllocator, theDict);
+       CFDictionaryApplyFunction(myDict, applier, context);
+       CFRelease(myDict);
+       return;
+}
+
+
 CFArrayRef
 SCBridgeInterfaceCopyAll(SCPreferencesRef prefs)
 {
 CFArrayRef
 SCBridgeInterfaceCopyAll(SCPreferencesRef prefs)
 {
@@ -229,7 +254,7 @@ SCBridgeInterfaceCopyAll(SCPreferencesRef prefs)
                                        kSCNetworkInterfaceTypeBridge);
        dict = SCPreferencesPathGetValue(prefs, path);
        if (isA_CFDictionary(dict)) {
                                        kSCNetworkInterfaceTypeBridge);
        dict = SCPreferencesPathGetValue(prefs, path);
        if (isA_CFDictionary(dict)) {
-               CFDictionaryApplyFunction(dict, add_configured_interface, &context);
+               my_CFDictionaryApplyFunction(dict, add_configured_interface, &context);
        }
        CFRelease(path);
 
        }
        CFRelease(path);
 
@@ -378,6 +403,7 @@ _SCBridgeInterfaceCopyActive(void)
                struct ifbifconf                *ibc_p;
                struct if_data                  *if_data;
                CFMutableArrayRef               members         = NULL;
                struct ifbifconf                *ibc_p;
                struct if_data                  *if_data;
                CFMutableArrayRef               members         = NULL;
+               size_t                          n;
 
                if_data = (struct if_data *)ifp->ifa_data;
                if (if_data == NULL
 
                if_data = (struct if_data *)ifp->ifa_data;
                if (if_data == NULL
@@ -386,6 +412,18 @@ _SCBridgeInterfaceCopyActive(void)
                        continue;
                }
 
                        continue;
                }
 
+               // check the interface name ("bridgeNNN") and ensure that
+               // we leave all non-SC configured bridge interfaces (those
+               // with unit #'s >= 100) alone.
+               n = strlen(ifp->ifa_name);
+               if ((n > 3) &&
+                   isdigit(ifp->ifa_name[n - 1]) &&
+                   isdigit(ifp->ifa_name[n - 2]) &&
+                   isdigit(ifp->ifa_name[n - 3])) {
+                       // if not SC managed bridge interface
+                       continue;
+               }
+
                ibc_p = ifbifconf_copy(s, ifp->ifa_name);
                if (ibc_p == NULL) {
                        if (errno == EBUSY) {
                ibc_p = ifbifconf_copy(s, ifp->ifa_name);
                if (ibc_p == NULL) {
                        if (errno == EBUSY) {
@@ -436,7 +474,9 @@ _SCBridgeInterfaceCopyActive(void)
 
     done :
 
 
     done :
 
-       (void) close(s);
+       if (s != -1) {
+               (void) close(s);
+       }
        freeifaddrs(ifap);
        return bridges;
 }
        freeifaddrs(ifap);
        return bridges;
 }
@@ -466,7 +506,7 @@ SCBridgeInterfaceCreate(SCPreferencesRef prefs)
                Boolean                         ok;
                CFStringRef                     path;
 
                Boolean                         ok;
                CFStringRef                     path;
 
-               bridge_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("bridge%d"), i);
+               bridge_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("bridge%ld"), i);
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
@@ -615,8 +655,9 @@ _SCBridgeInterfaceSetMemberInterfaces(SCBridgeInterfaceRef bridge, CFArrayRef me
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBridgeInterfaces, newMembers);
                CFRelease(newMembers);
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesBridgeInterfaces, newMembers);
                CFRelease(newMembers);
-
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -766,7 +807,9 @@ SCBridgeInterfaceSetLocalizedDisplayName(SCBridgeInterfaceRef bridge, CFStringRe
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -828,7 +871,9 @@ SCBridgeInterfaceSetOptions(SCBridgeInterfaceRef bridge, CFDictionaryRef newOpti
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBridgeOptions);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBridgeOptions);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -840,7 +885,23 @@ SCBridgeInterfaceSetOptions(SCBridgeInterfaceRef bridge, CFDictionaryRef newOpti
                        interfacePrivate->bridge.options = NULL;
                }
                if (newOptions != NULL) {
                        interfacePrivate->bridge.options = NULL;
                }
                if (newOptions != NULL) {
+                       CFStringRef     name_auto       = NULL;
+
                        interfacePrivate->bridge.options = CFDictionaryCreateCopy(NULL, newOptions);
                        interfacePrivate->bridge.options = CFDictionaryCreateCopy(NULL, newOptions);
+
+                       // set [auto] display name from options
+                       if ((interfacePrivate->localized_name == NULL) &&
+                           CFDictionaryGetValueIfPresent(newOptions,
+                                                         CFSTR("__AUTO__"),
+                                                         (const void **)&name_auto) &&
+                           isA_CFString(name_auto)) {
+                               // set display name
+                               interfacePrivate->localized_key = name_auto;
+                               if (interfacePrivate->localized_arg1 != NULL) {
+                                       CFRelease(interfacePrivate->localized_arg1);
+                                       interfacePrivate->localized_arg1 = NULL;
+                               }
+                       }
                }
        }
 
                }
        }
 
@@ -984,10 +1045,10 @@ _SCBridgeInterfaceUpdateConfiguration(SCPreferencesRef prefs)
                                CFIndex         c_count;
 
                                c_bridge_interfaces = SCBridgeInterfaceGetMemberInterfaces(c_bridge);
                                CFIndex         c_count;
 
                                c_bridge_interfaces = SCBridgeInterfaceGetMemberInterfaces(c_bridge);
-                               c_count           = (c_bridge_interfaces != NULL) ? CFArrayGetCount(c_bridge_interfaces) : 0;
+                               c_count             = (c_bridge_interfaces != NULL) ? CFArrayGetCount(c_bridge_interfaces) : 0;
 
                                a_bridge_interfaces = SCBridgeInterfaceGetMemberInterfaces(a_bridge);
 
                                a_bridge_interfaces = SCBridgeInterfaceGetMemberInterfaces(a_bridge);
-                               a_count           = (a_bridge_interfaces != NULL) ? CFArrayGetCount(a_bridge_interfaces) : 0;
+                               a_count             = (a_bridge_interfaces != NULL) ? CFArrayGetCount(a_bridge_interfaces) : 0;
 
                                for (a = 0; a < a_count; a++) {
                                        SCNetworkInterfaceRef   a_interface;
 
                                for (a = 0; a < a_count; a++) {
                                        SCNetworkInterfaceRef   a_interface;
index f295bb690b12001e492343ad9823cacea8e75cdc..94577fe419e8869d33239b5c093ab22a2c198052 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #pragma mark CaptiveNetwork.framework APIs (exported through the SystemConfiguration.framework)
 
 
 #pragma mark CaptiveNetwork.framework APIs (exported through the SystemConfiguration.framework)
 
 
-#if    TARGET_OS_EMBEDDED
+#if    TARGET_OS_IPHONE
 const CFStringRef kCNNetworkInfoKeySSIDData    = CFSTR("SSIDDATA");
 const CFStringRef kCNNetworkInfoKeySSID        = CFSTR("SSID");
 const CFStringRef kCNNetworkInfoKeyBSSID       = CFSTR("BSSID");
 const CFStringRef kCNNetworkInfoKeySSIDData    = CFSTR("SSIDDATA");
 const CFStringRef kCNNetworkInfoKeySSID        = CFSTR("SSID");
 const CFStringRef kCNNetworkInfoKeyBSSID       = CFSTR("BSSID");
-#endif // TARGET_OS_EMBEDDED
+#endif // TARGET_OS_IPHONE
 
 
 static void *
 
 
 static void *
@@ -109,7 +109,7 @@ CNCopySupportedInterfaces(void)
 }
 
 
 }
 
 
-#if    TARGET_OS_EMBEDDED
+#if    TARGET_OS_IPHONE
 CFDictionaryRef
 CNCopyCurrentNetworkInfo(CFStringRef   interfaceName)
 {
 CFDictionaryRef
 CNCopyCurrentNetworkInfo(CFStringRef   interfaceName)
 {
@@ -120,4 +120,4 @@ CNCopyCurrentNetworkInfo(CFStringRef        interfaceName)
        }
        return dyfunc ? dyfunc(interfaceName) : NULL;
 }
        }
        return dyfunc ? dyfunc(interfaceName) : NULL;
 }
-#endif // TARGET_OS_EMBEDDED
+#endif // TARGET_OS_IPHONE
index 12fd409d2427482f4ce0e95d8303c276455ad421..316c31bc7bedeb1d2b1d0eee4a4e8a6d03287b7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -106,8 +106,6 @@ CNMarkPortalOffline (CFStringRef    interfaceName)          __OSX_AVAILABLE_STARTING(__MAC_
 CFArrayRef
 CNCopySupportedInterfaces      (void)                          __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_4_1);
 
 CFArrayRef
 CNCopySupportedInterfaces      (void)                          __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_4_1);
 
-#if    TARGET_OS_EMBEDDED
-
 /*!
  @constant kCNNetworkInfoKeySSIDData
  @discussion NetworkInfo Dictionary key for SSID in CFData format
 /*!
  @constant kCNNetworkInfoKeySSIDData
  @discussion NetworkInfo Dictionary key for SSID in CFData format
@@ -148,8 +146,6 @@ extern const CFStringRef kCNNetworkInfoKeyBSSID                     __OSX_AVAILABLE_STARTING(__MAC
 CFDictionaryRef
 CNCopyCurrentNetworkInfo       (CFStringRef interfaceName)     __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1);
 
 CFDictionaryRef
 CNCopyCurrentNetworkInfo       (CFStringRef interfaceName)     __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1);
 
-#endif // TARGET_OS_EMBEDDED
-
 __END_DECLS
 
 #endif /* _CAPTIVENETWORK_H */
 __END_DECLS
 
 #endif /* _CAPTIVENETWORK_H */
index 2ea9adbd461f62b0138ef5fe896af55aabf9e37e..927ee05c3d43326cdda91f41184d66c6a82ec2ca 100644 (file)
Binary files a/SystemConfiguration.fproj/English.lproj/NetworkInterface.strings and b/SystemConfiguration.fproj/English.lproj/NetworkInterface.strings differ
index 87f9a94b8ba66d1bdc7fcd7089e08d42582bacf7..9f9b512bdc733ce4bd51eda264b1001aa5f7c7f2 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
 </dict>
 </plist>
 </dict>
 </plist>
index 87f9a94b8ba66d1bdc7fcd7089e08d42582bacf7..9f9b512bdc733ce4bd51eda264b1001aa5f7c7f2 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.12.2</string>
+       <string>1.13</string>
 </dict>
 </plist>
 </dict>
 </plist>
index 85249b035d0db0fe24115dbb4ca7720315e65d57..f75743fe033a75c8102c43d412442a28dd6c835e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2007, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2007, 2010, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -121,7 +121,15 @@ __getCapabilities(CFStringRef      interfaceName,
 
        if (ioctl(sock, SIOCGIFCAP, (caddr_t)&ifr) == -1) {
                _SCErrorSet(errno);
 
        if (ioctl(sock, SIOCGIFCAP, (caddr_t)&ifr) == -1) {
                _SCErrorSet(errno);
-               SCLog(TRUE, LOG_ERR, CFSTR("ioctl(SIOCGIFCAP) failed: %s"), strerror(errno));
+               switch (errno) {
+                       case EBUSY :
+                       case ENXIO :
+                               break;
+                       default :
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("ioctl(SIOCGIFCAP) failed: %s"),
+                                     strerror(errno));
+               }
                goto done;
        }
 
                goto done;
        }
 
@@ -867,6 +875,15 @@ _SCNetworkInterfaceIsPhysicalEthernet(SCNetworkInterfaceRef interface)
 
        ifm = __copyMediaList(interfaceName);
        if (ifm == NULL) {
 
        ifm = __copyMediaList(interfaceName);
        if (ifm == NULL) {
+               CFStringRef interfaceType;
+
+               interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+               if (CFEqual(interfaceType, kSCNetworkInterfaceTypeEthernet) &&
+                   !_SCNetworkInterfaceIsTethered(interface) &&
+                   !_SCNetworkInterfaceIsBluetoothPAN(interface)) {
+                   // if likely physical ethernet interface
+                   return TRUE;
+               }
                return FALSE;
        }
        _SCErrorSet(kSCStatusOK);
                return FALSE;
        }
        _SCErrorSet(kSCStatusOK);
@@ -1235,71 +1252,3 @@ SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef   interface,
        if (newConfiguration != NULL) CFRelease(newConfiguration);
        return ok;
 }
        if (newConfiguration != NULL) CFRelease(newConfiguration);
        return ok;
 }
-
-
-// XXXXX
-// XXXXX Remove the following SPIs as soon as we have migrated all
-// XXXXX internal users
-// XXXXX
-
-/* DEPRECATED */ Boolean
-NetworkInterfaceCopyMediaOptions(CFStringRef           interfaceName,
-                                CFDictionaryRef        *current,
-                                CFDictionaryRef        *active,
-                                CFArrayRef             *available,
-                                Boolean                filter)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate;
-       Boolean                         ok;
-
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
-       if (interfacePrivate == NULL) {
-               return FALSE;
-       }
-       interfacePrivate->entity_device = CFRetain(interfaceName);
-       ok = SCNetworkInterfaceCopyMediaOptions((SCNetworkInterfaceRef)interfacePrivate,
-                                               current,
-                                               active,
-                                               available,
-                                               filter);
-       CFRelease(interfacePrivate);
-       return ok;
-}
-
-
-/* DEPRECATED */ CFArrayRef
-NetworkInterfaceCopyMediaSubTypes(CFArrayRef   available)
-{
-       return SCNetworkInterfaceCopyMediaSubTypes(available);
-}
-
-
-/* DEPRECATED */ CFArrayRef
-NetworkInterfaceCopyMediaSubTypeOptions(CFArrayRef     available,
-                                       CFStringRef     subType)
-{
-       return SCNetworkInterfaceCopyMediaSubTypeOptions(available, subType);
-}
-
-
-/* DEPRECATED */ Boolean
-NetworkInterfaceCopyMTU(CFStringRef    interfaceName,
-                       int             *mtu_cur,
-                       int             *mtu_min,
-                       int             *mtu_max)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate;
-       Boolean                         ok;
-
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
-       if (interfacePrivate == NULL) {
-               return FALSE;
-       }
-       interfacePrivate->entity_device = CFRetain(interfaceName);
-       ok = SCNetworkInterfaceCopyMTU((SCNetworkInterfaceRef)interfacePrivate,
-                                      mtu_cur,
-                                      mtu_min,
-                                      mtu_max);
-       CFRelease(interfacePrivate);
-       return ok;
-}
diff --git a/SystemConfiguration.fproj/LinkConfiguration.h b/SystemConfiguration.fproj/LinkConfiguration.h
deleted file mode 100644 (file)
index 6a6c53f..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2002, 2004, 2006, 2008 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 _LINKCONFIGURATION_H
-#define _LINKCONFIGURATION_H
-
-#include <Availability.h>
-#include <sys/cdefs.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-/*!
-       @header LinkConfiguration
-*/
-
-__BEGIN_DECLS
-
-/*!
-       @function NetworkInterfaceCopyMediaOptions
-       @discussion For the specified network interface, returns information
-               about the currently requested media options, the active media
-               options, and the media options which are available.
-       @param interface The desired network interface.
-       @param current A pointer to memory that will be filled with a CFDictionaryRef
-               representing the currently requested media options (subtype, options).
-               If NULL, the current options will not be returned.
-       @param active A pointer to memory that will be filled with a CFDictionaryRef
-               representing the active media options (subtype, options).
-               If NULL, the active options will not be returned.
-       @param available A pointer to memory that will be filled with a CFArrayRef
-               representing the possible media options (subtype, options).
-               If NULL, the available options will not be returned.
-       @param filter A boolean indicating whether the available options should be
-               filtered to exclude those options which would not normally be
-               requested by a user/admin (e.g. hw-loopback).
-       @result TRUE if requested information has been returned.
-
- */
-Boolean
-NetworkInterfaceCopyMediaOptions(
-                                CFStringRef            interface,
-                                CFDictionaryRef        *current,
-                                CFDictionaryRef        *active,
-                                CFArrayRef             *available,
-                                Boolean                filter
-                                )              __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-
-/*!
-       @function NetworkInterfaceCopyMediaSubTypes
-       @discussion For the provided interface configuration options, return a list
-               of available media subtypes.
-       @param available The available options as returned by the
-               NetworkInterfaceCopyMediaOptions function.
-       @result An array of available media subtypes CFString's (e.g. 10BaseT/UTP,
-               100baseTX, etc).  NULL if no subtypes are available.
- */
-CFArrayRef
-NetworkInterfaceCopyMediaSubTypes(
-                                 CFArrayRef            available
-                                 )             __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-
-/*!
-       @function NetworkInterfaceCopyMediaSubTypeOptions
-       @discussion For the provided interface configuration options and specific
-               subtype, return a list of available media options.
-       @param available The available options as returned by the
-               NetworkInterfaceCopyMediaOptions function.
-       @param subType The subtype
-       @result An array of available media options.  Each of the available options
-               is returned as an array of CFString's (e.g. <half-duplex>,
-               <full-duplex,flow-control>).  NULL if no options are available.
- */
-CFArrayRef
-NetworkInterfaceCopyMediaSubTypeOptions(
-                                       CFArrayRef              available,
-                                       CFStringRef             subType
-                                       )       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-
-/*!
-       @function NetworkInterfaceCopyMTU
-       @discussion
-       @param interface The desired network interface.
-       @param mtu_cur A pointer to memory that will be filled with the current
-               MTU setting for the interface.
-       @param mtu_min A pointer to memory that will be filled with the minimum
-               MTU setting for the interface.  If negative, the minimum setting
-               could not be determined.
-       @param mtu_max A pointer to memory that will be filled with the maximum
-               MTU setting for the interface.  If negative, the maximum setting
-               could not be determined.
-       @result TRUE if requested information has been returned.
-
- */
-Boolean
-NetworkInterfaceCopyMTU(
-                       CFStringRef     interface,
-                       int             *mtu_cur,
-                       int             *mtu_min,
-                       int             *mtu_max
-                       )                       __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_5,__IPHONE_NA,__IPHONE_NA);
-
-
-__END_DECLS
-
-#endif /* _LINKCONFIGURATION_H */
-
index 43a21011d85dc399079ca73acc8f30bac68d5909..d6b87108e95177bc3f784a197132cea78f769d9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -34,6 +34,8 @@
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <servers/bootstrap.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <servers/bootstrap.h>
+#include <asl_msg.h>
+#include <asl_core.h>
 #include <pthread.h>
 #include <sys/time.h>
 
 #include <pthread.h>
 #include <sys/time.h>
 
@@ -48,8 +50,8 @@
 int    _sc_debug       = FALSE;        /* non-zero if debugging enabled */
 int    _sc_verbose     = FALSE;        /* non-zero if verbose logging enabled */
 int    _sc_log         = TRUE;         /* 0 if SC messages should be written to stdout/stderr,
 int    _sc_debug       = FALSE;        /* non-zero if debugging enabled */
 int    _sc_verbose     = FALSE;        /* non-zero if verbose logging enabled */
 int    _sc_log         = TRUE;         /* 0 if SC messages should be written to stdout/stderr,
-                                          1 if SC messages should be logged w/asl(3),
-                                          2 if SC messages should be written to stdout/stderr AND logged */
+                                        1 if SC messages should be logged w/asl(3),
+                                        2 if SC messages should be written to stdout/stderr AND logged */
 
 
 #pragma mark -
 
 
 #pragma mark -
@@ -87,7 +89,6 @@ __SCThreadSpecificDataRef
 __SCGetThreadSpecificData()
 {
        __SCThreadSpecificDataRef       tsd;
 __SCGetThreadSpecificData()
 {
        __SCThreadSpecificDataRef       tsd;
-
        pthread_once(&tsKeyInitialized, __SCThreadSpecificKeyInitialize);
 
        tsd = pthread_getspecific(tsDataKey);
        pthread_once(&tsKeyInitialized, __SCThreadSpecificKeyInitialize);
 
        tsd = pthread_getspecific(tsDataKey);
@@ -107,6 +108,10 @@ __SCGetThreadSpecificData()
 #pragma mark Logging
 
 
 #pragma mark Logging
 
 
+#define kASLModule             "ASLModule"
+#define kASLOption             "ASLOption"
+#define kLoggerID              "LoggerID"
+
 #define        ENABLE_SC_FORMATTING
 #ifdef ENABLE_SC_FORMATTING
 // from <CoreFoundation/ForFoundationOnly.h>
 #define        ENABLE_SC_FORMATTING
 #ifdef ENABLE_SC_FORMATTING
 // from <CoreFoundation/ForFoundationOnly.h>
@@ -178,26 +183,26 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
                tZone = CFTimeZoneCopySystem();
                gDate = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(cf), tZone);
                str   = CFStringCreateWithFormat(NULL,
                tZone = CFTimeZoneCopySystem();
                gDate = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(cf), tZone);
                str   = CFStringCreateWithFormat(NULL,
-                                               formatOptions,
-                                               CFSTR("%@%02d/%02d/%04d %02d:%02d:%02.0f %@"),
-                                               prefix1,
-                                               gDate.month,
-                                               gDate.day,
-                                               gDate.year,
-                                               gDate.hour,
-                                               gDate.minute,
-                                               gDate.second,
-                                               CFTimeZoneGetName(tZone));
+                                                formatOptions,
+                                                CFSTR("%@%02d/%02d/%04d %02d:%02d:%02.0f %@"),
+                                                prefix1,
+                                                gDate.month,
+                                                gDate.day,
+                                                (int)gDate.year,
+                                                gDate.hour,
+                                                gDate.minute,
+                                                gDate.second,
+                                                CFTimeZoneGetName(tZone));
                CFRelease(tZone);
                return str;
        }
 
                CFRelease(tZone);
                return str;
        }
 
-       if (!formatOptions ||
+       if ((formatOptions == NULL) ||
            !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) {
                prefix2 = prefix1;
        }
 
            !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) {
                prefix2 = prefix1;
        }
 
-       if (formatOptions) {
+       if (formatOptions != NULL) {
                nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions);
        } else {
                nFormatOptions = CFDictionaryCreateMutable(NULL,
                nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions);
        } else {
                nFormatOptions = CFDictionaryCreateMutable(NULL,
@@ -205,6 +210,7 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
                                                           &kCFTypeDictionaryKeyCallBacks,
                                                           &kCFTypeDictionaryValueCallBacks);
        }
                                                           &kCFTypeDictionaryKeyCallBacks,
                                                           &kCFTypeDictionaryValueCallBacks);
        }
+       assert(nFormatOptions != NULL);
 
 #define        N_QUICK 32
 
 
 #define        N_QUICK 32
 
@@ -229,7 +235,7 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
                                CFStringRef             nStr;
                                CFStringRef             vStr;
 
                                CFStringRef             nStr;
                                CFStringRef             vStr;
 
-                               nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%u"), i);
+                               nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), i);
 
                                nPrefix1 = CFStringCreateMutable(NULL, 0);
                                CFStringAppendFormat(nPrefix1,
 
                                nPrefix1 = CFStringCreateMutable(NULL, 0);
                                CFStringAppendFormat(nPrefix1,
@@ -355,7 +361,6 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
 
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
 
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
-
 static void
 __SCLog(aslclient asl, aslmsg msg, int level, CFStringRef formatString, va_list formatArguments)
 {
 static void
 __SCLog(aslclient asl, aslmsg msg, int level, CFStringRef formatString, va_list formatArguments)
 {
@@ -606,6 +611,432 @@ SCTrace(Boolean condition, FILE *stream, CFStringRef formatString, ...)
 }
 
 
 }
 
 
+#pragma mark -
+#pragma mark ASL Functions
+
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+
+extern kern_return_t _asl_server_query(mach_port_t server,
+                                      caddr_t request,
+                                      mach_msg_type_number_t requestCnt,
+                                      uint64_t startid,
+                                      int count,
+                                      int flags,
+                                      caddr_t *reply,
+                                      mach_msg_type_number_t *replyCnt,
+                                      uint64_t *lastid,
+                                      int *status,
+                                      security_token_t *token);
+
+#define ASL_SERVICE_NAME "com.apple.system.logger"
+
+
+static aslresponse
+_asl_control_query(aslmsg a)
+{
+       asl_search_result_t *out;
+       char *qstr, *str, *res;
+       uint32_t len, reslen, status;
+       uint64_t cmax, qmin;
+       kern_return_t kstatus;
+       caddr_t vmstr;
+       mach_port_t server_port;
+       security_token_t sec;
+
+       bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &server_port);
+       if (server_port == MACH_PORT_NULL) return NULL;
+
+       len = 0;
+       qstr = asl_msg_to_string((asl_msg_t *)a, &len);
+
+       str = NULL;
+       if (qstr == NULL)
+       {
+               asprintf(&str, "1\nQ [= ASLOption control]\n");
+               len = 27;
+       }
+       else
+       {
+               asprintf(&str, "1\n%s [= ASLOption control]\n", qstr);
+               len += 26;
+               free(qstr);
+       }
+
+       if (str == NULL) return NULL;
+
+       out = NULL;
+       qmin = 0;
+       cmax = 0;
+       sec.val[0] = -1;
+       sec.val[1] = -1;
+
+       res = NULL;
+       reslen = 0;
+       status = ASL_STATUS_OK;
+
+       kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE);
+       if (kstatus != KERN_SUCCESS) return NULL;
+
+       memmove(vmstr, str, len);
+       free(str);
+
+       status = 0;
+       kstatus = _asl_server_query(server_port, vmstr, len, qmin, 1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec);
+       if (kstatus != KERN_SUCCESS) return NULL;
+
+       if (res == NULL) return NULL;
+
+       out = asl_list_from_string(res);
+       vm_deallocate(mach_task_self(), (vm_address_t)res, reslen);
+
+       return out;
+}
+
+
+static CFTypeID __kSCLoggerTypeID = _kCFRuntimeNotATypeID;
+
+typedef  enum {
+       kModuleStatusEnabled,
+       kModuleStatusDisabled,
+       kModuleStatusDoesNotExist
+} ModuleStatus;
+
+struct SCLogger
+{
+       CFRuntimeBase           cf_base;
+
+       char *                  loggerID;       // LoggerID
+       SCLoggerFlags           flags;
+       aslclient               aslc;
+       aslmsg                  aslm;
+       ModuleStatus            module_status;
+       pthread_mutex_t         lock;
+};
+
+
+static void __SCLoggerDeallocate(CFTypeRef cf);
+static const CFRuntimeClass __SCLoggerClass = {
+       0,                              /* version */
+       "SCLogger",                     /* className */
+       NULL,                           /* init */
+       NULL,                           /* copy */
+       __SCLoggerDeallocate,           /* deallocate */
+       NULL,                           /* equal */
+       NULL,                           /* hash */
+       NULL,                           /* copyFormattingDesc */
+       NULL                            /* copyDebugDesc */
+};
+
+
+#define                DATETIMEBUFFERSIZE      32
+
+
+static pthread_once_t  registerLoggerOnce = PTHREAD_ONCE_INIT;
+static pthread_once_t  defaultLoggerOnce = PTHREAD_ONCE_INIT;
+
+typedef enum {
+       kLoggerASLControlEnableModule,
+       kLoggerASLControlDisableModule,
+       kLoggerASLControlLogFileCheckpoint
+} LoggerASLControl;
+
+static SCLoggerRef     defaultLogger = NULL;
+static SCLoggerRef     __SCLoggerCreate(void);
+static void            __SCLoggerDefaultLoggerInit();
+static SCLoggerRef     SCLoggerGetDefaultLogger();
+static void            SCLoggerSetLoggerID(SCLoggerRef logger, CFStringRef loggerID);
+static void            SCLoggerSendMessageToModuleOnly(SCLoggerRef logger, Boolean isPrivate);
+static void            SCLoggerSendASLControl(SCLoggerRef logger, LoggerASLControl control);
+static ModuleStatus    GetModuleStatus(const char * loggerID);
+
+static void
+__SCLoggerRegisterClass(void)
+{
+       if (__kSCLoggerTypeID == _kCFRuntimeNotATypeID) {
+               __kSCLoggerTypeID = _CFRuntimeRegisterClass(&__SCLoggerClass);
+       }
+       return;
+}
+
+static SCLoggerRef
+__SCLoggerAllocate(CFAllocatorRef allocator)
+{
+       SCLoggerRef state;
+       int size;
+
+       pthread_once(&registerLoggerOnce, __SCLoggerRegisterClass);
+
+       size = sizeof(*state) - sizeof(CFRuntimeBase);
+       state = (SCLoggerRef) _CFRuntimeCreateInstance(allocator,
+                                                      __kSCLoggerTypeID,
+                                                      size,
+                                                      NULL);
+       bzero((void*)state + sizeof(CFRuntimeBase), size);
+       return (state);
+}
+
+static void
+__SCLoggerDeallocate(CFTypeRef cf)
+{
+       SCLoggerRef logger = (SCLoggerRef)cf;
+
+       if (logger != NULL) {
+               // Rotate on close behavior
+               if (logger->module_status != kModuleStatusDoesNotExist) {
+                       SCLoggerSendASLControl(logger,
+                                              kLoggerASLControlLogFileCheckpoint);
+               }
+               if (logger->loggerID != NULL) {
+                       CFAllocatorDeallocate(NULL, logger->loggerID);
+                       logger->loggerID = NULL;
+               }
+               if (logger->aslm != NULL) {
+                       asl_free(logger->aslm);
+                       logger->aslm = NULL;
+               }
+               if (logger->aslc != NULL) {
+                       asl_close(logger->aslc);
+                       logger->aslc = NULL;
+               }
+       }
+}
+
+static SCLoggerRef
+__SCLoggerCreate(void)
+{
+       SCLoggerRef tempLogger = NULL;
+
+       tempLogger = __SCLoggerAllocate(kCFAllocatorDefault);
+       tempLogger->loggerID = NULL;
+       tempLogger->flags = kSCLoggerFlagsDefault;
+       tempLogger->aslc = asl_open(NULL, NULL, ASL_OPT_NO_DELAY);
+       tempLogger->aslm = asl_new(ASL_TYPE_MSG);
+       pthread_mutex_init(&(tempLogger->lock), NULL);
+       tempLogger->module_status = kModuleStatusDoesNotExist;
+
+       return tempLogger;
+}
+
+SCLoggerFlags
+SCLoggerGetFlags(SCLoggerRef logger)
+{
+       return logger->flags;
+}
+
+void
+SCLoggerSetFlags(SCLoggerRef logger, SCLoggerFlags flags)
+{
+       if (logger == defaultLogger) {
+               return;
+       }
+       pthread_mutex_lock(&(logger->lock));
+       if (flags != kSCLoggerFlagsNone) {
+               logger->module_status = GetModuleStatus(logger->loggerID);
+               if (logger->module_status == kModuleStatusDoesNotExist) {
+                       goto done;
+               }
+               if ((flags & kSCLoggerFlagsFile) != 0) {
+                       if ((logger->flags & kSCLoggerFlagsFile) == 0) {
+                               // Enable the module if disabled
+                               if (logger->module_status == kModuleStatusDisabled) {
+                                       SCLoggerSendASLControl(logger, kLoggerASLControlEnableModule);
+                               }
+                               // Setting ASL Filter level to debug
+                               asl_set_filter(logger->aslc, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
+                               if (logger->loggerID != NULL) {
+                                       asl_set(logger->aslm, kLoggerID,
+                                               logger->loggerID);
+                               }
+                       }
+               }
+               else if ((logger->flags & kSCLoggerFlagsFile) != 0) {
+                       asl_unset(logger->aslm, kLoggerID);
+                       asl_set_filter(logger->aslc, ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE));
+                       SCLoggerSendMessageToModuleOnly(logger, false);
+               }
+               if ((flags & kSCLoggerFlagsDefault) != 0) {
+                       if ((logger->flags & kSCLoggerFlagsDefault) == 0) {
+                               SCLoggerSendMessageToModuleOnly(logger, false);
+                       }
+               }
+               else if ((logger->flags & kSCLoggerFlagsDefault) != 0) {
+                       SCLoggerSendMessageToModuleOnly(logger, true);
+               }
+       }
+       logger->flags = flags;
+   done:
+       pthread_mutex_unlock(&(logger->lock));
+}
+
+
+static void
+SCLoggerSetLoggerID(SCLoggerRef logger, CFStringRef loggerID)
+{
+       logger->loggerID
+               = _SC_cfstring_to_cstring(loggerID, NULL, 0,
+                                         kCFStringEncodingUTF8);
+       // Enable the module if disabled
+       logger->module_status = GetModuleStatus(logger->loggerID);
+       if (logger->module_status == kModuleStatusDisabled) {
+               SCLoggerSendASLControl(logger, kLoggerASLControlEnableModule);
+       }
+}
+
+static ModuleStatus
+GetModuleStatus(const char * loggerID)
+{
+       aslresponse response = NULL;
+       aslmsg responseMessage = NULL;
+       ModuleStatus moduleStatus = kModuleStatusDoesNotExist;
+       const char* value = NULL;
+
+       if (loggerID != NULL) {
+               response = _asl_control_query(NULL);
+               if (response == NULL) {
+                       goto done;
+               }
+               responseMessage = aslresponse_next(response);
+               if (responseMessage == NULL) {
+                       goto done;
+               }
+               value = asl_get(responseMessage, loggerID);
+               if (value == NULL) {
+                       moduleStatus = kModuleStatusDoesNotExist;
+                       goto done;
+               }
+
+               if (strcmp(value, "enabled") == 0) {
+                       moduleStatus = kModuleStatusEnabled;
+               }
+               else {
+                       moduleStatus = kModuleStatusDisabled;
+               }
+       }
+done:
+       if (response != NULL) {
+               aslresponse_free(response);
+       }
+
+       return moduleStatus;
+}
+
+static void
+SCLoggerSendMessageToModuleOnly(SCLoggerRef logger, Boolean isPrivate)
+{
+       if (isPrivate) {
+               asl_set(logger->aslm, kASLModule, logger->loggerID);
+       }
+       else {
+               if (asl_get(logger->aslm, kASLModule) != NULL) {
+                       asl_unset(logger->aslm, kASLModule);
+               }
+       }
+}
+
+static void
+SCLoggerSendASLControl(SCLoggerRef logger, LoggerASLControl control)
+{
+       SCLoggerRef defLogger = SCLoggerGetDefaultLogger();
+       pthread_mutex_lock(&(defLogger->lock));
+
+       // this next line turns the asl_log()'s that follow into control messages
+       asl_set(defLogger->aslm, kASLOption, "control");
+
+       switch (control) {
+               case kLoggerASLControlEnableModule:
+                       asl_log(defLogger->aslc, defLogger->aslm,
+                               ASL_LEVEL_NOTICE, "@ %s enable 1",
+                               logger->loggerID);
+                       break;
+               case kLoggerASLControlDisableModule:
+                       asl_log(defLogger->aslc, defLogger->aslm,
+                               ASL_LEVEL_NOTICE, "@ %s enable 0",
+                               logger->loggerID);
+                       break;
+               case kLoggerASLControlLogFileCheckpoint:
+                       asl_log(defLogger->aslc, defLogger->aslm,
+                               ASL_LEVEL_NOTICE, "@ %s checkpoint",
+                               logger->loggerID);
+                       break;
+               default:
+                       break;
+       }
+
+       // turn off control mode
+       asl_unset(defLogger->aslm, kASLOption);
+       pthread_mutex_unlock(&defLogger->lock);
+       return;
+}
+
+SCLoggerRef
+SCLoggerCreate(CFStringRef loggerID)
+{
+       SCLoggerRef logger = NULL;
+
+       logger = __SCLoggerCreate();
+       if (loggerID != NULL) {
+               SCLoggerSetLoggerID(logger, loggerID);
+       }
+       SCLoggerSetFlags(logger, kSCLoggerFlagsDefault);
+       return logger;
+}
+
+static void
+__SCLoggerDefaultLoggerInit()
+{
+       if (defaultLogger == NULL) {
+               defaultLogger = __SCLoggerCreate();
+               defaultLogger->flags = kSCLoggerFlagsDefault;
+       }
+}
+
+static SCLoggerRef
+SCLoggerGetDefaultLogger()
+{
+       pthread_once(&defaultLoggerOnce, __SCLoggerDefaultLoggerInit);
+       return defaultLogger;
+}
+
+void
+SCLoggerVLog(SCLoggerRef logger, int loglevel, CFStringRef formatString,
+            va_list args)
+{
+       aslclient       aslc;
+       aslmsg          aslm;
+
+       if (logger == NULL
+           || logger->module_status == kModuleStatusDoesNotExist) {
+               logger = SCLoggerGetDefaultLogger();
+       }
+       pthread_mutex_lock(&(logger->lock));
+       if (logger->flags == kSCLoggerFlagsNone) {
+               pthread_mutex_unlock(&(logger->lock));
+               return;
+       }
+       aslc = logger->aslc;
+       aslm = logger->aslm;
+       __SCLog(aslc, aslm, loglevel, formatString, args);
+       pthread_mutex_unlock(&(logger->lock));
+       return;
+}
+
+void
+SCLoggerLog(SCLoggerRef logger, int loglevel, CFStringRef formatString, ...)
+{
+       va_list args;
+
+       va_start(args, formatString);
+       SCLoggerVLog(logger, loglevel, formatString, args);
+       va_end(args);
+
+       return;
+}
+
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+
 #pragma mark -
 #pragma mark SC error handling / logging
 
 #pragma mark -
 #pragma mark SC error handling / logging
 
@@ -618,6 +1049,7 @@ static const struct sc_errmsg {
        char    *message;
 } sc_errmsgs[] = {
        { kSCStatusAccessError,         "Permission denied" },
        char    *message;
 } sc_errmsgs[] = {
        { kSCStatusAccessError,         "Permission denied" },
+       { kSCStatusConnectionIgnore,    "Network connection information not available at this time" },
        { kSCStatusConnectionNoService, "Network service for connection not available" },
        { kSCStatusFailed,              "Failed!" },
        { kSCStatusInvalidArgument,     "Invalid argument" },
        { kSCStatusConnectionNoService, "Network service for connection not available" },
        { kSCStatusFailed,              "Failed!" },
        { kSCStatusInvalidArgument,     "Invalid argument" },
@@ -639,7 +1071,6 @@ static const struct sc_errmsg {
 };
 #define nSC_ERRMSGS (sizeof(sc_errmsgs)/sizeof(struct sc_errmsg))
 
 };
 #define nSC_ERRMSGS (sizeof(sc_errmsgs)/sizeof(struct sc_errmsg))
 
-
 void
 _SCErrorSet(int error)
 {
 void
 _SCErrorSet(int error)
 {
@@ -689,7 +1120,7 @@ SCCopyLastError(void)
 
        domain = kCFErrorDomainMach;
 
 
        domain = kCFErrorDomainMach;
 
-    done :
+       done :
 
        error = CFErrorCreate(NULL, domain, code, userInfo);
        if (userInfo != NULL) CFRelease(userInfo);
 
        error = CFErrorCreate(NULL, domain, code, userInfo);
        if (userInfo != NULL) CFRelease(userInfo);
index 2652bc421619dab71e935d6e14d46323311105c9..02e7d48911fb7f11382af001d486c667a7197e71 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2005, 2008-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2008-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -88,16 +88,6 @@ rlsCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 }
 
 
 }
 
 
-static void
-portInvalidate(CFMachPortRef port, void *info) {
-       mach_port_t     mp      = CFMachPortGetPort(port);
-
-       __MACH_PORT_DEBUG(TRUE, "*** portInvalidate", mp);
-       /* remove our receive right  */
-       (void)mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1);
-}
-
-
 static void
 rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode)
 {
 static void
 rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode)
 {
@@ -200,10 +190,9 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode)
 
                __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule (after notifyviaport)", port);
                storePrivate->rlsNotifyPort = _SC_CFMachPortCreateWithPort("SCDynamicStore",
 
                __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule (after notifyviaport)", port);
                storePrivate->rlsNotifyPort = _SC_CFMachPortCreateWithPort("SCDynamicStore",
-                                                                    port,
-                                                                    rlsCallback,
-                                                                    &context);
-               CFMachPortSetInvalidationCallBack(storePrivate->rlsNotifyPort, portInvalidate);
+                                                                          port,
+                                                                          rlsCallback,
+                                                                          &context);
                storePrivate->rlsNotifyRLS = CFMachPortCreateRunLoopSource(NULL, storePrivate->rlsNotifyPort, 0);
 
                storePrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                storePrivate->rlsNotifyRLS = CFMachPortCreateRunLoopSource(NULL, storePrivate->rlsNotifyPort, 0);
 
                storePrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -278,13 +267,20 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode)
                }
 
                if (storePrivate->rlsNotifyPort != NULL) {
                }
 
                if (storePrivate->rlsNotifyPort != NULL) {
-                       /* invalidate port */
+                       mach_port_t     mp;
+
+                       mp = CFMachPortGetPort(storePrivate->rlsNotifyPort);
                        __MACH_PORT_DEBUG((storePrivate->rlsNotifyPort != NULL),
                        __MACH_PORT_DEBUG((storePrivate->rlsNotifyPort != NULL),
-                                         "*** rlsCancel (before invalidating CFMachPort)",
-                                         CFMachPortGetPort(storePrivate->rlsNotifyPort));
+                                         "*** rlsCancel (before invalidating/releasing CFMachPort)",
+                                         mp);
+
+                       /* invalidate and release port */
                        CFMachPortInvalidate(storePrivate->rlsNotifyPort);
                        CFRelease(storePrivate->rlsNotifyPort);
                        storePrivate->rlsNotifyPort = NULL;
                        CFMachPortInvalidate(storePrivate->rlsNotifyPort);
                        CFRelease(storePrivate->rlsNotifyPort);
                        storePrivate->rlsNotifyPort = NULL;
+
+                       /* and, finally, remove our receive right  */
+                       (void)mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1);
                }
 
                if (storePrivate->server != MACH_PORT_NULL) {
                }
 
                if (storePrivate->server != MACH_PORT_NULL) {
@@ -343,8 +339,10 @@ rlsPerform(void *info)
                context_info    = storePrivate->rlsContext.info;
                context_release = NULL;
        }
                context_info    = storePrivate->rlsContext.info;
                context_release = NULL;
        }
-       (*rlsFunction)(store, changedKeys, context_info);
-       if (context_release) {
+       if (rlsFunction != NULL) {
+               (*rlsFunction)(store, changedKeys, context_info);
+       }
+       if (context_release != NULL) {
                context_release(context_info);
        }
 
                context_release(context_info);
        }
 
index c8090bb04b28a5cfc93d855df3f592656cac4c07..abe97272b3f3de1f435868857d63780ad3f6878b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2006, 2008-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -73,7 +73,7 @@ __SCDynamicStoreCopyDescription(CFTypeRef cf) {
        result = CFStringCreateMutable(allocator, 0);
        CFStringAppendFormat(result, NULL, CFSTR("<SCDynamicStore %p [%p]> {"), cf, allocator);
        if (storePrivate->server != MACH_PORT_NULL) {
        result = CFStringCreateMutable(allocator, 0);
        CFStringAppendFormat(result, NULL, CFSTR("<SCDynamicStore %p [%p]> {"), cf, allocator);
        if (storePrivate->server != MACH_PORT_NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR("server port = %p"), storePrivate->server);
+               CFStringAppendFormat(result, NULL, CFSTR("server port = 0x%x"), storePrivate->server);
        } else {
                CFStringAppendFormat(result, NULL, CFSTR("server not (no longer) available"));
        }
        } else {
                CFStringAppendFormat(result, NULL, CFSTR("server not (no longer) available"));
        }
@@ -236,25 +236,27 @@ __SCDynamicStoreInitialize(void)
 
 
 static mach_port_t
 
 
 static mach_port_t
-__SCDynamicStoreServerPort(kern_return_t *status)
+__SCDynamicStoreServerPort(SCDynamicStorePrivateRef storePrivate, kern_return_t *status)
 {
        mach_port_t     server  = MACH_PORT_NULL;
        char            *server_name;
 
        server_name = getenv("SCD_SERVER");
 {
        mach_port_t     server  = MACH_PORT_NULL;
        char            *server_name;
 
        server_name = getenv("SCD_SERVER");
-       if (!server_name) {
+
+
+       if (server_name == NULL) {
                server_name = SCD_SERVER;
        }
 
                server_name = SCD_SERVER;
        }
 
-#ifdef BOOTSTRAP_PRIVILEGED_SERVER
+#if    defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR
        *status = bootstrap_look_up2(bootstrap_port,
                                     server_name,
                                     &server,
                                     0,
                                     BOOTSTRAP_PRIVILEGED_SERVER);
        *status = bootstrap_look_up2(bootstrap_port,
                                     server_name,
                                     &server,
                                     0,
                                     BOOTSTRAP_PRIVILEGED_SERVER);
-#else  // BOOTSTRAP_PRIVILEGED_SERVER
+#else  // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR
        *status = bootstrap_look_up(bootstrap_port, server_name, &server);
        *status = bootstrap_look_up(bootstrap_port, server_name, &server);
-#endif // BOOTSTRAP_PRIVILEGED_SERVER
+#endif // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR
 
        switch (*status) {
                case BOOTSTRAP_SUCCESS :
 
        switch (*status) {
                case BOOTSTRAP_SUCCESS :
@@ -363,6 +365,31 @@ __SCDynamicStoreCreatePrivate(CFAllocatorRef               allocator,
 }
 
 
 }
 
 
+static void
+updateServerPort(SCDynamicStorePrivateRef storePrivate, mach_port_t *server, int *sc_status_p)
+{
+       pthread_mutex_lock(&_sc_lock);
+       if (_sc_server != MACH_PORT_NULL) {
+               if (*server == _sc_server) {
+                       // if the server we tried returned the error, deallocate
+                       // our send [or dead name] right
+                       (void)mach_port_deallocate(mach_task_self(), _sc_server);
+
+                       // and [re-]lookup the name to the server
+                       _sc_server = __SCDynamicStoreServerPort(storePrivate, sc_status_p);
+               } else {
+                       // another thread has refreshed the SCDynamicStore server port
+               }
+       } else {
+               _sc_server = __SCDynamicStoreServerPort(storePrivate, sc_status_p);
+       }
+       *server = _sc_server;
+       pthread_mutex_unlock(&_sc_lock);
+
+       return;
+}
+
+
 static Boolean
 __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate)
 {
 static Boolean
 __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate)
 {
@@ -390,6 +417,11 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate)
 
        /* open a new session with the server */
        server = _sc_server;
 
        /* open a new session with the server */
        server = _sc_server;
+
+
+       updateServerPort(storePrivate, &server, &sc_status);
+
+
        while (TRUE) {
                if (server != MACH_PORT_NULL) {
                        if (!storePrivate->serverNullSession) {
        while (TRUE) {
                if (server != MACH_PORT_NULL) {
                        if (!storePrivate->serverNullSession) {
@@ -427,23 +459,8 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate)
                        }
                }
 
                        }
                }
 
-               pthread_mutex_lock(&_sc_lock);
-               if (_sc_server != MACH_PORT_NULL) {
-                       if (server == _sc_server) {
-                               // if the server we tried returned the error, deallocate
-                               // our send [or dead name] right
-                               (void)mach_port_deallocate(mach_task_self(), _sc_server);
 
 
-                               // and [re-]lookup the name to the server
-                               _sc_server = __SCDynamicStoreServerPort(&sc_status);
-                       } else {
-                               // another thread has refreshed the SCDynamicStore server port
-                       }
-               } else {
-                       _sc_server = __SCDynamicStoreServerPort(&sc_status);
-               }
-               server = _sc_server;
-               pthread_mutex_unlock(&_sc_lock);
+               updateServerPort(storePrivate, &server, &sc_status);
 
                if (server == MACH_PORT_NULL) {
                        // if SCDynamicStore server not available
 
                if (server == MACH_PORT_NULL) {
                        // if SCDynamicStore server not available
@@ -495,6 +512,7 @@ __SCDynamicStoreNullSession(void)
                                                             CFSTR("NULL session"),
                                                             NULL,
                                                             NULL);
                                                             CFSTR("NULL session"),
                                                             NULL,
                                                             NULL);
+               assert(storePrivate != NULL);
                storePrivate->server = _sc_server;
                storePrivate->serverNullSession = TRUE;
 #else
                storePrivate->server = _sc_server;
                storePrivate->serverNullSession = TRUE;
 #else
@@ -508,6 +526,7 @@ __SCDynamicStoreNullSession(void)
                                                             CFSTR("Thread local session"),
                                                             NULL,
                                                             NULL);
                                                             CFSTR("Thread local session"),
                                                             NULL,
                                                             NULL);
+               assert(storePrivate != NULL);
                /*
                 * Use MACH_PORT_NULL here to trigger the call to
                 * __SCDynamicStoreAddSession below.
                /*
                 * Use MACH_PORT_NULL here to trigger the call to
                 * __SCDynamicStoreAddSession below.
@@ -732,6 +751,7 @@ __SCDynamicStoreReconnectNotifications(SCDynamicStoreRef store)
 const CFStringRef      kSCDynamicStoreUseSessionKeys   = CFSTR("UseSessionKeys");      /* CFBoolean */
 
 
 const CFStringRef      kSCDynamicStoreUseSessionKeys   = CFSTR("UseSessionKeys");      /* CFBoolean */
 
 
+
 SCDynamicStoreRef
 SCDynamicStoreCreateWithOptions(CFAllocatorRef         allocator,
                                CFStringRef             name,
 SCDynamicStoreRef
 SCDynamicStoreCreateWithOptions(CFAllocatorRef         allocator,
                                CFStringRef             name,
@@ -756,7 +776,10 @@ SCDynamicStoreCreateWithOptions(CFAllocatorRef             allocator,
        }
 
        // set "options"
        }
 
        // set "options"
-       storePrivate->options = (storeOptions != NULL) ? CFRetain(storeOptions) : NULL;
+
+       if (storeOptions != NULL) {
+               storePrivate->options = CFRetain(storeOptions);
+       }
 
        // establish SCDynamicStore session
        ok = __SCDynamicStoreAddSession(storePrivate);
 
        // establish SCDynamicStore session
        ok = __SCDynamicStoreAddSession(storePrivate);
index 8431f3c4e3620d3c7bbd6d2489e572fbbc049b57..926500f98a1a91eae3a2ba72a43348451340f52c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2006, 2013 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -278,11 +278,22 @@ _SCDPluginExecCommand2(SCDPluginExecCallBack      callout,
                       void                     *setupContext
                       )
 {
                       void                     *setupContext
                       )
 {
-       pid_t   pid;
+       char            buf[1024];
+       pid_t           pid;
+       struct passwd   pwd;
+       struct passwd   *result = NULL;
+       char            *username = NULL;
 
        // grab the activeChildren mutex
        pthread_mutex_lock(&lock);
 
 
        // grab the activeChildren mutex
        pthread_mutex_lock(&lock);
 
+       // cache the getpwuid_r result here to avoid spinning that can happen
+       // when calling it between fork and execv.
+       if ((getpwuid_r(uid, &pwd, buf, sizeof(buf), &result) == 0) &&
+           (result != NULL)) {
+               username = result->pw_name;
+       }
+
        // if needed, initialize
        if (childReaped == NULL) {
                _SCDPluginExecInit();
        // if needed, initialize
        if (childReaped == NULL) {
                _SCDPluginExecInit();
@@ -325,15 +336,8 @@ _SCDPluginExecCommand2(SCDPluginExecCallBack       callout,
                                (void) setgid(gid);
                        }
 
                                (void) setgid(gid);
                        }
 
-                       if ((euid != uid) || (egid != gid)) {
-                               char            buf[1024];
-                               struct passwd   pwd;
-                               struct passwd   *result = NULL;
-
-                               if ((getpwuid_r(uid, &pwd, buf, sizeof(buf), &result) == 0) &&
-                                   (result != NULL)) {
-                                       initgroups(result->pw_name, gid);
-                               }
+                       if (((euid != uid) || (egid != gid)) && username) {
+                               initgroups(username, gid);
                        }
 
                        if (euid != uid) {
                        }
 
                        if (euid != uid) {
index 0f3e346debc02b366815683f6a43a8d93d972dd8..5610bb7d10ccf793a0cb63345cf5d075ed5e1b64 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -41,6 +41,7 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <netinet/in.h>
@@ -56,9 +57,9 @@
 #include <dlfcn.h>
 
 
 #include <dlfcn.h>
 
 
-#if    TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#if    TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 #include <CoreFoundation/CFUserNotification.h>
 #include <CoreFoundation/CFUserNotification.h>
-#endif // TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 
 #define        N_QUICK 32
 
 
 #define        N_QUICK 32
 
@@ -161,15 +162,6 @@ _SC_sockaddr_to_string(const struct sockaddr *address, char *buf, size_t bufLen)
                        }
                        break;
                }
                        }
                        break;
                }
-               case AF_LINK :
-                       if (addr.sdl->sdl_len < bufLen) {
-                               bufLen = addr.sdl->sdl_len;
-                       } else {
-                               bufLen = bufLen - 1;
-                       }
-
-                       bcopy(addr.sdl->sdl_data, buf, bufLen);
-                       break;
                default :
                        snprintf(buf, bufLen, "unexpected address family %d", address->sa_family);
                        break;
                default :
                        snprintf(buf, bufLen, "unexpected address family %d", address->sa_family);
                        break;
@@ -542,6 +534,7 @@ _SCUnserializeData(CFDataRef *data, void *dataRef, CFIndex dataLen)
 CF_RETURNS_RETAINED CFDictionaryRef
 _SCSerializeMultiple(CFDictionaryRef dict)
 {
 CF_RETURNS_RETAINED CFDictionaryRef
 _SCSerializeMultiple(CFDictionaryRef dict)
 {
+       CFIndex                 i;
        const void *            keys_q[N_QUICK];
        const void **           keys            = keys_q;
        CFIndex                 nElements;
        const void *            keys_q[N_QUICK];
        const void **           keys            = keys_q;
        CFIndex                 nElements;
@@ -553,17 +546,16 @@ _SCSerializeMultiple(CFDictionaryRef dict)
 
        nElements = CFDictionaryGetCount(dict);
        if (nElements > 0) {
 
        nElements = CFDictionaryGetCount(dict);
        if (nElements > 0) {
-               CFIndex i;
-
                if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
                        keys   = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
                        values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
                if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
                        keys   = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
                        values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
-                       pLists = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+                       pLists = CFAllocatorAllocate(NULL, nElements * sizeof(CFDataRef), 0);
                }
                }
-               bzero(pLists, nElements * sizeof(CFTypeRef));
+               bzero(pLists, nElements * sizeof(CFDataRef));
 
                CFDictionaryGetKeysAndValues(dict, keys, values);
                for (i = 0; i < nElements; i++) {
 
                CFDictionaryGetKeysAndValues(dict, keys, values);
                for (i = 0; i < nElements; i++) {
+                       pLists[i] = NULL;
                        if (!_SCSerialize((CFPropertyListRef)values[i], (CFDataRef *)&pLists[i], NULL, NULL)) {
                                goto done;
                        }
                        if (!_SCSerialize((CFPropertyListRef)values[i], (CFDataRef *)&pLists[i], NULL, NULL)) {
                                goto done;
                        }
@@ -580,10 +572,8 @@ _SCSerializeMultiple(CFDictionaryRef dict)
     done :
 
        if (nElements > 0) {
     done :
 
        if (nElements > 0) {
-               CFIndex i;
-
                for (i = 0; i < nElements; i++) {
                for (i = 0; i < nElements; i++) {
-                       if (pLists[i])  CFRelease(pLists[i]);
+                       if (pLists[i] != NULL)  CFRelease((CFDataRef)pLists[i]);
                }
 
                if (keys != keys_q) {
                }
 
                if (keys != keys_q) {
@@ -892,6 +882,7 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString
 {
        CFDataRef       data    = NULL;
        SInt32          errCode = 0;
 {
        CFDataRef       data    = NULL;
        SInt32          errCode = 0;
+       Boolean         ok;
        CFURLRef        resourcesURL;
        CFStringRef     str     = NULL;
        CFURLRef        url;
        CFURLRef        resourcesURL;
        CFStringRef     str     = NULL;
        CFURLRef        url;
@@ -921,12 +912,16 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString
                CFRelease(fileName);
                CFRelease(resourcesURL);
 
                CFRelease(fileName);
                CFRelease(resourcesURL);
 
-               if (!CFURLCreateDataAndPropertiesFromResource(NULL,
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+               ok = CFURLCreateDataAndPropertiesFromResource(NULL,
                                                              url,
                                                              &data,
                                                              NULL,
                                                              NULL,
                                                              url,
                                                              &data,
                                                              NULL,
                                                              NULL,
-                                                             &errCode)) {
+                                                             &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
                        /*
                         * Failed to get the data using a manually-constructed URL
                         * for the given strings table. Fall back to using
@@ -944,12 +939,16 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString
                                                             NULL,
                                                             CFSTR("English"));
                if (url != NULL) {
                                                             NULL,
                                                             CFSTR("English"));
                if (url != NULL) {
-                       if (!CFURLCreateDataAndPropertiesFromResource(NULL,
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+                       ok = CFURLCreateDataAndPropertiesFromResource(NULL,
                                                                      url,
                                                                      &data,
                                                                      NULL,
                                                                      NULL,
                                                                      url,
                                                                      &data,
                                                                      NULL,
                                                                      NULL,
-                                                                     &errCode)) {
+                                                                     &errCode);
+#pragma GCC diagnostic pop
+                       if (!ok) {
                                data = NULL;
                        }
                        CFRelease(url);
                                data = NULL;
                        }
                        CFRelease(url);
@@ -1018,7 +1017,8 @@ _SC_CFMachPortCreateWithPort(const char           *portDescription,
                                                       portDescription);
                }
                crash_info = _SC_cfstring_to_cstring(err, NULL, 0, kCFStringEncodingASCII);
                                                       portDescription);
                }
                crash_info = _SC_cfstring_to_cstring(err, NULL, 0, kCFStringEncodingASCII);
-               CFRelease(err);
+               if (err != NULL) CFRelease(err);
+
 
                err = CFStringCreateWithFormat(NULL,
                                               NULL,
 
                err = CFStringCreateWithFormat(NULL,
                                               NULL,
@@ -1197,7 +1197,7 @@ _SC_logMachPortReferences(const char *str, mach_port_t port)
                static int      is_configd      = -1;
 
                if (is_configd == -1) {
                static int      is_configd      = -1;
 
                if (is_configd == -1) {
-                       is_configd = (strcmp(getprogname(), "configd") == 0);
+                       is_configd = (strcmp(getprogname(), _SC_SERVER_PROG) == 0);
                }
                if (is_configd == 1) {
                        // if "configd", add indication if this is the M[ain] or [P]lugin thread
                }
                if (is_configd == 1) {
                        // if "configd", add indication if this is the M[ain] or [P]lugin thread
@@ -1359,11 +1359,11 @@ asm(".desc ___crashreporter_info__, 0x10");
 static Boolean
 _SC_SimulateCrash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMessage)
 {
 static Boolean
 _SC_SimulateCrash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMessage)
 {
-       Boolean ok                                                                                      = FALSE;
+       Boolean ok      = FALSE;
 
 #if ! TARGET_IPHONE_SIMULATOR
        static bool     (*dyfunc_SimulateCrash)(pid_t, mach_exception_data_type_t, CFStringRef) = NULL;
 
 #if ! TARGET_IPHONE_SIMULATOR
        static bool     (*dyfunc_SimulateCrash)(pid_t, mach_exception_data_type_t, CFStringRef) = NULL;
-       static void     *image                                                                                  = NULL;
+       static void     *image                                                                  = NULL;
 
        if ((dyfunc_SimulateCrash == NULL) && (image == NULL)) {
                const char      *framework      = "/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport";
 
        if ((dyfunc_SimulateCrash == NULL) && (image == NULL)) {
                const char      *framework      = "/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport";
@@ -1394,28 +1394,30 @@ _SC_SimulateCrash(const char *crash_info, CFStringRef notifyHeader, CFStringRef
                CFRelease(str);
        }
 
                CFRelease(str);
        }
 
-#if    TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
-       if (ok) {
+#if    TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
+       if (ok && (notifyHeader != NULL) && (notifyMessage != NULL)) {
                static Boolean  warned  = FALSE;
 
                if (!warned) {
                static Boolean  warned  = FALSE;
 
                if (!warned) {
-                       notifyMessage = CFStringCreateWithFormat(NULL,
-                                                                NULL,
-                                                                CFSTR("%@\n\nPlease collect the crash report and file a Radar."),
-                                                                notifyMessage);
+                       CFStringRef     displayMessage;
+
+                       displayMessage = CFStringCreateWithFormat(NULL,
+                                                                 NULL,
+                                                                 CFSTR("%@\n\nPlease collect the crash report and file a Radar."),
+                                                                 notifyMessage);
                        CFUserNotificationDisplayNotice(0,
                                                        kCFUserNotificationStopAlertLevel,
                                                        NULL,
                                                        NULL,
                                                        NULL,
                                                        notifyHeader,
                        CFUserNotificationDisplayNotice(0,
                                                        kCFUserNotificationStopAlertLevel,
                                                        NULL,
                                                        NULL,
                                                        NULL,
                                                        notifyHeader,
-                                                       notifyMessage,
+                                                       displayMessage,
                                                        NULL);
                                                        NULL);
-                       CFRelease(notifyMessage);
+                       CFRelease(displayMessage);
                        warned = TRUE;
                }
        }
                        warned = TRUE;
                }
        }
-#endif // TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 #endif /* ! TARGET_IPHONE_SIMULATOR */
 
        return ok;
 #endif /* ! TARGET_IPHONE_SIMULATOR */
 
        return ok;
@@ -1447,3 +1449,41 @@ _SC_crash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMe
        __crashreporter_info__ = NULL;
        return;
 }
        __crashreporter_info__ = NULL;
        return;
 }
+
+
+Boolean
+_SC_getconninfo(int socket, struct sockaddr_storage *src_addr, struct sockaddr_storage *dest_addr, int *if_index, uint32_t *flags)
+{
+       struct so_cinforeq      request;
+
+       memset(&request, 0, sizeof(request));
+
+       if (src_addr != NULL) {
+               memset(src_addr, 0, sizeof(*src_addr));
+               request.scir_src = (struct sockaddr *)src_addr;
+               request.scir_src_len = sizeof(*src_addr);
+       }
+
+       if (dest_addr != NULL) {
+               memset(dest_addr, 0, sizeof(*dest_addr));
+               request.scir_dst = (struct sockaddr *)dest_addr;
+               request.scir_dst_len = sizeof(*dest_addr);
+       }
+
+       if (ioctl(socket, SIOCGCONNINFO, &request) != 0) {
+               SCLog(TRUE, LOG_WARNING, CFSTR("SIOCGCONNINFO failed: %s"), strerror(errno));
+               return FALSE;
+       }
+
+       if (if_index != NULL) {
+               *if_index = 0;
+               *if_index = request.scir_ifindex;
+       }
+
+       if (flags != NULL) {
+               *flags = 0;
+               *flags = request.scir_flags;
+       }
+
+       return TRUE;
+}
index 7682d42d41f6078bfa3d4d4e39e6eeebfe03364b..66148ea92b0131fe5c4437daa2290f4d3b990018 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2001, 2002, 2004, 2005, 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2001, 2002, 2004, 2005, 2008, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -106,11 +106,11 @@ DHCPInfoGetLeaseStartTime (CFDictionaryRef        info)           __OSX_AVAILABLE_STARTING(__MAC
                NULL if the lease is infinite i.e. has no expiration, or the
                configuration method is not DHCP. An infinite lease can be determined
                by a non-NULL lease start time (see DHCPInfoGetLeaseStartTime above).
                NULL if the lease is infinite i.e. has no expiration, or the
                configuration method is not DHCP. An infinite lease can be determined
                by a non-NULL lease start time (see DHCPInfoGetLeaseStartTime above).
-        
+
                The return value must NOT be released.
 */
 CFDateRef
                The return value must NOT be released.
 */
 CFDateRef
-DHCPInfoGetLeaseExpirationTime (CFDictionaryRef        info)           __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_NA);
+DHCPInfoGetLeaseExpirationTime (CFDictionaryRef        info)           __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/);
 
 __END_DECLS
 
 
 __END_DECLS
 
index a32aa7fe6794784de58d849da51e2855e2f59417..b81fbfc2a31f0b9d90628e48ff8f101b67d87ae2 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2009-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
index af5a5cc1fd83d49b04391ed30317a4fbf3743d63..40acd63e98deab1aa5ae37f1fd9c77552f490664 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2004, 2005, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2005, 2010, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -109,6 +109,7 @@ typedef void (*SCDynamicStoreDisconnectCallBack)    (
                                                         );
 
 
                                                         );
 
 
+
 __BEGIN_DECLS
 
 /*!
 __BEGIN_DECLS
 
 /*!
index 2342887f6bf552cffa91404090f382a720ed744c..b90bb1a53eb8cb6609e1bf6ad3fa788bc153f3c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -72,6 +72,7 @@ __setPrefsConfiguration(SCPreferencesRef      prefs,
                        CFDictionaryRef         config,
                        Boolean                 keepInactive)
 {
                        CFDictionaryRef         config,
                        Boolean                 keepInactive)
 {
+       CFDictionaryRef         curConfig;
        CFMutableDictionaryRef  newConfig       = NULL;
        Boolean                 ok;
 
        CFMutableDictionaryRef  newConfig       = NULL;
        Boolean                 ok;
 
@@ -80,13 +81,13 @@ __setPrefsConfiguration(SCPreferencesRef    prefs,
                return FALSE;
        }
 
                return FALSE;
        }
 
+       curConfig = SCPreferencesPathGetValue(prefs, path);
+
        if (config != NULL) {
                newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
        }
 
        if (keepInactive) {
        if (config != NULL) {
                newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
        }
 
        if (keepInactive) {
-               CFDictionaryRef curConfig;
-
                if (config == NULL) {
                        newConfig = CFDictionaryCreateMutable(NULL,
                                                              0,
                if (config == NULL) {
                        newConfig = CFDictionaryCreateMutable(NULL,
                                                              0,
@@ -94,7 +95,6 @@ __setPrefsConfiguration(SCPreferencesRef      prefs,
                                                              &kCFTypeDictionaryValueCallBacks);
                }
 
                                                              &kCFTypeDictionaryValueCallBacks);
                }
 
-               curConfig = SCPreferencesPathGetValue(prefs, path);
                if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
                        // if currently disabled
                        CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
                if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
                        // if currently disabled
                        CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
@@ -105,7 +105,11 @@ __setPrefsConfiguration(SCPreferencesRef   prefs,
        }
 
        // set new configuration
        }
 
        // set new configuration
-       if (newConfig != NULL) {
+       if (_SC_CFEqual(curConfig, newConfig)) {
+               // if no change
+               if (newConfig != NULL) CFRelease(newConfig);
+               ok = TRUE;
+       } else if (newConfig != NULL) {
                // if new configuration (or we are preserving a disabled state)
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
                // if new configuration (or we are preserving a disabled state)
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
@@ -168,7 +172,11 @@ __setPrefsEnabled(SCPreferencesRef      prefs,
        }
 
        // set new configuration
        }
 
        // set new configuration
-       if (newConfig != NULL) {
+       if (_SC_CFEqual(curConfig, newConfig)) {
+               // if no change
+               if (newConfig != NULL) CFRelease(newConfig);
+               ok = TRUE;
+       } else if (newConfig != NULL) {
                // if updated configuration (or we are establishing as disabled)
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
                // if updated configuration (or we are establishing as disabled)
                ok = SCPreferencesPathSetValue(prefs, path, newConfig);
                CFRelease(newConfig);
@@ -203,7 +211,10 @@ __copyTemplates()
                return NULL;
        }
 
                return NULL;
        }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
        ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL);
        ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
        CFRelease(url);
        if (!ok || (xmlTemplates == NULL)) {
                return NULL;
        CFRelease(url);
        if (!ok || (xmlTemplates == NULL)) {
                return NULL;
index ba253f07a72dee446486f19c9478d960cfee3437..3075883ea0b40e818fea9d1a5208ff2347326414 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -73,6 +73,9 @@ typedef struct {
        // name
        CFStringRef             name;
 
        // name
        CFStringRef             name;
 
+       // external identifiers
+       CFMutableDictionaryRef  externalIDs;
+
 } SCNetworkServicePrivate, *SCNetworkServicePrivateRef;
 
 
 } SCNetworkServicePrivate, *SCNetworkServicePrivateRef;
 
 
@@ -143,6 +146,7 @@ typedef struct {
        uint64_t                entryID;
        CFMutableDictionaryRef  overrides;
        Boolean                 modemIsV92;
        uint64_t                entryID;
        CFMutableDictionaryRef  overrides;
        Boolean                 modemIsV92;
+       CFStringRef             prefix;
        CFNumberRef             type;
        CFNumberRef             unit;
        struct {
        CFNumberRef             type;
        CFNumberRef             unit;
        struct {
@@ -158,8 +162,8 @@ typedef struct {
        Boolean                 supportsBond;
        struct {
                CFArrayRef              interfaces;
        Boolean                 supportsBond;
        struct {
                CFArrayRef              interfaces;
-               CFDictionaryRef         options;
                CFNumberRef             mode;
                CFNumberRef             mode;
+               CFDictionaryRef         options;
        } bond;
 
        // for Bridge interfaces
        } bond;
 
        // for Bridge interfaces
@@ -221,13 +225,13 @@ CFArrayRef
 __SCNetworkInterfaceCopyDeepConfiguration       (SCNetworkSetRef       set,
                                                 SCNetworkInterfaceRef  interface);
 
 __SCNetworkInterfaceCopyDeepConfiguration       (SCNetworkSetRef       set,
                                                 SCNetworkInterfaceRef  interface);
 
-#if    !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#if    !TARGET_OS_IPHONE
 CFStringRef
 __SCNetworkInterfaceCopyXLocalizedDisplayName  (SCNetworkInterfaceRef  interface);
 
 CFStringRef
 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface);
 CFStringRef
 __SCNetworkInterfaceCopyXLocalizedDisplayName  (SCNetworkInterfaceRef  interface);
 
 CFStringRef
 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface);
-#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#endif // !TARGET_OS_IPHONE
 
 int
 __SCNetworkInterfaceCreateCapabilities         (SCNetworkInterfaceRef  interface,
 
 int
 __SCNetworkInterfaceCreateCapabilities         (SCNetworkInterfaceRef  interface,
index fb1987bf26fe730e5594ac437186183e3f6791aa..ddc8ba74a7153411f6594e2f41546cee12669fdc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -192,6 +192,14 @@ _SCNetworkInterfaceCopyActive                              (SCDynamicStoreRef              store,
 CFArrayRef /* of SCNetworkInterfaceRef's */
 _SCNetworkInterfaceCopyAllWithPreferences              (SCPreferencesRef               prefs)          __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/);
 
 CFArrayRef /* of SCNetworkInterfaceRef's */
 _SCNetworkInterfaceCopyAllWithPreferences              (SCPreferencesRef               prefs)          __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/);
 
+/*!
+       @function _SCNetworkInterfaceCopyBTPANInterface
+       @discussion Returns the SCNetworkInterface associated with the BT-PAN interface
+       @result The BT-PAN interface; NULL if the interface is not (yet) known.
+ */
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCopyBTPANInterface                  (void)                                          __OSX_AVAILABLE_STARTING(__MAC_10_8/*FIXME*/,__IPHONE_NA);
+
 /*!
        @function _SCNetworkInterfaceCopySlashDevPath
        @discussion Returns the /dev pathname for the interface.
 /*!
        @function _SCNetworkInterfaceCopySlashDevPath
        @discussion Returns the /dev pathname for the interface.
@@ -311,6 +319,16 @@ _SCNetworkInterfaceGetConfigurationAction          (SCNetworkInterfaceRef          interface)      __
 CFDataRef
 _SCNetworkInterfaceGetHardwareAddress                  (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
 
 CFDataRef
 _SCNetworkInterfaceGetHardwareAddress                  (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
 
+/*!
+       @function _SCNetworkInterfaceGetIOInterfaceNamePrefix
+       @discussion Returns the IOInterfaceNamePrefix for the interface.
+       @param interface The network interface.
+       @result The IOInterfaceNamePrefix associated with the interface;
+               NULL if no IOInterfaceNamePrefix is available.
+ */
+CFStringRef
+_SCNetworkInterfaceGetIOInterfaceNamePrefix            (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0);
+
 /*!
        @function _SCNetworkInterfaceGetIOInterfaceType
        @discussion Returns the IOInterfaceType for the interface.
 /*!
        @function _SCNetworkInterfaceGetIOInterfaceType
        @discussion Returns the IOInterfaceType for the interface.
@@ -325,7 +343,7 @@ _SCNetworkInterfaceGetIOInterfaceType                       (SCNetworkInterfaceRef          interface)      __OSX
        @discussion Returns the IOInterfaceUnit for the interface.
        @param interface The network interface.
        @result The IOInterfaceUnit associated with the interface;
        @discussion Returns the IOInterfaceUnit for the interface.
        @param interface The network interface.
        @result The IOInterfaceUnit associated with the interface;
-               NULL if no IOLocation is available.
+               NULL if no IOInterfaceUnit is available.
  */
 CFNumberRef
 _SCNetworkInterfaceGetIOInterfaceUnit                  (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
  */
 CFNumberRef
 _SCNetworkInterfaceGetIOInterfaceUnit                  (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
@@ -415,6 +433,15 @@ _SCNetworkInterfaceIsModemV92                              (SCNetworkInterfaceRef          interface)      __OSX_AVAILA
 Boolean
 _SCNetworkInterfaceIsTethered                          (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0);
 
 Boolean
 _SCNetworkInterfaceIsTethered                          (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0);
 
+/*!
+       @function _SCNetworkInterfaceIsThunderbolt
+       @discussion Identifies if a network interface is a Thunderbolt device
+       @param interface The network interface.
+       @result TRUE if the interface is a Thunderbolt device.
+ */
+Boolean
+_SCNetworkInterfaceIsThunderbolt                       (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
 /*!
        @function _SCNetworkInterfaceIsPhysicalEthernet
        @discussion Indicates whether a network interface is a real ethernet interface i.e. one with an ethernet PHY.
 /*!
        @function _SCNetworkInterfaceIsPhysicalEthernet
        @discussion Indicates whether a network interface is a real ethernet interface i.e. one with an ethernet PHY.
@@ -779,6 +806,30 @@ SCNetworkServiceSetPrimaryRank                             (SCNetworkServiceRef            service,
 Boolean
 _SCNetworkServiceIsVPN                                 (SCNetworkServiceRef            service)        __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
 Boolean
 _SCNetworkServiceIsVPN                                 (SCNetworkServiceRef            service)        __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
+/*!
+       @function SCNetworkServiceSetExternalID
+       @discussion Set the external identifier for a network service.
+       @param service A reference to the network service.
+       @param identifierDomain A service can have multiple external identifiers. This string specifies which external identifier to set.
+       @param identifier The new external identifier to assign to the network service.
+       @result Returns TRUE if the external identifier was set successfully, FALSE if an error occurred.
+ */
+Boolean
+SCNetworkServiceSetExternalID                          (SCNetworkServiceRef            service,
+                                                        CFStringRef                    identifierDomain,
+                                                        CFStringRef identifier);
+
+/*!
+       @function SCNetworkServiceCopyExternalID
+       @discussion Copy the external identifier for a network service.
+       @param service The network service.
+       @param identifierDomain A service can have multiple external identifiers. This string specifies which external identifier to copy.
+       @result Returns the service's external identifier, or NULL if the service does not have an external identifier in the given domain.
+*/
+CFStringRef
+SCNetworkServiceCopyExternalID                         (SCNetworkServiceRef            service,
+                                                        CFStringRef                    identifierDomain);
+
 #pragma mark -
 #pragma mark SCNetworkSet configuration (SPI)
 
 #pragma mark -
 #pragma mark SCNetworkSet configuration (SPI)
 
@@ -795,6 +846,17 @@ isA_SCNetworkSet(CFTypeRef obj)
 }
 
 
 }
 
 
+/*!
+       @function SCNetworkSetCopyAvailableInterfaces
+       @discussion Returns all available interfaces for the set.
+               The interfaces excludes those of bond and bridge members.
+       @param set The network set.
+       @result The list of SCNetworkInterfaces.
+               You must release the returned value.
+ */
+CFArrayRef
+SCNetworkSetCopyAvailableInterfaces                    (SCNetworkSetRef                set)            __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
 /*!
        @function SCNetworkSetEstablishDefaultConfiguration
        @discussion Updates a network set by adding services for
 /*!
        @function SCNetworkSetEstablishDefaultConfiguration
        @discussion Updates a network set by adding services for
@@ -861,5 +923,85 @@ Boolean
 SCNetworkSetSetSelectedVPNService                      (SCNetworkSetRef                set,
                                                         SCNetworkServiceRef            service)        __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
 SCNetworkSetSetSelectedVPNService                      (SCNetworkSetRef                set,
                                                         SCNetworkServiceRef            service)        __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
+/*!
+       @group VPN Service configuration
+ */
+
+#pragma mark -
+#pragma mark VPN Service configuration
+
+typedef SCNetworkServiceRef VPNServiceRef;
+
+/*!
+       @function VPNServiceCopyAllMatchingExternalID
+       @discussion Copy the VPN services with the given external identifier.
+       @param prefs A reference to the prefs where the VPN services are stored.
+       @param identifierDomain A service can have multiple external identifiers. This string specifies which one to match with the given identifier.
+       @param identifier The external identifier of the desired services.
+       @result A array of references to the VPN services with the given identifier, or NULL if no such service exists
+ */
+CFArrayRef
+VPNServiceCopyAllMatchingExternalID            (SCPreferencesRef               prefs,
+                                                CFStringRef                    identifierDomain,
+                                                CFStringRef identifier)                __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
+/*!
+       @function VPNServiceCopyAll
+       @discussion Copy all VPN services.
+       @param prefs A reference to the prefs where the VPN services are stored.
+       @result An array containing VPNServiceRefs for all the VPN services.
+ */
+CFArrayRef
+VPNServiceCopyAll                              (SCPreferencesRef               prefs)  __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
+/*!
+       @function VPNServiceCopyAppRuleIDs
+       @discussion Copy all the app rule identifiers for a VPN service.
+       @param service A reference to the VPN service.
+       @result An array of CFStringRefs, each string containing the identifier of a app rule in the given service.
+ */
+CFArrayRef
+VPNServiceCopyAppRuleIDs                       (VPNServiceRef                  service)        __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
+/*!
+       @function VPNServiceSetAppRule
+       @discussion Add or modify an app rule in a VPN service. The ruleSettings dictionary must contain one of the following keys:
+               <pre>kSCValNetVPNAppRuleExecutableMatch</pre>
+               <pre>kSCValNetVPNAppRuleAccountIdentifierMatch</pre>
+       The ruleSettings dictionary may also contain the following keys:
+               <pre>kSCValNetVPNAppRuleDNSDomainMatch</pre>
+       See SCSchemaDefinitionsPrivate.h for more details.
+       @param service A reference to the VPN service.
+       @param ruleIdentifier The identifier of the new app rule.
+       @param ruleSettings The settings for the new app rule. See the dictionary keys defined above.
+       @result TRUE if the app rule was set successfully, FALSE if an error occurred.
+ */
+Boolean
+VPNServiceSetAppRule                           (VPNServiceRef                  service,
+                                                CFStringRef                    ruleIdentifier,
+                                                CFDictionaryRef                ruleSettings)   __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
+/*!
+       @function VPNServiceCopyAppRule
+       @discussion Copy the settings for a app rule in a VPN service.
+       @param service The app tunnel service.
+       @param ruleIdentifier The ID of the app rule.
+       @result The rule settings, or NULL if the app rule could not be found.
+ */
+CFDictionaryRef
+VPNServiceCopyAppRule                          (VPNServiceRef                  service,
+                                                CFStringRef                    ruleIdentifier) __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
+/*!
+       @function VPNServiceRemoveAppRule
+       @discussion Remove an app rule from a VPN service.
+       @param service The VPN service.
+       @param ruleIdentifier The ID of the app rule to remove.
+       @result Returns TRUE if the app rule was removed successfully; FALSE otherwise.
+ */
+Boolean
+VPNServiceRemoveAppRule                                (VPNServiceRef                  service,
+                                                CFStringRef                    ruleIdentifier) __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
 __END_DECLS
 #endif /* _SCNETWORKCONFIGURATIONPRIVATE_H */
 __END_DECLS
 #endif /* _SCNETWORKCONFIGURATIONPRIVATE_H */
index e54ea073c63ad8df05f8193ace89ef875a89144c..067c14e3a2ad975dde65f4521237441bf418ec87 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -44,6 +44,8 @@
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SCValidation.h>
+#include <SystemConfiguration/VPNAppLayerPrivate.h>
+#include <SystemConfiguration/VPNTunnel.h>
 
 #if    !TARGET_OS_IPHONE
 #include <Security/Security.h>
 
 #if    !TARGET_OS_IPHONE
 #include <Security/Security.h>
 #include <net/if.h>
 #include <mach/mach.h>
 #include <bsm/audit.h>
 #include <net/if.h>
 #include <mach/mach.h>
 #include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <sandbox.h>
 
 #include <ppp/ppp_msg.h>
 #include "pppcontroller.h"
 #include <ppp/pppcontroller_types.h>
 
 
 #include <ppp/ppp_msg.h>
 #include "pppcontroller.h"
 #include <ppp/pppcontroller_types.h>
 
+#ifndef        PPPCONTROLLER_SERVER_PRIV
+#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;
 static mach_port_t     scnc_server             = MACH_PORT_NULL;
 static int             debug                   = 0;
 static pthread_once_t  initialized             = PTHREAD_ONCE_INIT;
 static pthread_mutex_t scnc_lock               = PTHREAD_MUTEX_INITIALIZER;
 static mach_port_t     scnc_server             = MACH_PORT_NULL;
+static char            *scnc_server_name       = NULL;
 
 
 typedef struct {
 
 
 typedef struct {
@@ -90,9 +100,13 @@ typedef struct {
 
        /* client info (if we are proxying for another process */
        mach_port_t                     client_audit_session;
 
        /* client info (if we are proxying for another process */
        mach_port_t                     client_audit_session;
+       audit_token_t                   client_audit_token;
+       mach_port_t                     client_bootstrap_port;
        uid_t                           client_uid;
        gid_t                           client_gid;
        pid_t                           client_pid;
        uid_t                           client_uid;
        gid_t                           client_gid;
        pid_t                           client_pid;
+       uuid_t                          client_uuid;
+       CFStringRef                     client_bundle_id;
 
        /* ref to PPP controller for control messages */
        mach_port_t                     session_port;
 
        /* ref to PPP controller for control messages */
        mach_port_t                     session_port;
@@ -115,6 +129,14 @@ typedef struct {
        dispatch_queue_t                dispatchQueue;
        dispatch_source_t               dispatchSource;
 
        dispatch_queue_t                dispatchQueue;
        dispatch_source_t               dispatchSource;
 
+       SCNetworkConnectionType         type;
+       Boolean                         on_demand;
+       CFDictionaryRef                 on_demand_info;
+       CFDictionaryRef                 on_demand_user_options;
+       CFStringRef                     on_demand_required_probe;
+
+       /* Flow Divert support info */
+       CFDictionaryRef                 flow_divert_token_params;
 } SCNetworkConnectionPrivate, *SCNetworkConnectionPrivateRef;
 
 
 } SCNetworkConnectionPrivate, *SCNetworkConnectionPrivateRef;
 
 
@@ -136,7 +158,7 @@ __SCNetworkConnectionCopyDescription(CFTypeRef cf)
        CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkConnection, %p [%p]> {"), cf, allocator);
        CFStringAppendFormat(result, NULL, CFSTR("service = %p"), connectionPrivate->service);
        if (connectionPrivate->session_port != MACH_PORT_NULL) {
        CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkConnection, %p [%p]> {"), cf, allocator);
        CFStringAppendFormat(result, NULL, CFSTR("service = %p"), connectionPrivate->service);
        if (connectionPrivate->session_port != MACH_PORT_NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR(", server port = %p"), connectionPrivate->session_port);
+               CFStringAppendFormat(result, NULL, CFSTR(", server port = 0x%x"), connectionPrivate->session_port);
        }
        CFStringAppendFormat(result, NULL, CFSTR("}"));
 
        }
        CFStringAppendFormat(result, NULL, CFSTR("}"));
 
@@ -159,6 +181,17 @@ __SCNetworkConnectionDeallocate(CFTypeRef cf)
                                   -1);
        }
 
                                   -1);
        }
 
+       if (connectionPrivate->client_bootstrap_port != MACH_PORT_NULL) {
+               mach_port_mod_refs(mach_task_self(),
+                                  connectionPrivate->client_bootstrap_port,
+                                  MACH_PORT_RIGHT_SEND,
+                                  -1);
+       }
+
+       if (connectionPrivate->client_bundle_id != NULL) {
+               CFRelease(connectionPrivate->client_bundle_id);
+       }
+
        if (connectionPrivate->rls != NULL) {
                CFRunLoopSourceInvalidate(connectionPrivate->rls);
                CFRelease(connectionPrivate->rls);
        if (connectionPrivate->rls != NULL) {
                CFRunLoopSourceInvalidate(connectionPrivate->rls);
                CFRelease(connectionPrivate->rls);
@@ -185,7 +218,25 @@ __SCNetworkConnectionDeallocate(CFTypeRef cf)
        if (connectionPrivate->rlsContext.release != NULL)
                (*connectionPrivate->rlsContext.release)(connectionPrivate->rlsContext.info);
 
        if (connectionPrivate->rlsContext.release != NULL)
                (*connectionPrivate->rlsContext.release)(connectionPrivate->rlsContext.info);
 
-       CFRelease(connectionPrivate->service);
+       if (connectionPrivate->service != NULL) {
+               CFRelease(connectionPrivate->service);
+       }
+
+       if (connectionPrivate->on_demand_info != NULL) {
+               CFRelease(connectionPrivate->on_demand_info);
+       }
+
+       if (connectionPrivate->on_demand_user_options != NULL) {
+               CFRelease(connectionPrivate->on_demand_user_options);
+       }
+
+       if (connectionPrivate->on_demand_required_probe != NULL) {
+               CFRelease(connectionPrivate->on_demand_required_probe);
+       }
+
+       if (connectionPrivate->flow_divert_token_params != NULL) {
+               CFRelease(connectionPrivate->flow_divert_token_params);
+       }
 
        return;
 }
 
        return;
 }
@@ -212,6 +263,7 @@ childForkHandler()
        /* the process has forked (and we are the child process) */
 
        scnc_server = MACH_PORT_NULL;
        /* the process has forked (and we are the child process) */
 
        scnc_server = MACH_PORT_NULL;
+       scnc_server_name = NULL;
        return;
 }
 
        return;
 }
 
@@ -243,18 +295,84 @@ __SCNetworkConnectionInitialize(void)
 static Boolean
 __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection);
 
 static Boolean
 __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection);
 
+#define SC_NETWORK_CONNECTION_QUEUE "SCNetworkConnectionQueue"
+
+static dispatch_queue_t
+__SCNetworkConnectionQueue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(SC_NETWORK_CONNECTION_QUEUE, NULL);
+       });
+
+       return q;
+}
+
+
+static void
+__SCNetworkConnectionCallBackRunLoopPerform(SCNetworkConnectionRef connection,
+                                           CFRunLoopRef rl,
+                                           CFStringRef rl_mode,
+                                           SCNetworkConnectionCallBack rlsFunction,
+                                           void (*context_release)(const void *),
+                                           void *context_info)
+{
+       SCNetworkConnectionStatus       nc_status       = kSCNetworkConnectionInvalid;
+
+       nc_status = SCNetworkConnectionGetStatus(connection);
+       CFRunLoopPerformBlock(rl, rl_mode,
+                             ^{
+                                     (*rlsFunction)(connection, nc_status, context_info);
+                                     if ((context_release != NULL) && (context_info != NULL)) {
+                                             (*context_release)(context_info);
+                                     }
+                                     CFRelease(rl);
+                                     CFRelease(rl_mode);
+                                     CFRelease(connection);
+                             });
+       CFRunLoopWakeUp(rl);
+       return;
+}
+
+static void
+__SCNetworkConnectionCallBackDispatchPerform(SCNetworkConnectionRef connection,
+                                            dispatch_queue_t q,
+                                            SCNetworkConnectionCallBack rlsFunction,
+                                            void (*context_release)(const void *),
+                                            void *context_info)
+{
+       SCNetworkConnectionStatus       nc_status       = kSCNetworkConnectionInvalid;
+
+       nc_status = SCNetworkConnectionGetStatus(connection);
+       dispatch_async(q,
+                      ^{
+                              (*rlsFunction)(connection, nc_status, context_info);
+                              if ((context_release != NULL) && (context_info != NULL)) {
+                                      (*context_release)(context_info);
+                              }
+                              dispatch_release(q);
+                              CFRelease(connection);
+                      });
+       return;
+}
+
 
 static void
 __SCNetworkConnectionCallBack(CFMachPortRef port, void * msg, CFIndex size, void * info)
 {
        mach_no_senders_notification_t  *buf                    = msg;
        mach_msg_id_t                   msgid                   = buf->not_header.msgh_id;
 
 static void
 __SCNetworkConnectionCallBack(CFMachPortRef port, void * msg, CFIndex size, void * info)
 {
        mach_no_senders_notification_t  *buf                    = msg;
        mach_msg_id_t                   msgid                   = buf->not_header.msgh_id;
-
+       boolean_t                       exec_async              = FALSE;
        SCNetworkConnectionRef          connection              = (SCNetworkConnectionRef)info;
        SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
        void                            *context_info;
        void                            (*context_release)(const void *);
        SCNetworkConnectionRef          connection              = (SCNetworkConnectionRef)info;
        SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
        void                            *context_info;
        void                            (*context_release)(const void *);
+       CFRunLoopRef                    rl                      = NULL;
+       CFStringRef                     rl_mode;
        SCNetworkConnectionCallBack     rlsFunction             = NULL;
        SCNetworkConnectionCallBack     rlsFunction             = NULL;
+       dispatch_queue_t                q                       = NULL;
        SCNetworkConnectionStatus       nc_status               = kSCNetworkConnectionInvalid;
 
        if (msgid == MACH_NOTIFY_NO_SENDERS) {
        SCNetworkConnectionStatus       nc_status               = kSCNetworkConnectionInvalid;
 
        if (msgid == MACH_NOTIFY_NO_SENDERS) {
@@ -267,12 +385,14 @@ __SCNetworkConnectionCallBack(CFMachPortRef port, void * msg, CFIndex size, void
 
        if (!connectionPrivate->scheduled) {
                // if not currently scheduled
 
        if (!connectionPrivate->scheduled) {
                // if not currently scheduled
-               goto doit;
+               pthread_mutex_unlock(&connectionPrivate->lock);
+               return;
        }
 
        rlsFunction = connectionPrivate->rlsFunction;
        if (rlsFunction == NULL) {
        }
 
        rlsFunction = connectionPrivate->rlsFunction;
        if (rlsFunction == NULL) {
-               goto doit;
+               pthread_mutex_unlock(&connectionPrivate->lock);
+               return;
        }
 
        if ((connectionPrivate->rlsContext.retain != NULL) && (connectionPrivate->rlsContext.info != NULL)) {
        }
 
        if ((connectionPrivate->rlsContext.retain != NULL) && (connectionPrivate->rlsContext.info != NULL)) {
@@ -283,18 +403,54 @@ __SCNetworkConnectionCallBack(CFMachPortRef port, void * msg, CFIndex size, void
                context_release = NULL;
        }
 
                context_release = NULL;
        }
 
-    doit :
+       // Do we need to spin a new thread? (either we are running on the main
+       // dispatch queue or main runloop)
+       if (connectionPrivate->rlList == NULL) {
+               // this is the case if we are performing a callback on a dispatch queue
+               q = connectionPrivate->dispatchQueue;
+               if (q == dispatch_get_main_queue()) {
+                       exec_async = TRUE;
+               }
+       } else {
+               rl = CFRunLoopGetCurrent();
+               if (rl == CFRunLoopGetMain()) {
+                       exec_async = TRUE;
+               }
+       }
 
 
+       CFRetain(connection);
        pthread_mutex_unlock(&connectionPrivate->lock);
 
        pthread_mutex_unlock(&connectionPrivate->lock);
 
-       if (rlsFunction == NULL) {
+       if (exec_async == FALSE) {
+               nc_status = SCNetworkConnectionGetStatus(connection);
+               (*rlsFunction)(connection, nc_status, context_info);
+               if ((context_release != NULL) && (context_info != NULL)) {
+                       (*context_release)(context_info);
+               }
+               CFRelease(connection);
                return;
        }
 
                return;
        }
 
-       nc_status = SCNetworkConnectionGetStatus(connection);
-       (*rlsFunction)(connection, nc_status, context_info);
-       if ((context_release != NULL) && (context_info != NULL)) {
-               (*context_release)(context_info);
+       if (connectionPrivate->rlList == NULL) {
+               assert(q != NULL);
+               dispatch_retain(q);
+               dispatch_async(__SCNetworkConnectionQueue(),
+                              ^{__SCNetworkConnectionCallBackDispatchPerform(connection,
+                                                                             q,
+                                                                             rlsFunction,
+                                                                             context_release,
+                                                                             context_info);});
+       } else {
+               assert(rl != NULL);
+               CFRetain(rl);
+               rl_mode = CFRunLoopCopyCurrentMode(rl);
+               dispatch_async(__SCNetworkConnectionQueue(),
+                              ^{__SCNetworkConnectionCallBackRunLoopPerform(connection,
+                                                                            rl,
+                                                                            rl_mode,
+                                                                            rlsFunction,
+                                                                            context_release,
+                                                                            context_info);});
        }
 
        return;
        }
 
        return;
@@ -345,12 +501,17 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef         allocator,
        pthread_mutex_init(&connectionPrivate->lock, NULL);
 
        /* save the service */
        pthread_mutex_init(&connectionPrivate->lock, NULL);
 
        /* save the service */
-       connectionPrivate->service = CFRetain(service);
+       if (service != NULL) {
+               connectionPrivate->service = CFRetain(service);
+       }
 
        connectionPrivate->client_audit_session = MACH_PORT_NULL;
 
        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_uid = geteuid();
        connectionPrivate->client_gid = getegid();
        connectionPrivate->client_pid = getpid();
+       connectionPrivate->client_bundle_id = NULL;
+       uuid_clear(connectionPrivate->client_uuid);
 
        connectionPrivate->rlsFunction = callout;
 
 
        connectionPrivate->rlsFunction = callout;
 
@@ -361,6 +522,8 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef           allocator,
                }
        }
 
                }
        }
 
+       connectionPrivate->type = kSCNetworkConnectionTypeUnknown;
+
        /* success, return the connection reference */
        return connectionPrivate;
 
        /* success, return the connection reference */
        return connectionPrivate;
 
@@ -383,12 +546,12 @@ __SCNetworkConnectionServerPort(kern_return_t *status)
 
 #ifdef BOOTSTRAP_PRIVILEGED_SERVER
        *status = bootstrap_look_up2(bootstrap_port,
 
 #ifdef BOOTSTRAP_PRIVILEGED_SERVER
        *status = bootstrap_look_up2(bootstrap_port,
-                                    PPPCONTROLLER_SERVER,
+                                    __SCNetworkConnectionGetControllerPortName(),
                                     &server,
                                     0,
                                     BOOTSTRAP_PRIVILEGED_SERVER);
 #else  // BOOTSTRAP_PRIVILEGED_SERVER
                                     &server,
                                     0,
                                     BOOTSTRAP_PRIVILEGED_SERVER);
 #else  // BOOTSTRAP_PRIVILEGED_SERVER
-       *status = bootstrap_look_up(bootstrap_port, PPPCONTROLLER_SERVER, &server);
+       *status = bootstrap_look_up(bootstrap_port, __SCNetworkConnectionGetControllerPortName(), &server);
 #endif // BOOTSTRAP_PRIVILEGED_SERVER
 
        switch (*status) {
 #endif // BOOTSTRAP_PRIVILEGED_SERVER
 
        switch (*status) {
@@ -410,11 +573,41 @@ __SCNetworkConnectionServerPort(kern_return_t *status)
                        break;
        }
 
                        break;
        }
 
+       scnc_server_name = NULL;                /* reset pppcontroller server */
        return MACH_PORT_NULL;
 }
 
        return MACH_PORT_NULL;
 }
 
+static mach_port_t
+__SCNetworkConnectionGetCurrentServerPort(void)
+{
+       return scnc_server;
+}
+
+static mach_port_t
+__SCNetworkConnectionRefreshServerPort(mach_port_t current_server, int *mach_result)
+{
+       mach_port_t new_server;
+
+       pthread_mutex_lock(&scnc_lock);
+       if (scnc_server != MACH_PORT_NULL) {
+               if (current_server == scnc_server) {
+                       scnc_server_name = NULL;
+                       // if the server we tried returned the error
+                       (void)mach_port_deallocate(mach_task_self(), scnc_server);
+                       scnc_server = __SCNetworkConnectionServerPort(mach_result);
+               } else {
+                       // another thread has refreshed the server port
+               }
+       } else {
+               scnc_server = __SCNetworkConnectionServerPort(mach_result);
+       }
+       new_server = scnc_server;
+       pthread_mutex_unlock(&scnc_lock);
+
+       return new_server;
+}
 
 
-#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && !TARGET_IPHONE_SIMULATOR
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && (!TARGET_IPHONE_SIMULATOR || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000))
 #define        HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
 #endif
 
 #define        HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
 #endif
 
@@ -423,7 +616,6 @@ __SCNetworkConnectionServerPort(kern_return_t *status)
 #define        HAVE_PPPCONTROLLER_ATTACHWITHPROXY
 #endif
 
 #define        HAVE_PPPCONTROLLER_ATTACHWITHPROXY
 #endif
 
-
 static mach_port_t
 __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate)
 {
 static mach_port_t
 __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate)
 {
@@ -434,7 +626,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
        mach_port_t     oldNotify       = MACH_PORT_NULL;
        int             retry           = 0;
        int             sc_status       = kSCStatusFailed;
        mach_port_t     oldNotify       = MACH_PORT_NULL;
        int             retry           = 0;
        int             sc_status       = kSCStatusFailed;
-       mach_port_t     server          = scnc_server;
+       mach_port_t     server          = __SCNetworkConnectionGetCurrentServerPort();
        kern_return_t   status          = KERN_SUCCESS;
 
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
        kern_return_t   status          = KERN_SUCCESS;
 
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
@@ -445,6 +637,11 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
                return connectionPrivate->session_port;
        }
 
                return connectionPrivate->session_port;
        }
 
+       if (connectionPrivate->service == NULL) {
+               sc_status = kSCStatusConnectionNoService;
+               goto done;
+       }
+
        if (!_SCSerializeString(SCNetworkServiceGetServiceID(connectionPrivate->service), &dataRef, &data, &dataLen)) {
                goto done;
        }
        if (!_SCSerializeString(SCNetworkServiceGetServiceID(connectionPrivate->service), &dataRef, &data, &dataLen)) {
                goto done;
        }
@@ -490,6 +687,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
                if (server != MACH_PORT_NULL) {
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHPROXY
                        if ((connectionPrivate->client_audit_session == MACH_PORT_NULL) &&
                if (server != MACH_PORT_NULL) {
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHPROXY
                        if ((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_uid == geteuid()) &&
                            (connectionPrivate->client_gid == getegid()) &&
                            (connectionPrivate->client_pid == getpid())
@@ -508,6 +706,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHPROXY
                        } else {
                                mach_port_t     client_au_session;
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHPROXY
                        } else {
                                mach_port_t     client_au_session;
+                               mach_port_t     client_bootstrap_port;
 
                                if (connectionPrivate->client_audit_session == MACH_PORT_NULL) {
                                        client_au_session = au_session;
 
                                if (connectionPrivate->client_audit_session == MACH_PORT_NULL) {
                                        client_au_session = au_session;
@@ -515,10 +714,16 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
                                        client_au_session = connectionPrivate->client_audit_session;
                                }
 
                                        client_au_session = connectionPrivate->client_audit_session;
                                }
 
+                               if (connectionPrivate->client_bootstrap_port == MACH_PORT_NULL) {
+                                       client_bootstrap_port = bootstrap_port;
+                               } else {
+                                       client_bootstrap_port = connectionPrivate->client_bootstrap_port;
+                               }
+
                                status = pppcontroller_attach_proxy(server,
                                                                    data,
                                                                    dataLen,
                                status = pppcontroller_attach_proxy(server,
                                                                    data,
                                                                    dataLen,
-                                                                   bootstrap_port,
+                                                                   client_bootstrap_port,
                                                                    notify_port,
                                                                    client_au_session,
                                                                    connectionPrivate->client_uid,
                                                                    notify_port,
                                                                    client_au_session,
                                                                    connectionPrivate->client_uid,
@@ -571,21 +776,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
                        }
                }
 
                        }
                }
 
-               pthread_mutex_lock(&scnc_lock);
-               if (scnc_server != MACH_PORT_NULL) {
-                       if (server == scnc_server) {
-                               // if the server we tried returned the error
-                               (void)mach_port_deallocate(mach_task_self(), scnc_server);
-                               scnc_server = __SCNetworkConnectionServerPort(&sc_status);
-                       } else {
-                               // another thread has refreshed the server port
-                       }
-               } else {
-                       scnc_server = __SCNetworkConnectionServerPort(&sc_status);
-               }
-               server = scnc_server;
-               pthread_mutex_unlock(&scnc_lock);
-
+               server = __SCNetworkConnectionRefreshServerPort(server, &sc_status);
                if (server == MACH_PORT_NULL) {
                        // if server not available
                        if (sc_status == BOOTSTRAP_UNKNOWN_SERVICE) {
                if (server == MACH_PORT_NULL) {
                        // if server not available
                        if (sc_status == BOOTSTRAP_UNKNOWN_SERVICE) {
@@ -665,7 +856,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate
        // clean up
 
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
        // clean up
 
 #ifdef HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
-       if (au_session != MACH_PORT_NULL){
+       if (au_session != MACH_PORT_NULL) {
                (void)mach_port_deallocate(mach_task_self(), au_session);
        }
 #endif // HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
                (void)mach_port_deallocate(mach_task_self(), au_session);
        }
 #endif // HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION
@@ -731,17 +922,6 @@ __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection)
        if (connectionPrivate->rlList != NULL) {
                rlList = CFArrayCreateCopy(NULL, connectionPrivate->rlList);
        }
        if (connectionPrivate->rlList != NULL) {
                rlList = CFArrayCreateCopy(NULL, connectionPrivate->rlList);
        }
-       if (connectionPrivate->dispatchQueue != NULL) {
-               // save dispatchQueue, release reference when we've queue'd blocks
-               // complete, allow re-scheduling
-               dispatchGroup = connectionPrivate->dispatchGroup;
-               connectionPrivate->dispatchGroup = NULL;
-               dispatchQueue = connectionPrivate->dispatchQueue;
-               connectionPrivate->dispatchQueue = NULL;
-
-               // and take an extra reference for rescheduling
-               dispatch_retain(dispatchQueue);
-       }
 
        // cancel [old] notifications
        if (connectionPrivate->rlList != NULL) {
 
        // cancel [old] notifications
        if (connectionPrivate->rlList != NULL) {
@@ -758,6 +938,19 @@ __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection)
                connectionPrivate->dispatchSource = NULL;
        }
 
                connectionPrivate->dispatchSource = NULL;
        }
 
+       /* Make sure dispatchSource is cancelled before removing group/queue */
+       if (connectionPrivate->dispatchQueue != NULL) {
+               // save dispatchQueue, release reference when we've queue'd blocks
+               // complete, allow re-scheduling
+               dispatchGroup = connectionPrivate->dispatchGroup;
+               connectionPrivate->dispatchGroup = NULL;
+               dispatchQueue = connectionPrivate->dispatchQueue;
+               connectionPrivate->dispatchQueue = NULL;
+
+               // and take an extra reference for rescheduling
+               dispatch_retain(dispatchQueue);
+       }
+
        connectionPrivate->scheduled = FALSE;
 
        pthread_mutex_unlock(&connectionPrivate->lock);
        connectionPrivate->scheduled = FALSE;
 
        pthread_mutex_unlock(&connectionPrivate->lock);
@@ -960,6 +1153,16 @@ SCNetworkConnectionCreateWithServiceID(CFAllocatorRef                     allocator,
 }
 
 
 }
 
 
+SCNetworkConnectionRef
+SCNetworkConnectionCreate(CFAllocatorRef               allocator,
+                         SCNetworkConnectionCallBack   callout,
+                         SCNetworkConnectionContext    *context)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate = __SCNetworkConnectionCreatePrivate(allocator, NULL, callout, context);
+       return (SCNetworkConnectionRef)connectionPrivate;
+}
+
+
 CFStringRef
 SCNetworkConnectionCopyServiceID(SCNetworkConnectionRef connection)
 {
 CFStringRef
 SCNetworkConnectionCopyServiceID(SCNetworkConnectionRef connection)
 {
@@ -971,6 +1174,11 @@ SCNetworkConnectionCopyServiceID(SCNetworkConnectionRef connection)
                return NULL;
        }
 
                return NULL;
        }
 
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return NULL;
+       }
+
        serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
        return CFRetain(serviceID);
 }
        serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
        return CFRetain(serviceID);
 }
@@ -990,7 +1198,7 @@ SCNetworkConnectionSetClientInfo(SCNetworkConnectionRef    connection,
                return FALSE;
        }
 
                return FALSE;
        }
 
-       // save client bootstrap port
+       // save client audit session port
        if (connectionPrivate->client_audit_session != MACH_PORT_NULL) {
                mach_port_mod_refs(mach_task_self(),
                                   connectionPrivate->client_audit_session,
        if (connectionPrivate->client_audit_session != MACH_PORT_NULL) {
                mach_port_mod_refs(mach_task_self(),
                                   connectionPrivate->client_audit_session,
@@ -1015,6 +1223,72 @@ SCNetworkConnectionSetClientInfo(SCNetworkConnectionRef  connection,
 }
 
 
 }
 
 
+Boolean
+SCNetworkConnectionSetClientAuditInfo(SCNetworkConnectionRef   connection,
+                                     audit_token_t             client_audit_token,
+                                     mach_port_t               audit_session,
+                                     mach_port_t               bootstrap_port,
+                                     pid_t                     client_pid,
+                                     const uuid_t              uuid,
+                                     const char                *bundle_id)
+{
+       const audit_token_t             null_audit              = KERNEL_AUDIT_TOKEN_VALUE;
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       gid_t                           gid                     = 0;
+       pid_t                           pid                     = 0;
+       uid_t                           uid                     = 0;
+
+       if (memcmp(&client_audit_token, &null_audit, sizeof(client_audit_token))) {
+#if    TARGET_OS_IPHONE
+           audit_token_to_au32(client_audit_token, NULL, &uid, &gid, NULL, NULL, &pid, NULL, NULL);
+#else  // TARGET_OS_IPHONE
+           uid = audit_token_to_euid(client_audit_token);
+           gid = audit_token_to_egid(client_audit_token);
+           pid = audit_token_to_pid(client_audit_token);
+#endif // TARGET_OS_IPHONE
+       } else {
+           pid = client_pid;
+       }
+
+       if (!SCNetworkConnectionSetClientInfo(connection, audit_session, uid, gid, pid)) {
+               return FALSE;
+       }
+
+       if (connectionPrivate->client_bootstrap_port != MACH_PORT_NULL) {
+               mach_port_mod_refs(mach_task_self(),
+                                  connectionPrivate->client_bootstrap_port,
+                                  MACH_PORT_RIGHT_SEND,
+                                  -1);
+               connectionPrivate->client_bootstrap_port = MACH_PORT_NULL;
+       }
+
+       connectionPrivate->client_bootstrap_port = bootstrap_port;
+       if (connectionPrivate->client_bootstrap_port != MACH_PORT_NULL) {
+               mach_port_mod_refs(mach_task_self(),
+                                  connectionPrivate->client_bootstrap_port,
+                                  MACH_PORT_RIGHT_SEND,
+                                  1);
+       }
+
+       memcpy(&connectionPrivate->client_audit_token, &client_audit_token, sizeof(connectionPrivate->client_audit_token));
+
+       if (uuid != NULL && !uuid_is_null(uuid)) {
+               uuid_copy(connectionPrivate->client_uuid, uuid);
+       }
+
+       if (connectionPrivate->client_bundle_id != NULL) {
+               CFRelease(connectionPrivate->client_bundle_id);
+               connectionPrivate->client_bundle_id = NULL;
+       }
+
+       if (bundle_id != NULL) {
+               connectionPrivate->client_bundle_id = CFStringCreateWithCString(kCFAllocatorDefault, bundle_id, kCFStringEncodingUTF8);
+       }
+
+       return TRUE;
+}
+
+
 CFDictionaryRef
 SCNetworkConnectionCopyStatistics(SCNetworkConnectionRef connection)
 {
 CFDictionaryRef
 SCNetworkConnectionCopyStatistics(SCNetworkConnectionRef connection)
 {
@@ -1095,12 +1369,25 @@ SCNetworkConnectionGetStatus(SCNetworkConnectionRef connection)
        int                             sc_status               = kSCStatusFailed;
        mach_port_t                     session_port;
        kern_return_t                   status;
        int                             sc_status               = kSCStatusFailed;
        mach_port_t                     session_port;
        kern_return_t                   status;
+       CFStringRef                     serviceID;
 
        if (!isA_SCNetworkConnection(connection)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                return kSCNetworkConnectionInvalid;
        }
 
 
        if (!isA_SCNetworkConnection(connection)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                return kSCNetworkConnectionInvalid;
        }
 
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return kSCNetworkConnectionInvalid;
+       }
+
+       // skip retry and return immediately if we know no service is to be found.
+       serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
+       if (CFStringGetLength(serviceID) == 0) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return kSCNetworkConnectionInvalid;
+       }
+
        pthread_mutex_lock(&connectionPrivate->lock);
 
     retry :
        pthread_mutex_lock(&connectionPrivate->lock);
 
     retry :
@@ -1152,12 +1439,25 @@ SCNetworkConnectionCopyExtendedStatus(SCNetworkConnectionRef connection)
        int                             sc_status               = kSCStatusFailed;
        mach_port_t                     session_port;
        kern_return_t                   status;
        int                             sc_status               = kSCStatusFailed;
        mach_port_t                     session_port;
        kern_return_t                   status;
+       CFStringRef                     serviceID;
 
        if (!isA_SCNetworkConnection(connection)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                return NULL;
        }
 
 
        if (!isA_SCNetworkConnection(connection)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                return NULL;
        }
 
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return NULL;
+       }
+
+       // skip retry and return immediately if we know no service is to be found.
+       serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
+       if (CFStringGetLength(serviceID) == 0) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return NULL;
+       }
+
        pthread_mutex_lock(&connectionPrivate->lock);
 
     retry :
        pthread_mutex_lock(&connectionPrivate->lock);
 
     retry :
@@ -1209,6 +1509,14 @@ SCNetworkConnectionCopyExtendedStatus(SCNetworkConnectionRef connection)
 }
 
 
 }
 
 
+static void
+_SCNetworkConnectionMergeDictionaries (const void *key, const void *value, void *context)
+{
+       /* Add value only if not present */
+       CFDictionaryAddValue((CFMutableDictionaryRef)context, (CFStringRef)key, (CFTypeRef)value);
+}
+
+
 Boolean
 SCNetworkConnectionStart(SCNetworkConnectionRef        connection,
                         CFDictionaryRef        userOptions,
 Boolean
 SCNetworkConnectionStart(SCNetworkConnectionRef        connection,
                         CFDictionaryRef        userOptions,
@@ -1233,6 +1541,21 @@ SCNetworkConnectionStart(SCNetworkConnectionRef  connection,
                return FALSE;
        }
 
                return FALSE;
        }
 
+       if (userOptions == NULL) {
+               userOptions = connectionPrivate->on_demand_user_options;
+       } else if (connectionPrivate->on_demand_user_options != NULL) {
+               CFDictionaryRef localUserOptions        = NULL;
+
+               localUserOptions = CFDictionaryCreateMutableCopy(NULL, 0, userOptions);
+               if (localUserOptions) {
+                       CFDictionaryApplyFunction(connectionPrivate->on_demand_user_options,
+                                                 _SCNetworkConnectionMergeDictionaries,
+                                                 (void *)localUserOptions);
+                       CFRelease(connectionPrivate->on_demand_user_options);
+                       userOptions = connectionPrivate->on_demand_user_options = localUserOptions;
+               }
+       }
+
        if (debug > 0) {
                CFMutableDictionaryRef  mdict = NULL;
 
        if (debug > 0) {
                CFMutableDictionaryRef  mdict = NULL;
 
@@ -1293,6 +1616,12 @@ SCNetworkConnectionStart(SCNetworkConnectionRef  connection,
 
        pthread_mutex_lock(&connectionPrivate->lock);
 
 
        pthread_mutex_lock(&connectionPrivate->lock);
 
+       /* Clear out any cached flow divert token parameters */
+       if (connectionPrivate->flow_divert_token_params != NULL) {
+           CFRelease(connectionPrivate->flow_divert_token_params);
+           connectionPrivate->flow_divert_token_params = NULL;
+       }
+
     retry :
 
        session_port = __SCNetworkConnectionSessionPort(connectionPrivate);
     retry :
 
        session_port = __SCNetworkConnectionSessionPort(connectionPrivate);
@@ -1492,6 +1821,81 @@ SCNetworkConnectionResume(SCNetworkConnectionRef connection)
 }
 
 
 }
 
 
+#if    !TARGET_IPHONE_SIMULATOR
+Boolean
+SCNetworkConnectionRefreshOnDemandState(SCNetworkConnectionRef connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       Boolean                         ok                      = FALSE;
+       uint32_t                        retry                   = 0;
+       int                             sc_status               = kSCStatusFailed;
+       mach_port_t                     server_port             = __SCNetworkConnectionGetCurrentServerPort();
+       kern_return_t                   status                  = KERN_SUCCESS;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (debug > 0) {
+               SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionRefreshOnDemandState (0x%x)"), connectionPrivate);
+       }
+
+       pthread_mutex_lock(&connectionPrivate->lock);
+
+       while (TRUE) {
+               if (server_port == MACH_PORT_NULL) {
+                       server_port = __SCNetworkConnectionRefreshServerPort(server_port, &sc_status);
+                       if (server_port == MACH_PORT_NULL) {
+                               // if server not available
+                               if (sc_status == BOOTSTRAP_UNKNOWN_SERVICE) {
+                                       // wait up to 2.5 seconds for the [SCNetworkConnection] server
+                                       // to startup
+                                       if ((retry += 50) < 2500) {
+                                               usleep(50 * 1000);      // sleep 50ms between attempts
+                                               continue;
+                                       }
+                               }
+                               break;
+                       }
+               }
+
+               status = pppcontroller_ondemand_refresh_state(server_port, &sc_status);
+               if (status == KERN_SUCCESS)
+                       break;
+
+               if (status == MACH_SEND_INVALID_DEST) {
+                       // the server is not yet available
+                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnectionRefreshOnDemandState (!dest) (0x%x)"), connectionPrivate);
+               } else if (status == MIG_SERVER_DIED) {
+                       // the server we were using is gone
+                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnectionRefreshOnDemandState (!mig) (0x%x)"), connectionPrivate);
+               } else {
+                       // if we got an unexpected error, don't retry
+                       sc_status = status;
+                       break;
+               }
+       }
+
+       if (debug > 0) {
+               SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionRefreshOnDemandState (0x%x), return: %d/%d"), connectionPrivate, status, sc_status);
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               goto done;
+       }
+
+       ok = TRUE;
+
+    done :
+
+       pthread_mutex_unlock(&connectionPrivate->lock);
+       return ok;
+}
+#endif /* !TARGET_IPHONE_SIMULATOR */
+
+
 CFDictionaryRef
 SCNetworkConnectionCopyUserOptions(SCNetworkConnectionRef connection)
 {
 CFDictionaryRef
 SCNetworkConnectionCopyUserOptions(SCNetworkConnectionRef connection)
 {
@@ -1615,6 +2019,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef   connection,
        }
 
        if (queue != NULL) {
        }
 
        if (queue != NULL) {
+               dispatch_group_t        group   = NULL;
                mach_port_t             mp;
                dispatch_source_t       source;
 
                mach_port_t             mp;
                dispatch_source_t       source;
 
@@ -1644,7 +2049,8 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef   connection,
                // the group to empty and use the group's finalizer to release
                // our reference to the SCNetworkConnection.
                //
                // the group to empty and use the group's finalizer to release
                // our reference to the SCNetworkConnection.
                //
-               connectionPrivate->dispatchGroup = dispatch_group_create();
+               group = dispatch_group_create();
+               connectionPrivate->dispatchGroup = group;
                CFRetain(connection);
                dispatch_set_context(connectionPrivate->dispatchGroup, (void *)connection);
                dispatch_set_finalizer_f(connectionPrivate->dispatchGroup, (dispatch_function_t)CFRelease);
                CFRetain(connection);
                dispatch_set_context(connectionPrivate->dispatchGroup, (void *)connection);
                dispatch_set_finalizer_f(connectionPrivate->dispatchGroup, (dispatch_function_t)CFRelease);
@@ -1674,7 +2080,8 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef   connection,
 
                        CFRetain(connection);
                        notify_port = dispatch_get_context(source);
 
                        CFRetain(connection);
                        notify_port = dispatch_get_context(source);
-                       dispatch_group_async(connectionPrivate->dispatchGroup, connectionPrivate->dispatchQueue, ^{
+
+                       dispatch_group_async(group, queue, ^{
                                __SCNetworkConnectionCallBack(notify_port,
                                                              (void *)&notify_msg.msg,
                                                              sizeof(notify_msg),
                                __SCNetworkConnectionCallBack(notify_port,
                                                              (void *)&notify_msg.msg,
                                                              sizeof(notify_msg),
@@ -1874,47 +2281,453 @@ SCNetworkConnectionSetDispatchQueue(SCNetworkConnectionRef     connection,
 }
 
 
 }
 
 
-#pragma mark -
-#pragma mark User level "dial" API
-
-
-#define k_NetworkConnect_Notification  "com.apple.networkConnect"
-#define k_NetworkConnect_Pref_File     CFSTR("com.apple.networkConnect")
-#define k_InterentConnect_Pref_File    CFSTR("com.apple.internetconnect")
+/* Requires having called SCNetworkConnectionSelectServiceWithOptions previously */
+Boolean
+SCNetworkConnectionIsOnDemandSuspended(SCNetworkConnectionRef connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
 
 
-#define k_Dial_Default_Key             CFSTR("ConnectByDefault") // needs to go into SC
-#define k_Last_Service_Id_Key          CFSTR("ServiceID")
-#define k_Unique_Id_Key                        CFSTR("UniqueIdentifier")
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
 
 
+       if (connectionPrivate->on_demand_info != NULL) {
+               uint32_t        isSuspended     = 0;
+               CFNumberRef     num             = NULL;
 
 
-/* Private Prototypes */
-static Boolean SCNetworkConnectionPrivateCopyDefaultServiceIDForDial   (SCDynamicStoreRef session, CFStringRef *serviceID);
-static Boolean SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore (SCDynamicStoreRef session, CFStringRef *serviceID);
-static Boolean SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(CFArrayRef userOptionsArray, CFDictionaryRef *userOptions);
-static Boolean SCNetworkConnectionPrivateIsPPPService                  (SCDynamicStoreRef session, CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2);
-static void addPasswordFromKeychain                                    (SCDynamicStoreRef session, CFStringRef serviceID, CFDictionaryRef *userOptions);
-static CFStringRef copyPasswordFromKeychain                            (CFStringRef uniqueID);
+               num = CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCPropNetVPNOnDemandSuspended);
+               if (isA_CFNumber(num) &&
+                   CFNumberGetValue(num, kCFNumberSInt32Type, &isSuspended) &&
+                   (isSuspended != 0)) {
+                       return TRUE;
+               }
+       }
 
 
-static int             notify_userprefs_token  = -1;
+       _SCErrorSet(kSCStatusOK);
+       return FALSE;
+}
 
 
-static CFDictionaryRef onDemand_configuration  = NULL;
-static pthread_mutex_t onDemand_notify_lock    = PTHREAD_MUTEX_INITIALIZER;
-static int             onDemand_notify_token   = -1;
+static void
+SCNetworkConnectionTriggerOnDemandCallback (SCNetworkConnectionRef          connection,
+                                           SCNetworkConnectionStatus       status,
+                                           void                            *info)
+{
+       dispatch_group_t group = (dispatch_group_t)info;
+       if (status != kSCNetworkConnectionConnecting) {
+               dispatch_group_leave(group);
+       }
+}
 
 
-/*
- *     return TRUE if domain1 ends with domain2, and will check for trailing "."
- */
 Boolean
 Boolean
-_SC_domainEndsWithDomain(CFStringRef compare_domain, CFStringRef match_domain)
+SCNetworkConnectionTriggerOnDemandIfNeeded     (CFStringRef                    hostName,
+                                                Boolean                        afterDNSFail,
+                                                int                            timeout,
+                                                int                            trafficClass)
 {
 {
-       CFRange         range;
-       Boolean         ret             = FALSE;
-       CFStringRef     s1              = NULL;
-       Boolean         s1_created      = FALSE;
+       SCNetworkConnectionRef          connection = NULL;
+       dispatch_group_t                group = NULL;
+       CFMutableDictionaryRef          options_dict = NULL;
+       Boolean                         connectedIfNeeded = FALSE;
+
+       /* Require hostName, require non-root user */
+       if (hostName == NULL || geteuid() == 0) {
+               goto done;
+       }
+
+       group = dispatch_group_create();
+       if (group == NULL) {
+               goto done;
+       }
+
+       SCNetworkConnectionContext context = { 0, (void*)group, NULL, NULL, NULL };
+       connection = SCNetworkConnectionCreate(kCFAllocatorDefault, SCNetworkConnectionTriggerOnDemandCallback, &context);
+       if (connection == NULL) {
+               goto done;
+       }
+
+       options_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       if (options_dict == NULL) {
+               goto done;
+       }
+
+       CFDictionaryAddValue(options_dict, kSCNetworkConnectionSelectionOptionOnDemandHostName, hostName);
+       CFDictionaryAddValue(options_dict, kSCNetworkConnectionSelectionOptionOnDemandRetry, (afterDNSFail ? kCFBooleanTrue : kCFBooleanFalse));
+
+       if (trafficClass) {
+               CFNumberRef trafficClassRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &trafficClass);
+               if (trafficClassRef) {
+                       CFDictionaryAddValue(options_dict, kSCNetworkConnectionSelectionOptionOnDemandTrafficClass, trafficClassRef);
+                       CFRelease(trafficClassRef);
+               }
+       }
+
+       if (SCNetworkConnectionSelectServiceWithOptions(connection, options_dict)) {
+               SCNetworkConnectionStatus status = SCNetworkConnectionGetStatus(connection);
+
+               if (status == kSCNetworkConnectionConnected) {
+                       /* If already connected, done */
+                       connectedIfNeeded = TRUE;
+               } else if (status == kSCNetworkConnectionDisconnected || status == kSCNetworkConnectionConnecting) {
+                       dispatch_queue_t callback_queue = dispatch_queue_create("SCNetworkConnectionTrigger queue", NULL);
+                       if (callback_queue) {
+                               SCNetworkConnectionSetDispatchQueue(connection, callback_queue);
+
+                               dispatch_group_enter(group);
+
+                               /* If the connection is already connecting, we don't need to start.
+                                If disconnected, do call start. */
+                               if (status == kSCNetworkConnectionDisconnected) {
+                                       SCNetworkConnectionStart(connection, NULL, TRUE);
+                               }
+
+                               dispatch_group_wait(group, (timeout == 0) ? DISPATCH_TIME_FOREVER : dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * timeout));
+
+                               SCNetworkConnectionSetDispatchQueue(connection, NULL);
+
+                               status = SCNetworkConnectionGetStatus(connection);
+                               if (status == kSCNetworkConnectionConnected) {
+                                       connectedIfNeeded = TRUE;
+                               }
+
+                               dispatch_release(callback_queue);
+                       }
+               }
+       } else {
+               /* Not needed, so we can return true */
+               connectedIfNeeded = TRUE;
+       }
+
+done:
+       if (options_dict) {
+               CFRelease(options_dict);
+       }
+
+       if (connection) {
+               CFRelease(connection);
+       }
+
+       if (group) {
+               dispatch_release(group);
+       }
+
+       return connectedIfNeeded;
+}
+
+
+Boolean
+SCNetworkConnectionCopyOnDemandInfo(SCNetworkConnectionRef     connection,
+                                   CFStringRef                 *onDemandRemoteAddress,
+                                   SCNetworkConnectionStatus   *onDemandConnectionStatus)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return FALSE;
+       }
+
+       if (onDemandRemoteAddress != NULL) {
+               *onDemandRemoteAddress = NULL;
+       }
+
+       if (onDemandConnectionStatus != NULL) {
+               *onDemandConnectionStatus = kSCNetworkConnectionInvalid;
+       }
+
+       if (connectionPrivate->on_demand_info != NULL) {
+               if (onDemandRemoteAddress != NULL) {
+                       CFStringRef address =
+                           CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCNetworkConnectionOnDemandRemoteAddress);
+                       if (isA_CFString(address)) {
+                               *onDemandRemoteAddress = address;
+                               CFRetain(*onDemandRemoteAddress);
+                       }
+               }
+
+               if (onDemandConnectionStatus != NULL) {
+                       int num;
+                       CFNumberRef status_num =
+                           CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCNetworkConnectionOnDemandStatus);
+                       if (isA_CFNumber(status_num) && CFNumberGetValue(status_num, kCFNumberIntType, &num)) {
+                               *onDemandConnectionStatus = num;
+                       }
+               }
+       }
+
+       return connectionPrivate->on_demand;
+}
+
+
+Boolean
+SCNetworkConnectionGetReachabilityInfo(SCNetworkConnectionRef          connection,
+                                      SCNetworkReachabilityFlags       *reach_flags,
+                                      unsigned int                     *reach_if_index)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return FALSE;
+       }
+
+       if (reach_flags != NULL) {
+               *reach_flags = 0;
+       }
+
+       if (reach_if_index != NULL) {
+               *reach_if_index = 0;
+       }
+
+       if (connectionPrivate->on_demand_info != NULL) {
+               if (reach_flags != NULL) {
+                       int num;
+                       CFNumberRef flags_num =
+                           CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCNetworkConnectionOnDemandReachFlags);
+                       if (isA_CFNumber(flags_num) && CFNumberGetValue(flags_num, kCFNumberIntType, &num)) {
+                               *reach_flags = num;
+                       }
+               }
+
+               if (reach_if_index != NULL) {
+                       int num;
+                       CFNumberRef if_index_num =
+                           CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCNetworkConnectionOnDemandReachInterfaceIndex);
+                       if (isA_CFNumber(if_index_num) && CFNumberGetValue(if_index_num, kCFNumberIntType, &num)) {
+                               *reach_if_index = num;
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
+
+SCNetworkConnectionType
+SCNetworkConnectionGetType(SCNetworkConnectionRef connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return kSCNetworkConnectionTypeUnknown;
+       }
+
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               return kSCNetworkConnectionTypeUnknown;
+       }
+
+       _SCErrorSet(kSCStatusOK);
+
+       return connectionPrivate->type;
+}
+
+
+static Boolean
+validate_flow_properties(CFDictionaryRef flowProperties)
+{
+       CFStringRef                     host_name_str;
+       CFDataRef                       host_address_data;
+       CFNumberRef                     host_port_num;
+
+       if (!isA_CFDictionary(flowProperties)) {
+               return FALSE;
+       }
+
+       /* Validate the host name if one was given */
+       host_name_str = CFDictionaryGetValue(flowProperties, kSCNetworkConnectionFlowPropertyHostName);
+       if (host_name_str != NULL && (!isA_CFString(host_name_str) || CFStringGetLength(host_name_str) == 0)) {
+               return FALSE;
+       }
+
+       /* Validate the address if one was given */
+       host_address_data = CFDictionaryGetValue(flowProperties, kSCNetworkConnectionFlowPropertyHostAddress);
+       if (host_address_data != NULL) {
+               struct sockaddr *sock_addr;
+
+               if (!isA_CFData(host_address_data) || CFDataGetLength(host_address_data) < sizeof(struct sockaddr)) {
+                       return FALSE;
+               }
+
+               sock_addr = (struct sockaddr *)CFDataGetBytePtr(host_address_data);
+               if (CFDataGetLength(host_address_data) < sock_addr->sa_len) {
+                       return FALSE;
+               }
+
+               if (sock_addr->sa_family == AF_INET) {
+                       if (sock_addr->sa_len >= sizeof(struct sockaddr_in)) {
+                               struct sockaddr_in *sa_in = (struct sockaddr_in *)(void *)sock_addr;
+                               in_addr_t any = { INADDR_ANY };
+                               if (memcmp(&sa_in->sin_addr, &any, sizeof(any)) == 0) {
+                                       return FALSE;
+                               }
+                       } else {
+                               return FALSE;
+                       }
+               } else if (sock_addr->sa_family == AF_INET6) {
+                       if (sock_addr->sa_len >= sizeof(struct sockaddr_in6)) {
+                               struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)(void *)sock_addr;
+                               struct in6_addr any = IN6ADDR_ANY_INIT;
+                               if (memcmp(&sa_in6->sin6_addr, &any, sizeof(any)) == 0) {
+                                       return FALSE;
+                               }
+                       }
+               }
+       }
+
+       /* We must have either a host name or an address */
+       if (host_name_str == NULL && host_address_data == NULL) {
+               return FALSE;
+       }
+
+       /* Validate the port */
+       host_port_num = CFDictionaryGetValue(flowProperties, kSCNetworkConnectionFlowPropertyHostPort);
+       if (host_port_num != NULL) {
+               int num;
+               if (!isA_CFNumber(host_port_num) || !CFNumberGetValue(host_port_num, kCFNumberIntType, &num)) {
+                       return FALSE;
+               }
+
+               if (num == 0) {
+                       return FALSE;
+               }
+       } else {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+
+CFDataRef
+SCNetworkConnectionCopyFlowDivertToken(SCNetworkConnectionRef  connection,
+                                      CFDictionaryRef          flowProperties)
+{
+       CFDictionaryRef                 app_properties          = NULL;
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       CFDataRef                       token                   = NULL;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               goto done;
+       }
+
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               goto done;
+       }
+
+       if (connectionPrivate->type != kSCNetworkConnectionTypeAppLayerVPN) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               goto done;
+       }
+
+       if (!validate_flow_properties(flowProperties)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               goto done;
+       }
+
+       app_properties = VPNAppLayerCopyCachedAppProperties(connectionPrivate->client_audit_token,
+                                                           connectionPrivate->client_pid,
+                                                           connectionPrivate->client_uuid,
+                                                           connectionPrivate->client_bundle_id);
+       if (app_properties == NULL) {
+               SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnectionCopyFlowDivertToken: no cached app properties available"));
+               _SCErrorSet(kSCStatusFailed);
+               goto done;
+       }
+
+       token = VPNAppLayerCreateFlowDivertToken(connection, app_properties, flowProperties);
+
+done:
+       if (app_properties != NULL) {
+               CFRelease(app_properties);
+       }
+
+       return token;
+}
+
+
+int
+SCNetworkConnectionGetServiceIdentifier                (SCNetworkConnectionRef         connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       int                             service_identifier      = -1;
+
+       if (connectionPrivate->service != NULL) {
+               service_identifier = 0;
+               if (connectionPrivate->on_demand_info != NULL) {
+                       CFNumberRef id_num = CFDictionaryGetValue(connectionPrivate->on_demand_info, kSCPropNetDNSServiceIdentifier);
+
+                       if (isA_CFNumber(id_num)) {
+                               CFNumberGetValue(id_num, kCFNumberIntType, &service_identifier);
+                       }
+               }
+       }
+
+       return service_identifier;
+}
+
+
+#pragma mark -
+#pragma mark User level "dial" API
+
+
+#define k_NetworkConnect_Notification  "com.apple.networkConnect"
+#define k_NetworkConnect_Pref_File     CFSTR("com.apple.networkConnect")
+#define k_InterentConnect_Pref_File    CFSTR("com.apple.internetconnect")
+
+#define k_Dial_Default_Key             CFSTR("ConnectByDefault") // needs to go into SC
+#define k_Last_Service_Id_Key          CFSTR("ServiceID")
+#define k_Unique_Id_Key                        CFSTR("UniqueIdentifier")
+
+
+/* Private Prototypes */
+static Boolean SCNetworkConnectionPrivateCopyDefaultServiceIDForDial   (CFStringRef *serviceID);
+static Boolean SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore (CFStringRef *serviceID);
+static Boolean SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(CFArrayRef userOptionsArray, CFDictionaryRef *userOptions);
+static Boolean SCNetworkConnectionPrivateIsPPPService                  (CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2);
+static void addPasswordFromKeychain                                    (CFStringRef serviceID, CFDictionaryRef *userOptions);
+static CFStringRef copyPasswordFromKeychain                            (CFStringRef uniqueID);
+
+static int             notify_userprefs_token  = -1;
+
+static CFDictionaryRef onDemand_configuration  = NULL;
+static Boolean         onDemand_force_refresh  = FALSE;
+static pthread_mutex_t onDemand_notify_lock    = PTHREAD_MUTEX_INITIALIZER;
+static int             onDemand_notify_token   = -1;
+
+
+/*
+ *     return TRUE if domain1 ends with domain2, and will check for trailing "."
+ */
+#define WILD_CARD_MATCH_STR CFSTR("*")
+Boolean
+_SC_domainEndsWithDomain(CFStringRef compare_domain, CFStringRef match_domain)
+{
+       CFRange         range;
+       Boolean         ret             = FALSE;
+       CFStringRef     s1              = NULL;
+       Boolean         s1_created      = FALSE;
        CFStringRef     s2              = NULL;
        Boolean         s2_created      = FALSE;
        CFStringRef     s3              = NULL;
 
        CFStringRef     s2              = NULL;
        Boolean         s2_created      = FALSE;
        CFStringRef     s3              = NULL;
 
+       if (CFEqual(match_domain, WILD_CARD_MATCH_STR)) {
+               return TRUE;
+       }
+
        if (CFStringHasSuffix(compare_domain, CFSTR("."))) {
                range.location = 0;
                range.length = CFStringGetLength(compare_domain) - 1;
        if (CFStringHasSuffix(compare_domain, CFSTR("."))) {
                range.location = 0;
                range.length = CFStringGetLength(compare_domain) - 1;
@@ -1964,22 +2777,13 @@ _SC_domainEndsWithDomain(CFStringRef compare_domain, CFStringRef match_domain)
 
 /* VPN On Demand */
 
 
 /* VPN On Demand */
 
-Boolean
-__SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef                *storeP,
-                                             CFStringRef               hostName,
-                                             Boolean                   onDemandRetry,
-                                             CFStringRef               *connectionServiceID,
-                                             SCNetworkConnectionStatus *connectionStatus,
-                                             CFStringRef               *vpnRemoteAddress)      /*  CFDictionaryRef *info */
+static CFDictionaryRef
+__SCNetworkConnectionCopyOnDemandConfiguration(void)
 {
        int                     changed         = 1;
 {
        int                     changed         = 1;
-       CFDictionaryRef         configuration;
-       Boolean                 ok              = FALSE;
        int                     status;
        int                     status;
-       SCDynamicStoreRef       store           = *storeP;
-       CFArrayRef              triggers;
        uint64_t                triggersCount   = 0;
        uint64_t                triggersCount   = 0;
-       int                     triggersIndex;
+       CFDictionaryRef         configuration;
 
        pthread_mutex_lock(&onDemand_notify_lock);
        if (onDemand_notify_token == -1) {
 
        pthread_mutex_lock(&onDemand_notify_lock);
        if (onDemand_notify_token == -1) {
@@ -1989,6 +2793,7 @@ __SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef           *storeP,
                        onDemand_notify_token = -1;
                }
        }
                        onDemand_notify_token = -1;
                }
        }
+
        if (onDemand_notify_token != -1) {
                status = notify_check(onDemand_notify_token, &changed);
                if (status != NOTIFY_STATUS_OK) {
        if (onDemand_notify_token != -1) {
                status = notify_check(onDemand_notify_token, &changed);
                if (status != NOTIFY_STATUS_OK) {
@@ -2007,7 +2812,7 @@ __SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef           *storeP,
                }
        }
 
                }
        }
 
-       if (changed) {
+       if (changed || onDemand_force_refresh) {
                CFStringRef     key;
 
                if (_sc_debug || (debug > 0)) {
                CFStringRef     key;
 
                if (_sc_debug || (debug > 0)) {
@@ -2021,179 +2826,765 @@ __SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef               *storeP,
                        onDemand_configuration = NULL;
                }
 
                        onDemand_configuration = NULL;
                }
 
-               if (triggersCount > 0) {
-                       if (store == NULL) {
-                               store = SCDynamicStoreCreate(NULL, CFSTR("__SCNetworkConnectionCopyOnDemandInfoWithName"), NULL, NULL);
-                               if (store == NULL) {
-                                       SCLog(TRUE, LOG_ERR, CFSTR("__SCNetworkConnectionCopyOnDemandInfoWithName SCDynamicStoreCreate() failed"));
-
-                                       // force retry on next check
-                                       if (onDemand_notify_token != -1) {
-                                               (void)notify_cancel(onDemand_notify_token);
-                                               onDemand_notify_token = -1;
-                                       }
-                                       pthread_mutex_unlock(&onDemand_notify_lock);
-                                       return FALSE;
-                               }
-                               *storeP = store;
-                       }
-
+               if ((triggersCount > 0) || onDemand_force_refresh) {
                        key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetOnDemand);
                        key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetOnDemand);
-                       onDemand_configuration = SCDynamicStoreCopyValue(store, key);
+                       onDemand_configuration = SCDynamicStoreCopyValue(NULL, key);
                        CFRelease(key);
                        if ((onDemand_configuration != NULL) && !isA_CFDictionary(onDemand_configuration)) {
                                CFRelease(onDemand_configuration);
                                onDemand_configuration = NULL;
                        }
                }
                        CFRelease(key);
                        if ((onDemand_configuration != NULL) && !isA_CFDictionary(onDemand_configuration)) {
                                CFRelease(onDemand_configuration);
                                onDemand_configuration = NULL;
                        }
                }
+
+               onDemand_force_refresh = FALSE;
        }
 
        configuration = (onDemand_configuration != NULL) ? CFRetain(onDemand_configuration) : NULL;
        pthread_mutex_unlock(&onDemand_notify_lock);
 
        }
 
        configuration = (onDemand_configuration != NULL) ? CFRetain(onDemand_configuration) : NULL;
        pthread_mutex_unlock(&onDemand_notify_lock);
 
-       if (configuration == NULL) {
-               // if no "OnDemand" configurations
-               return FALSE;
-       }
+       return configuration;
+}
 
 
-       triggers = CFDictionaryGetValue(configuration, kSCNetworkConnectionOnDemandTriggers);
-       triggersCount = isA_CFArray(triggers) ? CFArrayGetCount(triggers) : 0;
-       for (triggersIndex = 0; triggersIndex < triggersCount; triggersIndex++) {
-               CFArrayRef      domains;
-               int             domainsCount;
-               int             domainsIndex;
-               CFStringRef     key;
-               CFDictionaryRef trigger;
 
 
-               trigger = CFArrayGetValueAtIndex(triggers, triggersIndex);
-               if (!isA_CFDictionary(trigger)) {
-                       // if not a valid "OnDemand" configuration
-                       continue;
-               }
+__private_extern__
+void
+__SCNetworkConnectionForceOnDemandConfigurationRefresh(void)
+{
+       pthread_mutex_lock(&onDemand_notify_lock);
+       onDemand_force_refresh = TRUE;
+       pthread_mutex_unlock(&onDemand_notify_lock);
 
 
-               /*
-                * If we haven't tried a resulution yet, we only want to check for a name
-                * match for domains that require to always connect.
-                */
-               key = onDemandRetry ? kSCNetworkConnectionOnDemandMatchDomainsOnRetry
-                                   : kSCNetworkConnectionOnDemandMatchDomainsAlways;
-               domains = CFDictionaryGetValue(trigger, key);
-               domainsCount = isA_CFArray(domains) ? CFArrayGetCount(domains) : 0;
-               for (domainsIndex = 0; domainsIndex < domainsCount; domainsIndex++) {
+       return;
+}
+
+
+static Boolean
+__SCNetworkConnectionShouldNeverMatch(CFDictionaryRef trigger, CFStringRef hostName, pid_t client_pid)
+{
+       CFArrayRef      exceptedProcesses;
+       int             exceptedProcessesCount;
+       int             exceptedProcessesIndex;
+       CFArrayRef      exceptions;
+       int             exceptionsCount;
+       int             exceptionsIndex;
+
+       // we have a matching domain, check against exception list
+       exceptions = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandMatchDomainsNever);
+       exceptionsCount = isA_CFArray(exceptions) ? CFArrayGetCount(exceptions) : 0;
+       for (exceptionsIndex = 0; exceptionsIndex < exceptionsCount; exceptionsIndex++) {
+               CFStringRef     exception;
+
+               exception = CFArrayGetValueAtIndex(exceptions, exceptionsIndex);
+               if (isA_CFString(exception) && _SC_domainEndsWithDomain(hostName, exception)) {
+                       // found matching exception
+                       if (_sc_debug || (debug > 0)) {
+                               SCLog(TRUE, LOG_INFO, CFSTR("OnDemand match exception"));
+                       }
+                       return TRUE;
+               }
+       }
+
+       if (client_pid != 0) {
+               exceptedProcesses = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandPluginPIDs);
+               exceptedProcessesCount = isA_CFArray(exceptedProcesses) ? CFArrayGetCount(exceptedProcesses) : 0;
+               for (exceptedProcessesIndex = 0; exceptedProcessesIndex < exceptedProcessesCount; exceptedProcessesIndex++) {
+                       int             pid;
+                       CFNumberRef     pidRef;
+
+                       pidRef = CFArrayGetValueAtIndex(exceptedProcesses, exceptedProcessesIndex);
+                       if (isA_CFNumber(pidRef) && CFNumberGetValue(pidRef, kCFNumberIntType, &pid)) {
+                               if (pid == client_pid) {
+                                       return TRUE;
+                               }
+                       }
+               }
+       }
+
+       return FALSE;
+}
+
+static CFStringRef
+__SCNetworkConnectionDomainGetMatchWithParameters(CFStringRef action, CFPropertyListRef actionParameters, CFStringRef hostName, CFStringRef *probeString)
+{
+       CFArrayRef      actionArray = NULL;
+       CFIndex         actionArraySize = 0;
+       CFIndex         i;
+       CFStringRef     matchDomain     = NULL;
+
+       /* For now, only support EvaluateConnection, which takes a CFArray */
+       if (!CFEqual(action, kSCValNetVPNOnDemandRuleActionEvaluateConnection) || !isA_CFArray(actionParameters)) {
+               return NULL;
+       }
+
+       actionArray = (CFArrayRef)actionParameters;
+       actionArraySize = CFArrayGetCount(actionArray);
+
+       /* Process domain rules, with actions of ConnectIfNeeded and NeverConnect */
+       for (i = 0; i < actionArraySize; i++) {
+               CFStringRef     domainAction = NULL;
+               CFDictionaryRef domainRule = CFArrayGetValueAtIndex(actionArray, i);
+               CFArrayRef      domains = NULL;
+               CFIndex         domainsCount = 0;
+               CFIndex         domainsIndex;
+
+               if (!isA_CFDictionary(domainRule)) {
+                       continue;
+               }
+
+               domains = CFDictionaryGetValue(domainRule, kSCPropNetVPNOnDemandRuleActionParametersDomains);
+               if (!isA_CFArray(domains)) {
+                       continue;
+               }
+
+               domainsCount = CFArrayGetCount(domains);
+               for (domainsIndex = 0; domainsIndex < domainsCount; domainsIndex++) {
                        CFStringRef     domain;
                        CFStringRef     domain;
+                       domain = CFArrayGetValueAtIndex(domains, domainsIndex);
+                       if (isA_CFString(domain) && _SC_domainEndsWithDomain(hostName, domain)) {
+                               matchDomain = domain;
+                               break;
+                       }
+               }
+
+               if (matchDomain) {
+                       domainAction = CFDictionaryGetValue(domainRule, kSCPropNetVPNOnDemandRuleActionParametersDomainAction);
+                       if (isA_CFString(domainAction) && CFEqual(domainAction, kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect)) {
+                               return NULL;
+                       } else {
+                               /* If we found a match, save the optional probe string as well */
+                               if (probeString) {
+                                       *probeString = CFDictionaryGetValue(domainRule, kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe);
+                               }
+                               break;
+                       }
+               }
+       }
+
+       return matchDomain;
+}
+
+static CFStringRef
+__SCNetworkConnectionDomainGetMatch(CFDictionaryRef trigger, CFStringRef hostName, Boolean onDemandRetry)
+{
+       CFArrayRef      domains;
+       int             domainsCount;
+       int             domainsIndex;
+       CFStringRef     key;
+       CFStringRef     match_domain    = NULL;
+
+       /* Old configuration: always, never, on retry lists */
+       key = onDemandRetry ? kSCNetworkConnectionOnDemandMatchDomainsOnRetry : kSCNetworkConnectionOnDemandMatchDomainsAlways;
+
+       domains = CFDictionaryGetValue(trigger, key);
+       domainsCount = isA_CFArray(domains) ? CFArrayGetCount(domains) : 0;
+       for (domainsIndex = 0; domainsIndex < domainsCount; domainsIndex++) {
+               CFStringRef     domain;
+
+               domain = CFArrayGetValueAtIndex(domains, domainsIndex);
+               if (isA_CFString(domain) && _SC_domainEndsWithDomain(hostName, domain)) {
+                       match_domain = domain;
+                       break;
+               }
+       }
+
+       return match_domain;
+}
+
+
+static Boolean
+__SCNetworkConnectionShouldAlwaysConnect(CFDictionaryRef trigger)
+{
+       CFStringRef action = CFDictionaryGetValue(trigger, kSCPropNetVPNOnDemandRuleAction);
+       return (isA_CFString(action) && CFEqual(action, kSCValNetVPNOnDemandRuleActionConnect));
+}
+
+
+static Boolean
+__SCNetworkConnectionShouldIgnoreTrigger(CFDictionaryRef trigger)
+{
+       CFStringRef     action          = CFDictionaryGetValue(trigger, kSCPropNetVPNOnDemandRuleAction);
+       int             flags;
+       CFNumberRef     reachFlags;
+
+       if (isA_CFString(action) &&
+           (CFEqual(action, kSCValNetVPNOnDemandRuleActionIgnore) ||
+            CFEqual(action, kSCValNetVPNOnDemandRuleActionDisconnect))) {
+                   return TRUE;
+       }
+
+       /* If the VPN server is not reachable immediately, ignore this trigger */
+       reachFlags = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandReachFlags);
+       if (isA_CFNumber(reachFlags) && CFNumberGetValue(reachFlags, kCFNumberIntType, &flags)) {
+               if (!(flags & kSCNetworkReachabilityFlagsReachable) || (flags & kSCNetworkReachabilityFlagsConnectionRequired)) {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+static CFDictionaryRef
+__SCNetworkConnectionCopyMatchingTriggerWithName(CFDictionaryRef       configuration,
+                                                CFStringRef            hostName,
+                                                pid_t                  client_pid,
+                                                Boolean                onDemandRetry,
+                                                CFDictionaryRef        *match_info,
+                                                Boolean                *triggerNow,
+                                                CFStringRef            *probe_string)
+{
+       CFDictionaryRef result          = NULL;
+       int             sc_status       = kSCStatusOK;
+       CFArrayRef      triggers;
+       uint64_t        triggersCount   = 0;
+       int             triggersIndex;
+       Boolean         usedOnDemandRetry = FALSE;
+
+       if (triggerNow != NULL) {
+               *triggerNow = FALSE;
+       }
+
+       if (match_info != NULL) {
+               *match_info = NULL;
+       }
+
+       triggers = CFDictionaryGetValue(configuration, kSCNetworkConnectionOnDemandTriggers);
+       triggersCount = isA_CFArray(triggers) ? CFArrayGetCount(triggers) : 0;
+       for (triggersIndex = 0; triggersIndex < triggersCount; triggersIndex++) {
+               CFStringRef     matched_domain  = NULL;
+               CFStringRef     matched_probe_string = NULL;
+               CFDictionaryRef trigger;
+               Boolean         trigger_matched = FALSE;
+
+               usedOnDemandRetry = FALSE;
+
+               trigger = CFArrayGetValueAtIndex(triggers, triggersIndex);
+               if (!isA_CFDictionary(trigger)) {
+                       // if not a valid "OnDemand" configuration
+                       continue;
+               }
+
+               if (__SCNetworkConnectionShouldAlwaysConnect(trigger)) {
+                       /* If the trigger action is 'Connect', always match this trigger */
+                       /* First check the never match list */
+                       if (__SCNetworkConnectionShouldNeverMatch(trigger, hostName, client_pid)) {
+                               continue;
+                       }
+                       trigger_matched = TRUE;
+               } else if (__SCNetworkConnectionShouldIgnoreTrigger(trigger)) {
+                       /* If the trigger action is 'Ignore' or 'Disconnect', skip this trigger */
+                       sc_status = kSCStatusConnectionIgnore;
+                       continue;
+               } else {
+                       CFStringRef action = CFDictionaryGetValue(trigger, kSCPropNetVPNOnDemandRuleAction);
+                       CFArrayRef actionParameters = CFDictionaryGetValue(trigger, kSCPropNetVPNOnDemandRuleActionParameters);
+                       if (action && actionParameters) {
+                               matched_domain = __SCNetworkConnectionDomainGetMatchWithParameters(action, actionParameters, hostName, &matched_probe_string);
+                               usedOnDemandRetry = TRUE;
+                       } else {
+                               if (onDemandRetry) {
+                                       matched_domain = __SCNetworkConnectionDomainGetMatch(trigger, hostName, TRUE);
+                                       usedOnDemandRetry = TRUE;
+                               } else {
+                                       matched_domain = __SCNetworkConnectionDomainGetMatch(trigger, hostName, FALSE);
+                                       if (matched_domain == NULL && result == NULL) {
+                                               /* Check the retry list if Always failed */
+                                               matched_domain = __SCNetworkConnectionDomainGetMatch(trigger, hostName, TRUE);
+                                               usedOnDemandRetry = TRUE;
+                                       }
+                               }
+                       }
+
+                       if (matched_domain) {
+                               if (__SCNetworkConnectionShouldNeverMatch(trigger, hostName, client_pid)) {
+                                       matched_domain = NULL;
+                                       continue;
+                               } else {
+                                       trigger_matched = TRUE;
+                               }
+                       }
+               }
+
+               if (trigger_matched) {
+                       // if we have a matching domain and there were no exceptions
+                       // then we pass back the OnDemand info
+                       if (match_info != NULL) {
+                               CFMutableDictionaryRef  minfo;
+                               SCNetworkConnectionType type    = kSCNetworkConnectionTypeIPLayerVPN;
+                               CFNumberRef             type_num;
+
+                               if (*match_info != NULL) {
+                                       CFRelease(*match_info);
+                                       *match_info = NULL;
+                               }
+
+                               minfo = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                 0,
+                                                                 &kCFTypeDictionaryKeyCallBacks,
+                                                                 &kCFTypeDictionaryValueCallBacks);
+
+                               type_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &type);
+                               CFDictionarySetValue(minfo, kSCNetworkConnectionOnDemandMatchInfoVPNType, type_num);
+                               CFRelease(type_num);
+                               if (matched_domain) {
+                                       CFDictionarySetValue(minfo, kSCNetworkConnectionOnDemandMatchInfoDomain, matched_domain);
+                               }
+                               CFDictionarySetValue(minfo,
+                                                    kSCNetworkConnectionOnDemandMatchInfoOnRetry,
+                                                    (usedOnDemandRetry ? kCFBooleanTrue : kCFBooleanFalse));
+
+                               *match_info = minfo;
+                       }
+
+                       if (probe_string != NULL) {
+                               if (*probe_string != NULL) {
+                                       CFRelease(*probe_string);
+                                       *probe_string = NULL;
+                               }
+
+                               if (matched_probe_string) {
+                                       *probe_string = CFRetain(matched_probe_string);
+                               }
+                       }
+
+                       result = trigger;
+
+                       /* If retry was requested, or we found Always match, trigger now */
+                       if (onDemandRetry || !usedOnDemandRetry) {
+                               if (triggerNow != NULL) {
+                                       *triggerNow = TRUE;
+                               }
+                               break;
+                       }
+
+                       /* If we matched the Retry list, but Always was requested,
+                        keep going through triggers in case one matches an Always */
+               }
+       }
+
+       if (result) {
+               CFRetain(result);
+       }
+
+       _SCErrorSet(sc_status);
+       return result;
+}
+
+
+static CFDictionaryRef
+__SCNetworkConnectionCopyTriggerWithService(CFDictionaryRef    configuration,
+                                           CFStringRef         service_id)
+{
+       CFArrayRef      triggers;
+       uint64_t        triggersCount   = 0;
+       int             triggersIndex;
+
+       triggers = CFDictionaryGetValue(configuration, kSCNetworkConnectionOnDemandTriggers);
+       triggersCount = isA_CFArray(triggers) ? CFArrayGetCount(triggers) : 0;
+       for (triggersIndex = 0; triggersIndex < triggersCount; triggersIndex++) {
+               CFDictionaryRef trigger;
+               CFStringRef     trigger_service_id;
+
+               trigger = CFArrayGetValueAtIndex(triggers, triggersIndex);
+               if (!isA_CFDictionary(trigger)) {
+                       // if not a valid "OnDemand" configuration
+                       continue;
+               }
+
+               trigger_service_id = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandServiceID);
+               if (isA_CFString(trigger_service_id) && CFEqual(trigger_service_id, service_id)) {
+                       CFRetain(trigger);
+                       return trigger;
+               }
+       }
+
+       return NULL;
+}
+
+
+__private_extern__ CFDictionaryRef
+__SCNetworkConnectionCopyTokenParameters(SCNetworkConnectionRef connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       CFDictionaryRef                 parameters              = NULL;
+       uint8_t                         params_buffer[PPP_MACH_MAX_INLINE_DATA];
+       uint32_t                        params_buffer_len       = sizeof(params_buffer);
+       int                             sc_status               = kSCStatusOK;
+       mach_port_t                     session_port;
+       kern_return_t                   status;
+
+       pthread_mutex_lock(&connectionPrivate->lock);
+
+       parameters = connectionPrivate->flow_divert_token_params;
+       if (parameters != NULL) {
+           CFRetain(parameters);
+           goto done;
+       }
+
+retry:
+       if (parameters != NULL) {
+               CFRelease(parameters);
+               parameters = NULL;
+       }
+
+       session_port = __SCNetworkConnectionSessionPort(connectionPrivate);
+       if (session_port == MACH_PORT_NULL) {
+               goto done;
+       }
+
+       status = pppcontroller_flow_divert_copy_token_parameters(session_port, params_buffer, &params_buffer_len);
+       if (status == KERN_SUCCESS) {
+               if (params_buffer_len > 0) {
+                       CFDataRef params_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
+                                                                           params_buffer,
+                                                                           params_buffer_len,
+                                                                           kCFAllocatorNull);
+                       parameters = CFPropertyListCreateWithData(kCFAllocatorDefault,
+                                                                 params_data,
+                                                                 kCFPropertyListImmutable,
+                                                                 NULL,
+                                                                 NULL);
+                       CFRelease(params_data);
+               }
+       }
+
+       if (__SCNetworkConnectionNeedsRetry(connection, "__SCNetworkConnectionCopyTokenParameters()", status, &sc_status)) {
+               goto retry;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+       }
+
+done:
+       if (parameters != NULL && connectionPrivate->flow_divert_token_params == NULL) {
+           connectionPrivate->flow_divert_token_params = (CFDictionaryRef)CFRetain(parameters);
+       }
+
+       pthread_mutex_unlock(&connectionPrivate->lock);
+
+       return parameters;
+}
+
+Boolean
+__SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef                *storeP,
+                                             CFStringRef               hostName,
+                                             Boolean                   onDemandRetry,
+                                             CFStringRef               *connectionServiceID,
+                                             SCNetworkConnectionStatus *connectionStatus,
+                                             CFStringRef               *vpnRemoteAddress)      /*  CFDictionaryRef *info */
+{
+       CFDictionaryRef         configuration;
+       Boolean                 ok              = FALSE;
+       int                     sc_status       = kSCStatusOK;
+       CFDictionaryRef         trigger;
+       Boolean                 trigger_now     = FALSE;
+
+       configuration = __SCNetworkConnectionCopyOnDemandConfiguration();
+       if (configuration == NULL) {
+               _SCErrorSet(sc_status);
+               return ok;
+       }
+
+       trigger = __SCNetworkConnectionCopyMatchingTriggerWithName(configuration, hostName, 0, onDemandRetry, NULL, &trigger_now, NULL);
+       if (trigger != NULL && trigger_now) {
+               CFNumberRef                     num;
+               SCNetworkConnectionStatus       onDemandStatus  = kSCNetworkConnectionDisconnected;
+
+               ok = TRUE;
+
+               if (!CFDictionaryGetValueIfPresent(trigger, kSCNetworkConnectionOnDemandStatus, (const void **)&num) ||
+                   !isA_CFNumber(num) ||
+                   !CFNumberGetValue(num, kCFNumberSInt32Type, &onDemandStatus)) {
+                       onDemandStatus = kSCNetworkConnectionDisconnected;
+               }
+               if (connectionStatus != NULL) {
+                       *connectionStatus = onDemandStatus;
+               }
+
+               if (connectionServiceID != NULL) {
+                       *connectionServiceID = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandServiceID);
+                       *connectionServiceID = isA_CFString(*connectionServiceID);
+                       if ((*connectionServiceID != NULL) && (CFStringGetLength(*connectionServiceID) > 0)) {
+                               CFRetain(*connectionServiceID);
+                       } else {
+                               SCLog(TRUE, LOG_INFO, CFSTR("OnDemand%s configuration error, no serviceID"),
+                                     onDemandRetry ? " (on retry)" : "");
+                               *connectionServiceID = NULL;
+                               ok = FALSE;
+                       }
+               }
+
+               if (vpnRemoteAddress != NULL) {
+                       *vpnRemoteAddress = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandRemoteAddress);
+                       *vpnRemoteAddress = isA_CFString(*vpnRemoteAddress);
+                       if ((*vpnRemoteAddress != NULL) && (CFStringGetLength(*vpnRemoteAddress) > 0)) {
+                               CFRetain(*vpnRemoteAddress);
+                       } else {
+                               SCLog(TRUE, LOG_INFO, CFSTR("OnDemand%s configuration error, no server address"),
+                                     onDemandRetry ? " (on retry)" : "");
+                               *vpnRemoteAddress = NULL;
+                               ok = FALSE;
+                       }
+               }
+
+               if (!ok) {
+                       if ((connectionServiceID != NULL) && (*connectionServiceID != NULL)) {
+                               CFRelease(*connectionServiceID);
+                               *connectionServiceID = NULL;
+                       }
+                       if ((vpnRemoteAddress != NULL) && (*vpnRemoteAddress != NULL)) {
+                               CFRelease(*vpnRemoteAddress);
+                               *vpnRemoteAddress = NULL;
+                       }
+                       sc_status = kSCStatusFailed;
+               } else {
+                       if (_sc_debug || (debug > 0)) {
+                               SCLog(TRUE, LOG_INFO, CFSTR("OnDemand%s match, connection status = %d"),
+                                     onDemandRetry ? " (on retry)" : "",
+                                     onDemandStatus);
+                       }
+               }
+       }
+
+       if (trigger) {
+               CFRelease(trigger);
+       }
+
+//     if (_sc_debug || (debug > 0)) {
+//             SCLog(TRUE, LOG_INFO, CFSTR("OnDemand domain name(s) not matched"));
+//     }
+
+       if (configuration != NULL) CFRelease(configuration);
+       if (!ok) {
+               _SCErrorSet(sc_status);
+       }
+       return ok;
+}
+
+static Boolean
+__SCNetworkConnectionCopyUserPreferencesInternal(CFDictionaryRef       selectionOptions,
+                                                CFStringRef            *serviceID,
+                                                CFDictionaryRef        *userOptions)
+{
+       int             prefsChanged    = 1;
+       int             status;
+       Boolean         success         = FALSE;
+
+       if (notify_userprefs_token == -1) {
+               status = notify_register_check(k_NetworkConnect_Notification, &notify_userprefs_token);
+               if (status != NOTIFY_STATUS_OK) {
+                       SCLog(TRUE, LOG_ERR, CFSTR("notify_register_check() failed, status=%lu"), status);
+                       (void)notify_cancel(notify_userprefs_token);
+                       notify_userprefs_token = -1;
+               } else {
+                       // clear the "something has changed" state
+                       (void) notify_check(notify_userprefs_token, &prefsChanged);
+                       prefsChanged = 1;
+               }
+       }
+       if (notify_userprefs_token != -1) {
+               status = notify_check(notify_userprefs_token, &prefsChanged);
+               if (status != NOTIFY_STATUS_OK) {
+                       SCLog(TRUE, LOG_ERR, CFSTR("notify_check() failed, status=%lu"), status);
+                       (void)notify_cancel(notify_userprefs_token);
+                       notify_userprefs_token = -1;
+               }
+       }
+
+
+       *serviceID = NULL;
+       *userOptions = NULL;
 
 
-                       domain = CFArrayGetValueAtIndex(domains, domainsIndex);
-                       if (!isA_CFString(domain)) {
-                               // if not a valid match domain
+       if (selectionOptions != NULL) {
+               Boolean         catchAllFound   = FALSE;
+               CFIndex         catchAllService = 0;
+               CFIndex         catchAllConfig  = 0;
+               CFStringRef     hostName        = NULL;
+               CFStringRef     priority        = NULL;
+               CFArrayRef      serviceNames    = NULL;
+               CFDictionaryRef services        = NULL;
+               CFIndex         serviceIndex;
+               CFIndex         servicesCount;
+
+               hostName = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName);
+               if (hostName == NULL) {
+                       hostName = CFDictionaryGetValue(selectionOptions, kSCPropNetPPPOnDemandHostName);
+               }
+               hostName = isA_CFString(hostName);
+               if (hostName == NULL)
+                       goto done_selection;    // if no hostname for matching
+
+               priority = CFDictionaryGetValue(selectionOptions, kSCPropNetPPPOnDemandPriority);
+               if (!isA_CFString(priority))
+                       priority = kSCValNetPPPOnDemandPriorityDefault;
+
+
+               if (!isA_CFArray(serviceNames))
+                       goto done_selection;
+
+
+               if (!isA_CFDictionary(services)) {
+                       goto done_selection;
+               }
+
+               servicesCount = CFArrayGetCount(serviceNames);
+               for (serviceIndex = 0; serviceIndex < servicesCount; serviceIndex++) {
+                       CFIndex         configIndex;
+                       CFIndex         configsCount;
+                       CFArrayRef      serviceConfigs;
+                       CFStringRef     serviceName;
+                       int             val;
+
+                       serviceName = CFArrayGetValueAtIndex(serviceNames, serviceIndex);
+                       if (!isA_CFString(serviceName)) {
+                               continue;
+                       }
+
+                       serviceConfigs = CFDictionaryGetValue(services, serviceName);
+                       if (!isA_CFArray(serviceConfigs)) {
                                continue;
                        }
 
                                continue;
                        }
 
-                       if (_SC_domainEndsWithDomain(hostName, domain)) {
-                               CFArrayRef                      exceptions;
-                               int                             exceptionsCount;
-                               int                             exceptionsIndex;
-                               CFNumberRef                     num;
-                               SCNetworkConnectionStatus       onDemandStatus  = kSCNetworkConnectionDisconnected;
+                       configsCount = CFArrayGetCount(serviceConfigs);
+                       for (configIndex = 0; configIndex < configsCount; configIndex++) {
+                               CFNumberRef     autodial;
+                               CFDictionaryRef config;
+                               CFDictionaryRef pppConfig;
+
+                               config = CFArrayGetValueAtIndex(serviceConfigs, configIndex);
+                               if (!isA_CFDictionary(config)) {
+                                       continue;
+                               }
+
+                               pppConfig = CFDictionaryGetValue(config, kSCEntNetPPP);
+                               if (!isA_CFDictionary(pppConfig)) {
+                                       continue;
+                               }
+
+                               autodial = CFDictionaryGetValue(pppConfig, kSCPropNetPPPOnDemandEnabled);
+                               if (!isA_CFNumber(autodial)) {
+                                       continue;
+                               }
+
+                               CFNumberGetValue(autodial, kCFNumberIntType, &val);
+                               if (val) {
+                                       CFArrayRef      domains;
+                                       CFIndex         domainsCount;
+                                       CFIndex         domainsIndex;
 
 
-                               // we have a matching domain, check against exception list
-                               exceptions = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandMatchDomainsNever);
-                               exceptionsCount = isA_CFArray(exceptions) ? CFArrayGetCount(exceptions) : 0;
-                               for (exceptionsIndex = 0; exceptionsIndex < exceptionsCount; exceptionsIndex++) {
-                                       CFStringRef     exception;
+                                       /* we found an conditional connection enabled configuration */
 
 
-                                       exception = CFArrayGetValueAtIndex(exceptions, exceptionsIndex);
-                                       if (!isA_CFString(exception)) {
-                                               // if not a valid match exception
+                                       /* check domain */
+                                       domains = CFDictionaryGetValue(pppConfig, kSCPropNetPPPOnDemandDomains);
+                                       if (!isA_CFArray(domains)) {
                                                continue;
                                        }
 
                                                continue;
                                        }
 
-                                       if (_SC_domainEndsWithDomain(hostName, exception)) {
-                                               // found matching exception
-                                               if (_sc_debug || (debug > 0)) {
-                                                       SCLog(TRUE, LOG_INFO, CFSTR("OnDemand match exception"));
+                                       domainsCount = CFArrayGetCount(domains);
+                                       for (domainsIndex = 0; domainsIndex < domainsCount; domainsIndex++) {
+                                               CFStringRef     domain;
+
+                                               domain = CFArrayGetValueAtIndex(domains, domainsIndex);
+                                               if (!isA_CFString(domain)) {
+                                                       continue;
+                                               }
+
+                                               if (!catchAllFound &&
+                                                   (CFStringCompare(domain, CFSTR(""), 0) == kCFCompareEqualTo
+                                                       || CFStringCompare(domain, CFSTR("."), 0) == kCFCompareEqualTo))
+                                               {
+                                                       // found a catch all
+                                                       catchAllFound = TRUE;
+                                                       catchAllService = serviceIndex;
+                                                       catchAllConfig = configIndex;
+                                               }
+
+                                               if (_SC_domainEndsWithDomain(hostName, domain)) {
+                                                       // found matching configuration
+                                                       *serviceID = serviceName;
+                                                       CFRetain(*serviceID);
+                                                       *userOptions = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                                                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName, hostName);
+                                                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCPropNetPPPOnDemandPriority, priority);
+                                                       addPasswordFromKeychain(*serviceID, userOptions);
+                                                       success = TRUE;
+                                                       goto done_selection;
                                                }
                                                }
-                                               goto done;
                                        }
                                }
                                        }
                                }
+                       }
+               }
 
 
-                               // if we have a matching domain and there were no exceptions
-                               // then we pass back the OnDemand info
+               // config not found, do we have a catchall ?
+               if (catchAllFound) {
+                       CFDictionaryRef config;
+                       CFArrayRef      serviceConfigs;
+                       CFStringRef     serviceName;
 
 
-                               ok = TRUE;
+                       serviceName = CFArrayGetValueAtIndex(serviceNames, catchAllService);
+                       serviceConfigs = CFDictionaryGetValue(services, serviceName);
+                       config = CFArrayGetValueAtIndex(serviceConfigs, catchAllConfig);
 
 
-                               if (!CFDictionaryGetValueIfPresent(trigger,
-                                                                  kSCNetworkConnectionOnDemandStatus,
-                                                                  (const void **)&num) ||
-                                   !isA_CFNumber(num) ||
-                                   !CFNumberGetValue(num, kCFNumberSInt32Type, &onDemandStatus)) {
-                                       onDemandStatus = kSCNetworkConnectionDisconnected;
-                               }
-                               if (connectionStatus != NULL) {
-                                       *connectionStatus = onDemandStatus;
-                               }
+                       *serviceID = serviceName;
+                       CFRetain(*serviceID);
+                       *userOptions = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName, hostName);
+                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCPropNetPPPOnDemandPriority, priority);
+                       addPasswordFromKeychain(*serviceID, userOptions);
+                       success = TRUE;
+                       goto done_selection;
+               }
 
 
-                               if (connectionServiceID != NULL) {
-                                       *connectionServiceID = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandServiceID);
-                                       *connectionServiceID = isA_CFString(*connectionServiceID);
-                                       if ((*connectionServiceID != NULL) && (CFStringGetLength(*connectionServiceID) > 0)) {
-                                               CFRetain(*connectionServiceID);
-                                       } else {
-                                               SCLog(TRUE, LOG_INFO,
-                                                     CFSTR("OnDemand%s configuration error, no serviceID"),
-                                                     onDemandRetry ? " (on retry)" : "");
-
-                                               *connectionServiceID = NULL;
-                                               ok = FALSE;
-                                       }
-                               }
+           done_selection:
 
 
-                               if (vpnRemoteAddress != NULL) {
-                                       *vpnRemoteAddress = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandRemoteAddress);
-                                       *vpnRemoteAddress = isA_CFString(*vpnRemoteAddress);
-                                       if ((*vpnRemoteAddress != NULL) && (CFStringGetLength(*vpnRemoteAddress) > 0)) {
-                                               CFRetain(*vpnRemoteAddress);
-                                       } else {
-                                               SCLog(TRUE, LOG_INFO,
-                                                     CFSTR("OnDemand%s configuration error, no server address"),
-                                                     onDemandRetry ? " (on retry)" : "");
-
-                                               *vpnRemoteAddress = NULL;
-                                               ok = FALSE;
-                                       }
-                               }
+               if (serviceNames) {
+                       CFRelease(serviceNames);
+               }
+               if (services) {
+                       CFRelease(services);
+               }
 
 
-                               if (!ok) {
-                                       if ((connectionServiceID != NULL) && (*connectionServiceID != NULL)) {
-                                               CFRelease(*connectionServiceID);
-                                               *connectionServiceID = NULL;
-                                       }
-                                       if ((vpnRemoteAddress != NULL) && (*vpnRemoteAddress != NULL)) {
-                                               CFRelease(*vpnRemoteAddress);
-                                               *vpnRemoteAddress = NULL;
-                                       }
-                                       continue;
-                               }
+               if (debug > 1) {
+                       SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionCopyUserPreferences %@"), success ? CFSTR("succeeded") : CFSTR("failed"));
+                       SCLog(TRUE, LOG_DEBUG, CFSTR("Selection options: %@"), selectionOptions);
+               }
 
 
-                               if (_sc_debug || (debug > 0)) {
-                                       SCLog(TRUE, LOG_INFO,
-                                             CFSTR("OnDemand%s match, connection status = %d"),
-                                             onDemandRetry ? " (on retry)" : "",
-                                             onDemandStatus);
-                               }
+               return success;
+       }
 
 
-                               goto done;
+       /* we don't have selection options */
+
+       // (1) Figure out which service ID we care about, allocate it into passed "serviceID"
+       success = SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(serviceID);
+
+       if (success && (*serviceID != NULL)) {
+               // (2) Get the list of user data for this service ID
+               CFPropertyListRef       userServices    = NULL;
+
+
+               // (3) We are expecting an array if the user has defined records for this service ID or NULL if the user hasn't
+               if (userServices != NULL) {
+                       if (isA_CFArray(userServices)) {
+                               // (4) Get the default set of user options for this service
+                               success = SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray((CFArrayRef)userServices,
+                                                                                                   userOptions);
+                               if(success && (userOptions != NULL)) {
+                                       addPasswordFromKeychain(*serviceID, userOptions);
+                               }
+                       } else {
+                               SCLog(TRUE, LOG_DEBUG, CFSTR("Error, userServices are not of type CFArray!"));
                        }
                        }
+
+                       CFRelease(userServices); // this is OK because SCNetworkConnectionPrivateISExpectedCFType() checks for NULL
                }
        }
 
                }
        }
 
-//     if (_sc_debug || (debug > 0)) {
-//             SCLog(TRUE, LOG_INFO, CFSTR("OnDemand domain name(s) not matched"));
-//     }
-
-    done :
+       if (debug > 1) {
+               SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionCopyUserPreferences %@, no selection options"), success ? CFSTR("succeeded") : CFSTR("failed"));
+       }
 
 
-       if (configuration != NULL) CFRelease(configuration);
-       return ok;
+       return success;
 }
 
 
 }
 
 
@@ -2202,10 +3593,7 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef   selectionOptions,
                                       CFStringRef      *serviceID,
                                       CFDictionaryRef  *userOptions)
 {
                                       CFStringRef      *serviceID,
                                       CFDictionaryRef  *userOptions)
 {
-       int                     prefsChanged    = 1;
-       SCDynamicStoreRef       session         = NULL;
-       Boolean                 success         = FALSE;
-       int                     status;
+       Boolean success = FALSE;
 
 
        /* initialize runtime */
 
 
        /* initialize runtime */
@@ -2218,14 +3606,14 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef  selectionOptions,
                hostName = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName);
                if (isA_CFString(hostName)) {
                        CFStringRef                     connectionServiceID     = NULL;
                hostName = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName);
                if (isA_CFString(hostName)) {
                        CFStringRef                     connectionServiceID     = NULL;
-                       SCNetworkConnectionStatus       connectionStatus;
+                       SCNetworkConnectionStatus       connectionStatus        = kSCNetworkConnectionInvalid;
                        Boolean                         onDemandRetry;
                        CFTypeRef                       val;
 
                        val = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandRetry);
                        onDemandRetry = isA_CFBoolean(val) ? CFBooleanGetValue(val) : TRUE;
 
                        Boolean                         onDemandRetry;
                        CFTypeRef                       val;
 
                        val = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandRetry);
                        onDemandRetry = isA_CFBoolean(val) ? CFBooleanGetValue(val) : TRUE;
 
-                       success = __SCNetworkConnectionCopyOnDemandInfoWithName(&session,
+                       success = __SCNetworkConnectionCopyOnDemandInfoWithName(NULL,
                                                                                hostName,
                                                                                onDemandRetry,
                                                                                &connectionServiceID,
                                                                                hostName,
                                                                                onDemandRetry,
                                                                                &connectionServiceID,
@@ -2240,9 +3628,6 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef    selectionOptions,
 
                        if (success) {
                                // if the hostname matches an OnDemand domain
 
                        if (success) {
                                // if the hostname matches an OnDemand domain
-                               if (session != NULL) {
-                                       CFRelease(session);
-                               }
                                if (connectionStatus == kSCNetworkConnectionConnected) {
                                        // if we are already connected
                                        if (connectionServiceID != NULL) {
                                if (connectionStatus == kSCNetworkConnectionConnected) {
                                        // if we are already connected
                                        if (connectionServiceID != NULL) {
@@ -2258,232 +3643,580 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef        selectionOptions,
                        } else if (!onDemandRetry) {
                                // if the hostname does not match an OnDemand domain and we have
                                // not yet issued an initial DNS query (i.e. it's not a query
                        } else if (!onDemandRetry) {
                                // if the hostname does not match an OnDemand domain and we have
                                // not yet issued an initial DNS query (i.e. it's not a query
-                               // being retried after the VPN has been established) than we're
+                               // being retried after the VPN has been established) then we're
                                // done
                                // done
-                               if (session != NULL) {
-                                       CFRelease(session);
-                               }
                                return FALSE;
                        }
                }
        }
 
                                return FALSE;
                        }
                }
        }
 
-       if (notify_userprefs_token == -1) {
-               status = notify_register_check(k_NetworkConnect_Notification, &notify_userprefs_token);
-               if (status != NOTIFY_STATUS_OK) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("notify_register_check() failed, status=%lu"), status);
-                       (void)notify_cancel(notify_userprefs_token);
-                       notify_userprefs_token = -1;
+       return __SCNetworkConnectionCopyUserPreferencesInternal(selectionOptions, serviceID, userOptions);
+}
+
+
+Boolean
+SCNetworkConnectionOnDemandShouldRetryOnFailure (SCNetworkConnectionRef connection)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       CFDictionaryRef                 match_info              = NULL;
+
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               goto fail;
+       }
+
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               goto fail;
+       }
+
+       if (isA_CFDictionary(connectionPrivate->on_demand_user_options)) {
+               match_info = CFDictionaryGetValue(connectionPrivate->on_demand_user_options, kSCNetworkConnectionSelectionOptionOnDemandMatchInfo);
+               if (isA_CFDictionary(match_info)) {
+                       CFBooleanRef onRetry = CFDictionaryGetValue(match_info, kSCNetworkConnectionOnDemandMatchInfoOnRetry);
+                       if (isA_CFBoolean(onRetry)) {
+                               return CFBooleanGetValue(onRetry);
+                       }
+               }
+       }
+
+    fail:
+       return FALSE;
+}
+
+
+// Mask is optional in routes dictionary; if not present, whole addresses are matched
+Boolean
+__SCNetworkConnectionIPv4AddressMatchesRoutes (struct sockaddr_in *addr_in, CFDictionaryRef routes)
+{
+       int             count;
+       int             i;
+       CFDataRef       maskData        = NULL;
+       struct in_addr  *maskDataArray;
+       CFDataRef       routeaddrData   = NULL;
+       struct in_addr  *routeaddrDataArray;
+
+       if (!isA_CFDictionary(routes)) {
+               return FALSE;
+       }
+
+       routeaddrData = CFDictionaryGetValue(routes, kSCNetworkConnectionNetworkInfoAddresses);
+       maskData = CFDictionaryGetValue(routes, kSCNetworkConnectionNetworkInfoMasks);
+
+       /* routeaddrData and maskData are packed arrays of addresses; make sure they have the same length */
+       if (!isA_CFData(routeaddrData) || (maskData && (!isA_CFData(maskData) || CFDataGetLength(routeaddrData) != CFDataGetLength(maskData)))) {
+               return FALSE;
+       }
+
+       routeaddrDataArray = (struct in_addr*)(void*)CFDataGetBytePtr(routeaddrData);
+       if (maskData) {
+               maskDataArray = (struct in_addr*)(void*)CFDataGetBytePtr(maskData);
+       }
+
+       count = CFDataGetLength(routeaddrData) / sizeof(struct in_addr);
+
+       for (i=0; i<count; i++) {
+               struct in_addr  routeAddr       = *routeaddrDataArray;
+
+               if (maskData) {
+                       struct in_addr  mask    = *maskDataArray;
+
+                       if ((addr_in->sin_addr.s_addr & mask.s_addr) == (routeAddr.s_addr & mask.s_addr)) {
+                               return TRUE;
+                       }
+                       maskDataArray++;
                } else {
                } else {
-                       // clear the "something has changed" state
-                       (void) notify_check(notify_userprefs_token, &prefsChanged);
-                       prefsChanged = 1;
+                       if (addr_in->sin_addr.s_addr == routeAddr.s_addr) {
+                               return TRUE;
+                       }
                }
                }
+               routeaddrDataArray++;
        }
        }
-       if (notify_userprefs_token != -1) {
-               status = notify_check(notify_userprefs_token, &prefsChanged);
-               if (status != NOTIFY_STATUS_OK) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("notify_check() failed, status=%lu"), status);
-                       (void)notify_cancel(notify_userprefs_token);
-                       notify_userprefs_token = -1;
+       return FALSE;
+}
+
+
+void
+__SCNetworkConnectionMaskIPv6Address(struct in6_addr *addr, struct in6_addr *mask)
+{
+       int     i;
+
+       for (i = 0; i < sizeof(struct in6_addr); i++)
+               addr->s6_addr[i] &= mask->s6_addr[i];
+}
+
+
+// Mask is optional in routes dictionary; if not present, whole addresses are matched
+Boolean
+__SCNetworkConnectionIPv6AddressMatchesRoutes (struct sockaddr_in6 *addr_in6, CFDictionaryRef routes)
+{
+       int             count;
+       int             i;
+       CFDataRef       maskData        = NULL;
+       struct in6_addr *maskDataArray;
+       CFDataRef       routeaddrData   = NULL;
+       struct in6_addr *routeaddrDataArray;
+
+       if (!isA_CFDictionary(routes)) {
+               return FALSE;
+       }
+
+       routeaddrData = CFDictionaryGetValue(routes, kSCNetworkConnectionNetworkInfoAddresses);
+       maskData = CFDictionaryGetValue(routes, kSCNetworkConnectionNetworkInfoMasks);
+
+       /* routeaddrData and maskData are packed arrays of addresses; make sure they have the same length */
+       if (!isA_CFData(routeaddrData) || (maskData && (!isA_CFData(maskData) || CFDataGetLength(routeaddrData) != CFDataGetLength(maskData)))) {
+               return FALSE;
+       }
+
+       routeaddrDataArray = (struct in6_addr*)(void*)CFDataGetBytePtr(routeaddrData);
+       if (maskData) {
+               maskDataArray = (struct in6_addr*)(void*)CFDataGetBytePtr(maskData);
+       }
+
+       count = CFDataGetLength(routeaddrData) / sizeof(struct in6_addr);
+
+       for (i=0; i<count; i++) {
+               if (maskData) {
+                       struct in6_addr cmpAddr;
+                       struct in6_addr *mask = maskDataArray;
+                       struct in6_addr routeAddr;
+
+                       memcpy(&routeAddr, routeaddrDataArray, sizeof(routeAddr));
+                       memcpy(&cmpAddr, &addr_in6->sin6_addr, sizeof(cmpAddr));
+                       __SCNetworkConnectionMaskIPv6Address(&routeAddr, mask);
+                       __SCNetworkConnectionMaskIPv6Address(&cmpAddr, mask);
+                       maskDataArray++;
+                       if (!memcmp(&routeAddr, &cmpAddr, sizeof(routeAddr))) {
+                               return TRUE;
+                       }
+               } else {
+                       if (!memcmp(routeaddrDataArray, &addr_in6->sin6_addr, sizeof(struct in6_addr))) {
+                               return TRUE;
+                       }
                }
                }
+
+               routeaddrDataArray++;
        }
        }
+       return FALSE;
+}
 
 
 
 
-       *serviceID = NULL;
-       *userOptions = NULL;
+static Boolean
+__SCNetworkConnectionAddressMatchesRedirectedDNS(CFDictionaryRef trigger, const struct sockaddr *input_addr)
+{
+       CFBooleanRef redirectedRef = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandDNSRedirectDetected);
 
 
-       if (session == NULL) {
-               session = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkConnection"), NULL, NULL);
+       if (isA_CFBoolean(redirectedRef) && CFBooleanGetValue(redirectedRef)) {
+               /* DNS is redirected. Look for address list. */
+               CFDictionaryRef redirectedAddressesRef = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandDNSRedirectedAddresses);
+
+               if (isA_CFDictionary(redirectedAddressesRef)) {
+                       if (input_addr->sa_family == AF_INET) {
+                               return __SCNetworkConnectionIPv4AddressMatchesRoutes((struct sockaddr_in*)(void*)input_addr, CFDictionaryGetValue(redirectedAddressesRef, kSCNetworkConnectionNetworkInfoIPv4));
+                       } else if (input_addr->sa_family == AF_INET6) {
+                               return __SCNetworkConnectionIPv6AddressMatchesRoutes((struct sockaddr_in6*)(void*)input_addr, CFDictionaryGetValue(redirectedAddressesRef, kSCNetworkConnectionNetworkInfoIPv6));
+                       }
+               }
        }
        }
-       if (session == NULL) {
-               SCLog(TRUE, LOG_ERR, CFSTR("Error,  SCNetworkConnectionCopyUserPreferences, SCDynamicStoreCreate() returned NULL!"));
+
+       return FALSE;
+}
+
+/* If the required probe has failed, we need to tunnel the address. Equivalent to redirected DNS. */
+static Boolean
+__SCNetworkConnectionRequiredProbeFailed (CFDictionaryRef trigger, CFStringRef probeString)
+{
+       CFDictionaryRef probeResults = NULL;
+
+       if (!isA_CFString(probeString)) {
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if (selectionOptions != NULL) {
-               Boolean         catchAllFound   = FALSE;
-               CFIndex         catchAllService = 0;
-               CFIndex         catchAllConfig  = 0;
-               CFStringRef     hostName        = NULL;
-               CFStringRef     priority        = NULL;
-               CFArrayRef      serviceNames    = NULL;
-               CFDictionaryRef services        = NULL;
-               CFIndex         serviceIndex;
-               CFIndex         servicesCount;
+       probeResults = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandProbeResults);
+       if (!isA_CFDictionary(probeResults)) {
+               return TRUE;
+       }
 
 
-               hostName = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName);
-               if (hostName == NULL) {
-                       hostName = CFDictionaryGetValue(selectionOptions, kSCPropNetPPPOnDemandHostName);
-               }
-               hostName = isA_CFString(hostName);
-               if (hostName == NULL)
-                       goto done_selection;    // if no hostname for matching
+       CFBooleanRef result = CFDictionaryGetValue(probeResults, probeString);
 
 
-               priority = CFDictionaryGetValue(selectionOptions, kSCPropNetPPPOnDemandPriority);
-               if (!isA_CFString(priority))
-                       priority = kSCValNetPPPOnDemandPriorityDefault;
+       /* Only a value of kCFBooleanFalse marks the probe as failed  */
+       return (isA_CFBoolean(result) && !CFBooleanGetValue(result));
+}
 
 
+Boolean
+SCNetworkConnectionCanTunnelAddress (SCNetworkConnectionRef connection, const struct sockaddr *address, Boolean *startImmediately)
+{
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       CFStringRef                     serviceID               = NULL;
+       CFDictionaryRef                 configuration           = NULL;
+       CFDictionaryRef                 trigger                 = NULL;
+       CFDictionaryRef                 tunneledNetworks        = NULL;
+       sa_family_t                     address_family          = AF_UNSPEC;
+       Boolean                         success                 = FALSE;
 
 
-               if (!isA_CFArray(serviceNames))
-                       goto done_selection;
+       if (startImmediately) {
+               *startImmediately = FALSE;
+       }
 
 
+       if (address == NULL) {
+               goto done;
+       }
 
 
-               if (!isA_CFDictionary(services))
-                       goto done_selection;
+       address_family = address->sa_family;
+       if (address_family != AF_INET && address_family != AF_INET6) {
+               goto done;
+       }
 
 
-               servicesCount = CFArrayGetCount(serviceNames);
-               for (serviceIndex = 0; serviceIndex < servicesCount; serviceIndex++) {
-                       CFIndex         configIndex;
-                       CFIndex         configsCount;
-                       CFArrayRef      serviceConfigs;
-                       CFStringRef     serviceName;
-                       int             val;
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               goto done;
+       }
 
 
-                       serviceName = CFArrayGetValueAtIndex(serviceNames, serviceIndex);
-                       if (!isA_CFString(serviceName))
-                               continue;
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusConnectionNoService);
+               goto done;
+       }
 
 
-                       serviceConfigs = CFDictionaryGetValue(services, serviceName);
-                       if (!isA_CFArray(serviceConfigs))
-                               continue;
+       serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service);
+       if (!isA_CFString(serviceID)) {
+               goto done;
+       }
 
 
-                       configsCount = CFArrayGetCount(serviceConfigs);
-                       for (configIndex = 0; configIndex < configsCount; configIndex++) {
-                               CFNumberRef     autodial;
-                               CFDictionaryRef config;
-                               CFDictionaryRef pppConfig;
+       configuration = __SCNetworkConnectionCopyOnDemandConfiguration();
+       if (configuration == NULL) {
+               goto done;
+       }
 
 
-                               config = CFArrayGetValueAtIndex(serviceConfigs, configIndex);
-                               if (!isA_CFDictionary(config))
-                                       continue;
+       trigger = __SCNetworkConnectionCopyTriggerWithService(configuration, serviceID);
+       if (trigger == NULL) {
+               goto done;
+       }
 
 
-                               pppConfig = CFDictionaryGetValue(config, kSCEntNetPPP);
-                               if (!isA_CFDictionary(pppConfig))
-                                       continue;
+       if (__SCNetworkConnectionRequiredProbeFailed(trigger, connectionPrivate->on_demand_required_probe)) {
+               /* If probe failed, we can't trust DNS - connect now */
+               if (startImmediately) {
+                       *startImmediately = TRUE;
+               }
+               success = TRUE;
+               goto done;
+       }
 
 
-                               autodial = CFDictionaryGetValue(pppConfig, kSCPropNetPPPOnDemandEnabled);
-                               if (!isA_CFNumber(autodial))
-                                       continue;
+       if (__SCNetworkConnectionAddressMatchesRedirectedDNS(trigger, address)) {
+               if (startImmediately) {
+                       *startImmediately = TRUE;
+               }
+               success = TRUE;
+               goto done;
+       }
 
 
-                               CFNumberGetValue(autodial, kCFNumberIntType, &val);
-                               if (val) {
-                                       CFArrayRef      domains;
-                                       CFIndex         domainsCount;
-                                       CFIndex         domainsIndex;
+       tunneledNetworks = CFDictionaryGetValue(trigger, kSCNetworkConnectionOnDemandTunneledNetworks);
+       if (!isA_CFDictionary(tunneledNetworks)) {
+               goto done;
+       }
 
 
-                                       /* we found an conditional connection enabled configuration */
+       if (address_family == AF_INET) {
+               CFDictionaryRef ip_dict;
+               Boolean matches = FALSE;
+               struct sockaddr_in *addr_in = (struct sockaddr_in *)(void*)address;
 
 
-                                       /* check domain */
-                                       domains = CFDictionaryGetValue(pppConfig, kSCPropNetPPPOnDemandDomains);
-                                       if (!isA_CFArray(domains))
-                                               continue;
+               ip_dict = CFDictionaryGetValue(tunneledNetworks, kSCNetworkConnectionNetworkInfoIPv4);
+               if (!isA_CFDictionary(ip_dict)) {
+                       goto done;
+               }
 
 
-                                       domainsCount = CFArrayGetCount(domains);
-                                       for (domainsIndex = 0; domainsIndex < domainsCount; domainsIndex++) {
-                                               CFStringRef     domain;
+               matches = __SCNetworkConnectionIPv4AddressMatchesRoutes(addr_in, CFDictionaryGetValue(ip_dict, kSCNetworkConnectionNetworkInfoIncludedRoutes));
 
 
-                                               domain = CFArrayGetValueAtIndex(domains, domainsIndex);
-                                               if (!isA_CFString(domain))
-                                                       continue;
+               if (matches) {
+                       if (!__SCNetworkConnectionIPv4AddressMatchesRoutes(addr_in, CFDictionaryGetValue(ip_dict, kSCNetworkConnectionNetworkInfoExcludedRoutes))) {
+                               success = TRUE;
+                               goto done;
+                       }
+               }
+       } else {
+               CFDictionaryRef ip6_dict;
+               Boolean matches = FALSE;
+               struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)(void*)address;
 
 
-                                               if (!catchAllFound &&
-                                                   (CFStringCompare(domain, CFSTR(""), 0) == kCFCompareEqualTo
-                                                       || CFStringCompare(domain, CFSTR("."), 0) == kCFCompareEqualTo)) {
-                                                       // found a catch all
-                                                       catchAllFound = TRUE;
-                                                       catchAllService = serviceIndex;
-                                                       catchAllConfig = configIndex;
-                                               }
+               ip6_dict = CFDictionaryGetValue(tunneledNetworks, kSCNetworkConnectionNetworkInfoIPv6);
+               if (!isA_CFDictionary(ip6_dict)) {
+                       goto done;
+               }
 
 
-                                               if (_SC_domainEndsWithDomain(hostName, domain)) {
-                                                       // found matching configuration
-                                                       *serviceID = serviceName;
-                                                       CFRetain(*serviceID);
-                                                       *userOptions = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                                                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName, hostName);
-                                                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCPropNetPPPOnDemandPriority, priority);
-                                                       addPasswordFromKeychain(session, *serviceID, userOptions);
-                                                       success = TRUE;
-                                                       goto done_selection;
-                                               }
-                                       }
-                               }
+               matches = __SCNetworkConnectionIPv6AddressMatchesRoutes(addr_in6, CFDictionaryGetValue(ip6_dict, kSCNetworkConnectionNetworkInfoIncludedRoutes));
+
+               if (matches) {
+                       if (!__SCNetworkConnectionIPv6AddressMatchesRoutes(addr_in6, CFDictionaryGetValue(ip6_dict, kSCNetworkConnectionNetworkInfoExcludedRoutes))) {
+                               success = TRUE;
+                               goto done;
                        }
                }
                        }
                }
+       }
+done:
+       if (configuration) {
+               CFRelease(configuration);
+       }
+       if (trigger) {
+               CFRelease(trigger);
+       }
+       return success;
+}
 
 
-               // config not found, do we have a catchall ?
-               if (catchAllFound) {
-                       CFDictionaryRef config;
-                       CFArrayRef      serviceConfigs;
-                       CFStringRef     serviceName;
+Boolean
+SCNetworkConnectionSelectServiceWithOptions(SCNetworkConnectionRef connection, CFDictionaryRef selectionOptions)
+{
+       CFStringRef                     account_identifier      = NULL;
+       CFDictionaryRef                 configuration           = NULL;
+       SCNetworkConnectionPrivateRef   connectionPrivate       = (SCNetworkConnectionPrivateRef)connection;
+       CFDictionaryRef                 found_trigger           = NULL;
+       CFStringRef                     host_name               = NULL;
+       Boolean                         is_retry                = TRUE;
+       CFDictionaryRef                 match_info              = NULL;
+       CFMutableDictionaryRef          new_user_options        = NULL;
+       SCNetworkConnectionStatus       on_demand_status        = kSCNetworkConnectionInvalid;
+       CFStringRef                     requiredProbe           = NULL;
+       CFStringRef                     service_id              = NULL;
+       Boolean                         skip_prefs              = FALSE;
+       Boolean                         success                 = TRUE;
+       CFDictionaryRef                 user_options            = NULL;
 
 
-                       serviceName = CFArrayGetValueAtIndex(serviceNames, catchAllService);
-                       serviceConfigs = CFDictionaryGetValue(services, serviceName);
-                       config = CFArrayGetValueAtIndex(serviceConfigs, catchAllConfig);
+       if (!isA_SCNetworkConnection(connection)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               success = FALSE;
+               goto done;
+       }
 
 
-                       *serviceID = serviceName;
-                       CFRetain(*serviceID);
-                       *userOptions = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName, hostName);
-                       CFDictionarySetValue((CFMutableDictionaryRef)*userOptions, kSCPropNetPPPOnDemandPriority, priority);
-                       addPasswordFromKeychain(session, *serviceID, userOptions);
-                       success = TRUE;
-                       goto done_selection;
+       /* Can't call this on a connection that is already associated with a service */
+       if (connectionPrivate->service != NULL) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               success = FALSE;
+               goto done;
+       }
+
+       if (isA_CFDictionary(selectionOptions)) {
+               CFBooleanRef no_user_prefs = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionNoUserPrefs);
+               CFBooleanRef retry = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandRetry);
+
+               account_identifier = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandAccountIdentifier);
+               host_name = CFDictionaryGetValue(selectionOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName);
+               skip_prefs = (isA_CFBoolean(no_user_prefs) && CFBooleanGetValue(no_user_prefs));
+
+               if (isA_CFBoolean(retry)) {
+                       is_retry = CFBooleanGetValue(retry);
                }
                }
+       }
 
 
-           done_selection:
+       configuration = __SCNetworkConnectionCopyOnDemandConfiguration();
+
+       /* First, check for a match with the App Layer rules */
+       service_id = VPNAppLayerCopyMatchingService(connectionPrivate->client_audit_token,
+                                                   connectionPrivate->client_pid,
+                                                   connectionPrivate->client_uuid,
+                                                   connectionPrivate->client_bundle_id,
+                                                   host_name,
+                                                   account_identifier,
+                                                   &match_info);
+       if (service_id != NULL) {
+               Boolean use_app_layer   = TRUE;
+
+               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);
+                               }
+                               /*
+                                * 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)
+                               {
+                                       use_app_layer = FALSE;
+                               }
+                       }
+               }
 
 
-               if (serviceNames)
-                       CFRelease(serviceNames);
-               if (services)
-                       CFRelease(services);
-               CFRelease(session);
+               if (use_app_layer) {
+                       /* If this is not the 'OnRetry' call, and the service has not yet started, the match may need to return false */
+                       if (!is_retry &&
+                           match_info != NULL &&
+                           on_demand_status != kSCNetworkConnectionConnecting &&
+                           on_demand_status != kSCNetworkConnectionConnected) {
+                               CFBooleanRef matchedOnRetry = CFDictionaryGetValue(match_info, kSCNetworkConnectionOnDemandMatchInfoOnRetry);
+                               if (matchedOnRetry && CFBooleanGetValue(matchedOnRetry)) {
+                                       /* Don't return that we matched always; wait for SCNetworkConnectionOnDemandShouldRetryOnFailure */
+                                       success = FALSE;
+                               }
+                       }
+                       connectionPrivate->type = kSCNetworkConnectionTypeAppLayerVPN;
+                       goto search_done;
+               } else {
+                       CFRelease(service_id);
+                       service_id = NULL;
+                       if (match_info != NULL) {
+                               CFRelease(match_info);
+                               match_info = NULL;
+                       }
+                       if (found_trigger != NULL) {
+                               CFRelease(found_trigger);
+                               found_trigger = NULL;
+                       }
+               }
+       }
 
 
-               if (debug > 1) {
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionCopyUserPreferences %@"), success ? CFSTR("succeeded") : CFSTR("failed"));
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("Selection options: %@"), selectionOptions);
+       /* Next, check the IP layer rules */
+       if (isA_CFDictionary(configuration) && host_name != NULL) {
+               Boolean triggerNow      = FALSE;
+
+               found_trigger = __SCNetworkConnectionCopyMatchingTriggerWithName(configuration, host_name, connectionPrivate->client_pid, is_retry, &match_info, &triggerNow, &requiredProbe);
+               if (found_trigger != NULL) {
+                       service_id = CFDictionaryGetValue(found_trigger, kSCNetworkConnectionOnDemandServiceID);
+                       if (isA_CFString(service_id)) {
+                               CFRetain(service_id);
+                               connectionPrivate->type = kSCNetworkConnectionTypeIPLayerVPN;
+                       } else {
+                               service_id = NULL;
+                       }
+                       if (!triggerNow) {
+                               success = FALSE;
+                       }
+                       goto search_done;
+               } else if (!is_retry) {
+                       goto search_done;
                }
 
                }
 
-               return success;
+               if (match_info != NULL) {
+                       CFRelease(match_info);
+                       match_info = NULL;
+               }
        }
 
        }
 
-       /* we don't have selection options */
+       /* Next, check the user preferences */
+       if (!skip_prefs && __SCNetworkConnectionCopyUserPreferencesInternal(selectionOptions, &service_id, &user_options)) {
+               CFMutableDictionaryRef  minfo;
+               CFNumberRef             type_num;
 
 
-       // (1) Figure out which service ID we care about, allocate it into passed "serviceID"
-       success = SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(session, serviceID);
+               if (isA_CFDictionary(configuration)) {
+                       found_trigger = __SCNetworkConnectionCopyTriggerWithService(configuration, service_id);
+               }
+               connectionPrivate->type = kSCNetworkConnectionTypePPP;
+
+               minfo = CFDictionaryCreateMutable(NULL,
+                                                 0,
+                                                 &kCFTypeDictionaryKeyCallBacks,
+                                                 &kCFTypeDictionaryValueCallBacks);
+               type_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &connectionPrivate->type);
+               CFDictionarySetValue(minfo, kSCNetworkConnectionOnDemandMatchInfoVPNType, type_num);
+               CFRelease(type_num);
+               match_info = minfo;
+               goto search_done;
+       }
+
+search_done:
+       if (service_id == NULL) {
+               _SCErrorSet(kSCStatusOK);
+               success = FALSE;
+               goto done;
+       }
 
 
-       if (success && (*serviceID != NULL)) {
-               // (2) Get the list of user data for this service ID
-               CFPropertyListRef       userServices    = NULL;
+       connectionPrivate->service = _SCNetworkServiceCopyActive(NULL, service_id);
+       if (connectionPrivate->service == NULL) {
+               _SCErrorSet(kSCStatusOK);
+               success = FALSE;
+               goto done;
+       }
 
 
+       if (found_trigger != NULL) {
+               if (connectionPrivate->on_demand_info) {
+                     CFRelease(connectionPrivate->on_demand_info);
+               }
+               connectionPrivate->on_demand_info = found_trigger;
+               CFRetain(connectionPrivate->on_demand_info);
 
 
-               // (3) We are expecting an array if the user has defined records for this service ID or NULL if the user hasn't
-               if (userServices != NULL) {
-                       if (isA_CFArray(userServices)) {
-                               // (4) Get the default set of user options for this service
-                               success = SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray((CFArrayRef)userServices,
-                                                                                                   userOptions);
-                               if(success && (userOptions != NULL)) {
-                                       addPasswordFromKeychain(session, *serviceID, userOptions);
+               if (on_demand_status == kSCNetworkConnectionInvalid) {
+                       CFNumberRef status_num = CFDictionaryGetValue(found_trigger, kSCNetworkConnectionOnDemandStatus);
+                       if (isA_CFNumber(status_num)) {
+                               CFNumberGetValue(status_num, kCFNumberIntType, &on_demand_status);
+                       }
+               }
+
+               if (on_demand_status != kSCNetworkConnectionConnected) {
+                       if (connectionPrivate->type == kSCNetworkConnectionTypeAppLayerVPN) {
+                               /* Check App Layer on demand flag */
+                               CFBooleanRef app_on_demand_enabled =
+                                       CFDictionaryGetValue(found_trigger, kSCNetworkConnectionOnDemandMatchAppEnabled);
+                               if (isA_CFBoolean(app_on_demand_enabled) && CFBooleanGetValue(app_on_demand_enabled)) {
+                                       connectionPrivate->on_demand = TRUE;
                                }
                        } else {
                                }
                        } else {
-                               SCLog(TRUE, LOG_DEBUG, CFSTR("Error, userServices are not of type CFArray!"));
+                               connectionPrivate->on_demand = TRUE;
                        }
                        }
-
-                       CFRelease(userServices); // this is OK because SCNetworkConnectionPrivateISExpectedCFType() checks for NULL
                }
                }
+       } else if (connectionPrivate->type == kSCNetworkConnectionTypePPP) {
+               /* If we got the service from __SCNetworkConnectionCopyUserPreferencesInternal, then it's on demand */
+               connectionPrivate->on_demand = TRUE;
        }
 
        }
 
-       if (debug > 1) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("SCNetworkConnectionCopyUserPreferences %@, no selection options"), success ? CFSTR("succeeded") : CFSTR("failed"));
+       if (user_options == NULL) {
+               new_user_options = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                            0,
+                                                            &kCFTypeDictionaryKeyCallBacks,
+                                                            &kCFTypeDictionaryValueCallBacks);
+       } else {
+               new_user_options = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, user_options);
+       }
+
+       if (host_name != NULL) {
+               CFDictionarySetValue(new_user_options, kSCNetworkConnectionSelectionOptionOnDemandHostName, host_name);
+       }
+
+       if (connectionPrivate->on_demand && match_info != NULL) {
+               CFDictionarySetValue(new_user_options, kSCNetworkConnectionSelectionOptionOnDemandMatchInfo, match_info);
+       }
+
+       connectionPrivate->on_demand_user_options = new_user_options;
+       CFRetain(connectionPrivate->on_demand_user_options);
+
+       if (requiredProbe) {
+               connectionPrivate->on_demand_required_probe = requiredProbe;
+               CFRetain(connectionPrivate->on_demand_required_probe);
+       }
+
+done:
+       if (service_id != NULL) {
+               CFRelease(service_id);
+       }
+
+       if (configuration != NULL) {
+               CFRelease(configuration);
+       }
+
+       if (found_trigger != NULL) {
+               CFRelease(found_trigger);
+       }
+
+       if (user_options != NULL) {
+               CFRelease(user_options);
+       }
+
+       if (new_user_options != NULL) {
+               CFRelease(new_user_options);
+       }
+
+       if (match_info != NULL) {
+               CFRelease(match_info);
+       }
+
+       if (requiredProbe != NULL) {
+               CFRelease(requiredProbe);
        }
 
        }
 
-       CFRelease(session);
        return success;
 }
 
        return success;
 }
 
-
 //*******************************************************************************************
 // SCNetworkConnectionPrivateCopyDefaultServiceIDForDial
 // ----------------------------------------------------
 //*******************************************************************************************
 // SCNetworkConnectionPrivateCopyDefaultServiceIDForDial
 // ----------------------------------------------------
@@ -2493,7 +4226,7 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef    selectionOptions,
 //     with the highest ordering
 //********************************************************************************************
 static Boolean
 //     with the highest ordering
 //********************************************************************************************
 static Boolean
-SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, CFStringRef *serviceID)
+SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(CFStringRef *serviceID)
 {
        Boolean                 foundService            = FALSE;
        CFPropertyListRef       lastServiceSelectedInIC = NULL;
 {
        Boolean                 foundService            = FALSE;
        CFPropertyListRef       lastServiceSelectedInIC = NULL;
@@ -2503,7 +4236,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session,
        // we found the service the user last had open in IC
        if (lastServiceSelectedInIC != NULL) {
                // make sure its a PPP service
        // we found the service the user last had open in IC
        if (lastServiceSelectedInIC != NULL) {
                // make sure its a PPP service
-               if (SCNetworkConnectionPrivateIsPPPService(session, lastServiceSelectedInIC, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) {
+               if (SCNetworkConnectionPrivateIsPPPService(lastServiceSelectedInIC, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) {
                        // make sure the service that we found is valid
                        CFDictionaryRef dict;
                        CFStringRef     key;
                        // make sure the service that we found is valid
                        CFDictionaryRef dict;
                        CFStringRef     key;
@@ -2512,7 +4245,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session,
                                                                          kSCDynamicStoreDomainSetup,
                                                                          lastServiceSelectedInIC,
                                                                          kSCEntNetInterface);
                                                                          kSCDynamicStoreDomainSetup,
                                                                          lastServiceSelectedInIC,
                                                                          kSCEntNetInterface);
-                       dict = SCDynamicStoreCopyValue(session, key);
+                       dict = SCDynamicStoreCopyValue(NULL, key);
                        CFRelease(key);
                        if (dict != NULL) {
                                CFRelease(dict);
                        CFRelease(key);
                        if (dict != NULL) {
                                CFRelease(dict);
@@ -2524,7 +4257,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session,
        }
 
        if (!foundService) {
        }
 
        if (!foundService) {
-               foundService = SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(session, serviceID);
+               foundService = SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(serviceID);
        }
 
        return foundService;
        }
 
        return foundService;
@@ -2536,7 +4269,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session,
 // Find the highest ordered PPP service in the dynamic store
 //********************************************************************************
 static Boolean
 // Find the highest ordered PPP service in the dynamic store
 //********************************************************************************
 static Boolean
-SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(SCDynamicStoreRef session, CFStringRef *serviceID)
+SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(CFStringRef *serviceID)
 {
        CFDictionaryRef dict            = NULL;
        CFStringRef     key             = NULL;
 {
        CFDictionaryRef dict            = NULL;
        CFStringRef     key             = NULL;
@@ -2555,7 +4288,7 @@ SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(SCDynamicStoreRef sessio
                        break;
                }
 
                        break;
                }
 
-               dict = SCDynamicStoreCopyValue(session, key);
+               dict = SCDynamicStoreCopyValue(NULL, key);
                if (!isA_CFDictionary(dict)) {
                        fprintf(stderr, "no global IPv4 entity\n");
                        break;
                if (!isA_CFDictionary(dict)) {
                        fprintf(stderr, "no global IPv4 entity\n");
                        break;
@@ -2571,7 +4304,7 @@ SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(SCDynamicStoreRef sessio
                for (i = 0; i < count; i++) {
                        CFStringRef service = CFArrayGetValueAtIndex(serviceIDs, i);
 
                for (i = 0; i < count; i++) {
                        CFStringRef service = CFArrayGetValueAtIndex(serviceIDs, i);
 
-                       if (SCNetworkConnectionPrivateIsPPPService(session, service, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) {
+                       if (SCNetworkConnectionPrivateIsPPPService(service, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) {
                                *serviceID = CFRetain(service);
                                success = TRUE;
                                break;
                                *serviceID = CFRetain(service);
                                success = TRUE;
                                break;
@@ -2625,7 +4358,7 @@ SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(CFArrayRef userOptions
 // Check and see if the service is a PPP service of the given types
 //********************************************************************************
 static Boolean
 // Check and see if the service is a PPP service of the given types
 //********************************************************************************
 static Boolean
-SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2)
+SCNetworkConnectionPrivateIsPPPService(CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2)
 {
        CFStringRef     entityKey;
        Boolean         isPPPService            = FALSE;
 {
        CFStringRef     entityKey;
        Boolean         isPPPService            = FALSE;
@@ -2640,7 +4373,7 @@ SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef se
                return FALSE;
        }
 
                return FALSE;
        }
 
-       serviceDict = SCDynamicStoreCopyValue(session, entityKey);
+       serviceDict = SCDynamicStoreCopyValue(NULL, entityKey);
        if (serviceDict != NULL) {
                if (isA_CFDictionary(serviceDict)) {
                        CFStringRef     type;
        if (serviceDict != NULL) {
                if (isA_CFDictionary(serviceDict)) {
                        CFStringRef     type;
@@ -2672,7 +4405,7 @@ SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef se
 // them to the PPP and IPSec dictionaries
 //********************************************************************************
 static void
 // them to the PPP and IPSec dictionaries
 //********************************************************************************
 static void
-addPasswordFromKeychain(SCDynamicStoreRef session, CFStringRef serviceID, CFDictionaryRef *userOptions)
+addPasswordFromKeychain(CFStringRef serviceID, CFDictionaryRef *userOptions)
 {
        CFPropertyListRef       uniqueID;
        CFStringRef             password;
 {
        CFPropertyListRef       uniqueID;
        CFStringRef             password;
@@ -2691,7 +4424,7 @@ addPasswordFromKeychain(SCDynamicStoreRef session, CFStringRef serviceID, CFDict
        password = copyPasswordFromKeychain(uniqueID);
 
        /* then, if necessary, get the IPSec Shared Secret */
        password = copyPasswordFromKeychain(uniqueID);
 
        /* then, if necessary, get the IPSec Shared Secret */
-       if (SCNetworkConnectionPrivateIsPPPService(session, serviceID, kSCValNetInterfaceSubTypeL2TP, 0)) {
+       if (SCNetworkConnectionPrivateIsPPPService(serviceID, kSCValNetInterfaceSubTypeL2TP, 0)) {
                CFMutableStringRef      uniqueIDSS;
 
                uniqueIDSS = CFStringCreateMutableCopy(NULL, 0, uniqueID);
                CFMutableStringRef      uniqueIDSS;
 
                uniqueIDSS = CFStringCreateMutableCopy(NULL, 0, uniqueID);
@@ -2839,3 +4572,25 @@ copyPasswordFromKeychain(CFStringRef uniqueID)
        return NULL;
 #endif // !TARGET_OS_IPHONE
 }
        return NULL;
 #endif // !TARGET_OS_IPHONE
 }
+
+
+__private_extern__
+char *
+__SCNetworkConnectionGetControllerPortName()
+{
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 70000)) && !TARGET_IPHONE_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{
+                       scnc_server_name = PPPCONTROLLER_SERVER;
+               }
+               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkConnectionGetControllerPortName() returns port: %s"), scnc_server_name);
+       }
+#else
+       scnc_server_name = PPPCONTROLLER_SERVER;
+#endif
+       return scnc_server_name;
+}
+
diff --git a/SystemConfiguration.fproj/SCNetworkConnectionInternal.h b/SystemConfiguration.fproj/SCNetworkConnectionInternal.h
new file mode 100644 (file)
index 0000000..9bef13b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2013 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 _SCNETWORKCONNECTIONINTERNAL_H
+#define _SCNETWORKCONNECTIONINTERNAL_H
+
+#include <sys/cdefs.h>
+
+
+__BEGIN_DECLS
+
+void           __SCNetworkConnectionForceOnDemandConfigurationRefresh(void);
+char *         __SCNetworkConnectionGetControllerPortName(void);
+CFDictionaryRef        __SCNetworkConnectionCopyTokenParameters(SCNetworkConnectionRef connection);
+
+__END_DECLS
+
+#endif /* _SCNETWORKCONNECTIONINTERNAL_H */
index 6e98de14f609251d79db55e239580df3e6d96ac3..7b58f62526f1ee6228f2321b0823c450e631b9fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -399,6 +399,7 @@ processPreferences(CFStringRef                      serviceID,
                CFDictionaryRef dict;
 
                dict = CFArrayGetValueAtIndex(prefs, i);
                CFDictionaryRef dict;
 
                dict = CFArrayGetValueAtIndex(prefs, i);
+               assert(dict != NULL);
                if (isA_CFDictionary(dict)) {
                        newDict = (*callout)(serviceID, dict, context1, context2, context3);
                        if (newDict == NULL) {
                if (isA_CFDictionary(dict)) {
                        newDict = (*callout)(serviceID, dict, context1, context2, context3);
                        if (newDict == NULL) {
@@ -2179,6 +2180,7 @@ SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef                userPreferences,
                                                                              &kCFTypeDictionaryKeyCallBacks,
                                                                              &kCFTypeDictionaryValueCallBacks);
                                }
                                                                              &kCFTypeDictionaryKeyCallBacks,
                                                                              &kCFTypeDictionaryValueCallBacks);
                                }
+                               assert(newConfig != NULL);
                                CFDictionarySetValue(newConfig,
                                                     kSCPropNetVPNAuthPassword,
                                                     unique_id);
                                CFDictionarySetValue(newConfig,
                                                     kSCPropNetVPNAuthPassword,
                                                     unique_id);
index d790dbb69223bf73e495b54114c94cd7ba98546e..81e6194a6473df31b342354f8343492bb68d32de 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2008, 2009, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -40,7 +40,6 @@ __BEGIN_DECLS
 #pragma mark -
 #pragma mark SCNetworkConnection SPIs
 
 #pragma mark -
 #pragma mark SCNetworkConnection SPIs
 
-
 CFArrayRef /* of SCNetworkServiceRef's */
 SCNetworkConnectionCopyAvailableServices       (SCNetworkSetRef                set)                    __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
 
 CFArrayRef /* of SCNetworkServiceRef's */
 SCNetworkConnectionCopyAvailableServices       (SCNetworkSetRef                set)                    __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
 
@@ -68,6 +67,9 @@ SCNetworkConnectionSuspend                    (SCNetworkConnectionRef         connection)             __OSX_AVAILAB
 Boolean
 SCNetworkConnectionResume                      (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);
 
 Boolean
 SCNetworkConnectionResume                      (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);
 
+Boolean
+SCNetworkConnectionRefreshOnDemandState                (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
 Boolean
 SCNetworkConnectionSetClientInfo               (SCNetworkConnectionRef         connection,
                                                 mach_port_t                    client_audit_session,
 Boolean
 SCNetworkConnectionSetClientInfo               (SCNetworkConnectionRef         connection,
                                                 mach_port_t                    client_audit_session,
@@ -75,6 +77,280 @@ SCNetworkConnectionSetClientInfo            (SCNetworkConnectionRef         connection,
                                                 gid_t                          client_gid,
                                                 pid_t                          client_pid)             __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_0);
 
                                                 gid_t                          client_gid,
                                                 pid_t                          client_pid)             __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_0);
 
+/*!
+ @function SCNetworkConnectionCreate
+ @discussion Create a network connection that is not associated with any
+     network service.
+ @param allocator The CFAllocator that should be used to allocate
+     memory for the connection structure.  This parameter may be
+     NULL in which case the current default CFAllocator is used.
+     If this reference is not a valid CFAllocator, the behavior
+     is undefined.
+ @param callout The function to be called when the status
+     of the connection changes.  If this parameter is NULL, the
+     application will not receive notifications of status change
+     and will need to poll for updates.
+ @param context The SCNetworkConnectionContext associated with the
+     callout.
+ @return The new SCNetworkConnection object.
+ */
+SCNetworkConnectionRef
+SCNetworkConnectionCreate                      (CFAllocatorRef                 allocator,
+                                                SCNetworkConnectionCallBack    callout,
+                                                SCNetworkConnectionContext     *context)               __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionSetClientAuditInfo
+ @discussion Set audit information for the process that is initiating the network traffic
+      that will be transmitted over this network connection.
+ @param connection The SCNetworkConnection object.
+ @param client_audit_token The audit token of the initiator process.
+ @param audit_session The audit session mach port of the initiator process.
+ @param bootstrap_port The bootstrap port of the initiator process.
+ @param pid The PID of the initiator process.
+ @param uuid The Mach-O UUID of the initiator process.
+ @param bundle_id The CFBundleIdentifier of the initiator process.
+ @return TRUE if the audit token was set successfully, FALSE if an error occurred.
+ */
+Boolean
+SCNetworkConnectionSetClientAuditInfo          (SCNetworkConnectionRef         connection,
+                                                audit_token_t                  client_audit_token,
+                                                mach_port_t                    audit_session,
+                                                mach_port_t                    bootstrap_port,
+                                                pid_t                          pid,
+                                                const uuid_t                   uuid,
+                                                const char                     *bundle_id)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @defined kSCNetworkConnectionSelectionOptionNoUserPrefs
+ @abstract Indicates whether or not SCNetworkConnectionSelectServiceWithOptions
+     should consult the user preferences to find a network service.
+ */
+#define kSCNetworkConnectionSelectionOptionNoUserPrefs         CFSTR("NoUserPrefs")    /* CFBoolean */
+
+/*!
+ @define kSCNetworkConnectionSelectionOptionOnDemandTrafficClass
+ @abstract The traffic class that is attempting to trigger OnDemand.
+ */
+#define kSCNetworkConnectionSelectionOptionOnDemandTrafficClass        CFSTR("OnDemandTrafficClass")   // CFNumber
+                                                                                               // __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/)
+/*!
+ @define kSCNetworkConnectionSelectionOptionOnDemandAccountIdentifier
+ @abstract The account identifier that is attempting to trigger OnDemand.
+ */
+#define kSCNetworkConnectionSelectionOptionOnDemandAccountIdentifier   CFSTR("OnDemandAccountIdentifier")      /* CFString */
+
+/*!
+ @define kSCNetworkConnectionSelectionOptionOnDemandMatchInfo
+ @abstract A dictionary containing information about the On Demand trigger that matched
+ */
+#define kSCNetworkConnectionSelectionOptionOnDemandMatchInfo   CFSTR("OnDemandMatchInfo")      /* CFDictionary */
+
+/*!
+ @define kSCNetworkConnectionOnDemandMatchInfoVPNType
+ @abstract The type of VPN connection associated with the matching trigger.
+ */
+#define kSCNetworkConnectionOnDemandMatchInfoVPNType           CFSTR("OnDemandMatchInfoVPNType")       /* CFNumber containing a SCNetworkConnectionType */
+
+/*!
+ @define kSCNetworkConnectionOnDemandMatchInfoDomain
+ @abstract The specific DNS domain in the trigger's match domains that matched the on demand hostname.
+ */
+#define kSCNetworkConnectionOnDemandMatchInfoDomain            CFSTR("OnDemandMatchInfoDomain")        /* CFString */
+
+/*!
+ @define kSCNetworkConnectionOnDemandMatchInfoAppRuleID
+ @abstract The identifier of the app rule in the matching trigger that matched the calling app.
+ */
+#define kSCNetworkConnectionOnDemandMatchInfoAppRuleID         CFSTR("OnDemandMatchInfoAppRuleID")     /* CFString */
+
+/*
+ @define kSCNetworkConnectionOnDemandMatchInfoOnRetry
+ @abstract A flag indicating if the on demand hostname matched a domain in the "on retry" match domains.
+ */
+#define kSCNetworkConnectionOnDemandMatchInfoOnRetry           CFSTR("OnDemandMatchInfoOnRetry")       /* CFString */
+
+
+/*!
+ @function SCNetworkConnectionSelectServiceWithOptions
+ @discussion Associate a network connection with a network service based on some
+      selection options. This function can only be called on connections that are
+      not already associated with a network service.
+ @param connection The SCNetworkConnection object.
+ @param selectionOptions A dictionary containing some options to be used to
+      select the appropriate service.
+ @return TRUE if an appropriate network service was found and was associated with
+      the connection, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionSelectServiceWithOptions    (SCNetworkConnectionRef         connection,
+                                                CFDictionaryRef                selectionOptions)       __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionOnDemandShouldRetryOnFailure
+ @discussion After SCNetworkConnectionSelectServiceWithOptions returns FALSE, use
+       this function to determine if an On Demand service was indeed matched for
+       On Retry behavior (try resolving/connecting, and start VPN on failure).
+ @param connection The SCNetworkConnection object.
+ @return TRUE if the selected On Demand connection should be retried on DNS or connection
+       failure, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionOnDemandShouldRetryOnFailure        (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionCanTunnelAddress
+ @discussion This function should be called on a connection object selected with
+       SCNetworkConnectionSelectServiceWithOptions. If the address belongs to
+       the connection (the tunnel can be used for the address), the function
+       will return TRUE. If startImmediately is set, the address should not be trusted
+       and the VPN should be brought up before attempting to connect.
+ @param connection The SCNetworkConnection object.
+ @param address The address structure to check.
+ @param startImmediately On return, TRUE indicates that the address is not trusted
+       and the VPN should be started immediately.
+ @return TRUE if the selected VPN connection's tunnel routes match the address.
+ */
+Boolean
+SCNetworkConnectionCanTunnelAddress            (SCNetworkConnectionRef         connection,
+                                                const struct sockaddr          *address,
+                                                Boolean                        *startImmediately)      __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionIsOnDemandSuspended
+ @discussion Indicates whether the On Demand connection is suspended or not. Call
+       SCNetworkConnectionSelectServiceWithOptions before calling this function.
+ @param connection The SCNetworkConnection object.
+ @return TRUE if the On Demand connection is suspended, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionIsOnDemandSuspended         (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionCopyOnDemandInfo
+ @discussion Indicates whether or not the caller should start the network connection,
+      assuming that the caller has network traffic that needs to use the network connection.
+ @param connection The SCNetworkConnection object.
+ @param onDemandRemoteAddress On return, contains the address of the server providing the
+      network connection. Ownership follows the "Create" rule.
+ @param onDemandConnectionStatus On return, contains the current status of the network
+      connection.
+ @return TRUE if the caller should start the connection upon traffic demand, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionCopyOnDemandInfo            (SCNetworkConnectionRef         connection,
+                                                CFStringRef                    *onDemandRemoteAddress,
+                                                SCNetworkConnectionStatus      *onDemandConnectionStatus)      __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionTriggerOnDemandIfNeeded
+ @discussion Trigger a VPN On Demand connection based on a hostname. This function combines the
+       functionality of calling SCNetworkConnectionCreate, SCNetworkConnectionSelectServiceWithOptions,
+       and SCNetworkConnectionStart. The function blocks until the connection is established,
+       fails, or the timer runs out. Since it blocks, this function should not generally be called on
+       the main runloop. NOTE: This function should only be called from process running
+       in the user's context to ensure that the user's keychain is available.
+ @param hostName The hostname that needs to be resolved and accessed.
+ @param afterDNSFail Pass FALSE if this call is made before trying to resolve the hostname, and
+       TRUE if the hostname resolution already failed.
+ @param timeout Number of seconds to wait for a connection. Passing 0 sets a timeout of forever.
+ @param trafficClass Numeric value of a traffic class. Pass 0 for default traffic class, 'Best Effort'.
+ @return TRUE if the connection was established or was not needed, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionTriggerOnDemandIfNeeded     (CFStringRef                    hostName,
+                                                Boolean                        afterDNSFail,
+                                                int                            timeout,
+                                                int                            trafficClass)                   __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @function SCNetworkConnectionGetReachabilityInfo
+ @discussion Get the reachability info of the connection server.
+ @param connection The SCNetworkConnection object.
+ @param reach_flags On return, contains the reachability flags of the connection server.
+ @param reach_if_index On return, contains the index of the interface through which
+      the connection server is reachable.
+ @return TRUE if the reachability information was available for the connection
+      server, FALSE otherwise.
+ */
+Boolean
+SCNetworkConnectionGetReachabilityInfo         (SCNetworkConnectionRef         connection,
+                                                SCNetworkReachabilityFlags     *reach_flags,
+                                                unsigned int                   *reach_if_index)        __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+
+/*!
+ @enum SCNetworkConnectionType
+ @discussion Type of the network connection.
+ @constant kSCNetworkConnectionTypeUnknown
+     The type of the network connection has not yet been determined.
+ @constant kSCNetworkConnectionTypePPP
+     The network connection is a Point To Point Protocol connection.
+ @constant kSCNetworkConnectionTypeIPLayerVPN
+     The network connection is a IP-layer Virtual Private Network connection.
+ @constant kSCNetworkConnectionTypeAppLayerVPN
+     The network connection is an Application-layer Virtual Private Network connection.
+ */
+enum {
+       kSCNetworkConnectionTypeUnknown         = 0,
+       kSCNetworkConnectionTypePPP             = 1,
+       kSCNetworkConnectionTypeIPLayerVPN      = 2,
+       kSCNetworkConnectionTypeAppLayerVPN     = 3,
+};
+
+typedef int SCNetworkConnectionType;
+
+/*!
+ @function SCNetworkConnectionGetType
+ @discussion Get the type of the network connection.
+ @param connection The SCNetworkConnection object.
+ @return The type of the network connection.
+ */
+SCNetworkConnectionType
+SCNetworkConnectionGetType                     (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/*!
+ @defined kSCNetworkConnectionFlowPropertyHostName
+ @abstract The host name of the flow's destination server.
+ */
+#define kSCNetworkConnectionFlowPropertyHostName       CFSTR("HostName")       /* CFString */
+
+/*!
+ @defined kSCNetworkConnectionFlowPropertyHostAddress
+ @abstract The address of the flow's destination server.
+ */
+#define kSCNetworkConnectionFlowPropertyHostAddress    CFSTR("HostAddress")    /* CFData containing a struct sockaddr */
+
+/*!
+ @defined kSCNetworkConnectionFlowPropertyHostPort
+ @abstract The port of the flow's destination server.
+ */
+#define kSCNetworkConnectionFlowPropertyHostPort       CFSTR("HostPort")       /* CFNumber */
+
+/*!
+ @function SCNetworkConnectionCopyFlowDivertToken
+ @discussion Copy a token that should be used to activate flow divert on
+      a socket, causing data on the socket to be diverted through the
+      Application-layer VPN provided by the given network connection.
+ @param connection The SCNetworkConnection object.
+ @param flowProperties A dictionary containing properties of the socket
+      to be diverted.
+ @return The flow divert token, or NULL if the flow properties are not valid
+      or the connection does not provide Application-Layer VPN services.
+ */
+CFDataRef
+SCNetworkConnectionCopyFlowDivertToken         (SCNetworkConnectionRef         connection,
+                                                CFDictionaryRef                flowProperties)         __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+#define kSCNetworkConnectionAppPropertyRuleID          CFSTR("RuleID")
+#define kSCNetworkConnectionAppPropertyCodeDirHash     CFSTR("CodeDirHash")
+#define kSCNetworkConnectionAppPropertySigningID       CFSTR("SigningID")
+#define kSCNetworkConnectionAppPropertyAuditToken      CFSTR("AuditToken")
+#define kSCNetworkConnectionAppPropertyPID             CFSTR("ProcessID")
+#define kSCNetworkConnectionAppPropertyUUID            CFSTR("UUID")
+
+int
+SCNetworkConnectionGetServiceIdentifier                (SCNetworkConnectionRef         connection)             __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
 
 #pragma mark -
 #pragma mark SCNetworkConnection "VPN on Demand" SPIs
 
 #pragma mark -
 #pragma mark SCNetworkConnection "VPN on Demand" SPIs
@@ -107,6 +383,8 @@ SCNetworkConnectionSetClientInfo            (SCNetworkConnectionRef         connection,
  *         <array>
  *           <string>external.mycompany.com</string>
  *         </array>
  *         <array>
  *           <string>external.mycompany.com</string>
  *         </array>
+ *         <key>OnDemandMatchAppEnabled</key>
+ *         <integer>0</integer>
  *       </dict>
  *     </array>
  *   </dict>
  *       </dict>
  *     </array>
  *   </dict>
@@ -115,34 +393,88 @@ SCNetworkConnectionSetClientInfo          (SCNetworkConnectionRef         connection,
 // notify(3) key
 #define kSCNETWORKCONNECTION_ONDEMAND_NOTIFY_KEY               "com.apple.system.SCNetworkConnectionOnDemand"
 
 // notify(3) key
 #define kSCNETWORKCONNECTION_ONDEMAND_NOTIFY_KEY               "com.apple.system.SCNetworkConnectionOnDemand"
 
+// SCNetworkConnection status
+// (included in the dictionary returned by SCNetworkConnectionCopyExtendedStatus)
+#define kSCNetworkConnectionStatus                             CFSTR("Status")                 /* CFNumber */
+
 // a CFArray[CFDictionary] of VPN on Demand "trigger" configurations
 // a CFArray[CFDictionary] of VPN on Demand "trigger" configurations
-#define kSCNetworkConnectionOnDemandTriggers                   CFSTR("Triggers")
+#define kSCNetworkConnectionOnDemandTriggers                   CFSTR("Triggers")               /* CFArray[CFDictionary] */
 
 // VPN service ID
 
 // VPN service ID
-#define kSCNetworkConnectionOnDemandServiceID                  CFSTR("ServiceID")
+#define kSCNetworkConnectionOnDemandServiceID                  CFSTR("ServiceID")              /* CFString */
 
 // VPN service status (idle, connecting, connected, disconnecting)
 
 // VPN service status (idle, connecting, connected, disconnecting)
-#define kSCNetworkConnectionOnDemandStatus                     CFSTR("Status")
+#define kSCNetworkConnectionOnDemandStatus                     CFSTR("Status")                 /* CFNumber */
 
 // VPN server address
 
 // VPN server address
-#define kSCNetworkConnectionOnDemandRemoteAddress              CFSTR("RemoteAddress")
+#define kSCNetworkConnectionOnDemandRemoteAddress              CFSTR("RemoteAddress")          /* CFString */
+
+// Reachability flags for the VPN server
+#define kSCNetworkConnectionOnDemandReachFlags                 CFSTR("ReachFlags")             /* CFNumber */
+
+// Reachability interface index for the VPN server
+#define kSCNetworkConnectionOnDemandReachInterfaceIndex                CFSTR("ReachInterfaceIndex")    /* CFNumber */
+
+// Network detection has detected DNS Redirecting (like OpenDNS)
+#define kSCNetworkConnectionOnDemandDNSRedirectDetected                CFSTR("DNSRedirectDetected")    /* CFBoolean */
+
+// a dictionary of address information for known lying results
+#define kSCNetworkConnectionOnDemandDNSRedirectedAddresses     CFSTR("DNSRedirectedAddresses") /* CFDictionary[CFDictionary] */
+
+// A dictionary of routes tunneled over this service in the past
+#define kSCNetworkConnectionOnDemandTunneledNetworks           CFSTR("TunneledNetworks")       /* CFDictionary[CFDictionary] */
+
+// An array of plugin PIDs
+#define kSCNetworkConnectionOnDemandPluginPIDs                 CFSTR("PluginPIDs")             /* CFArray[CFNumber] */
+
+// A dictionary of results, keyed by probe string
+#define kSCNetworkConnectionOnDemandProbeResults               CFSTR("ProbeResults")           /* CFDictionary[CFBoolean] */
+
+/* The following generic NetworkInfo keys are currently used in the dynamic store as follows:
+
+ kSCNetworkConnectionOnDemandTunneledNetworks (CFDictionary)
+       - kSCNetworkConnectionNetworkInfoIPv4 (CFDictionary)
+               - kSCNetworkConnectionNetworkInfoIncludedRoutes (CFDictionary)
+                       - kSCNetworkConnectionNetworkInfoAddresses (CFData)
+                       - kSCNetworkConnectionNetworkInfoMasks (CFData)
+               - kSCNetworkConnectionNetworkInfoExcludedRoutes (CFDictionary)
+                       - kSCNetworkConnectionNetworkInfoAddresses (CFData)
+                       - kSCNetworkConnectionNetworkInfoMasks (CFData)
+       - kSCNetworkConnectionNetworkInfoIPv6 (CFDictionary)
+               [Same as for IPv4]
+
+ kSCNetworkConnectionOnDemandDNSRedirectedAddresses (CFDictionary)
+       - kSCNetworkConnectionNetworkInfoIPv4 (CFDictionary)
+               - kSCNetworkConnectionNetworkInfoAddresses (CFData)
+       - kSCNetworkConnectionNetworkInfoIPv6 (CFDictionary)
+               - kSCNetworkConnectionNetworkInfoAddresses (CFData)
+ */
+#define kSCNetworkConnectionNetworkInfoIPv4                    CFSTR("IPv4")                   /* CFDictionary[CFType] */
+#define kSCNetworkConnectionNetworkInfoIPv6                    CFSTR("IPv6")                   /* CFDictionary[CFType] */
+#define kSCNetworkConnectionNetworkInfoIncludedRoutes          CFSTR("IncludedRoutes")         /* CFDictionary[CFData] */
+#define kSCNetworkConnectionNetworkInfoExcludedRoutes          CFSTR("ExcludedRoutes")         /* CFDictionary[CFData] */
+#define kSCNetworkConnectionNetworkInfoAddresses               CFSTR("Addresses")              /* CFData */
+#define kSCNetworkConnectionNetworkInfoMasks                   CFSTR("Masks")                  /* CFData */
 
 // a CFArray[CFString] representing those domain (or host) names that, if
 // matched to a target hostname, should result in our first establishing
 // the VPN connection before any DNS queries are issued.
 
 // a CFArray[CFString] representing those domain (or host) names that, if
 // matched to a target hostname, should result in our first establishing
 // the VPN connection before any DNS queries are issued.
-#define kSCNetworkConnectionOnDemandMatchDomainsAlways         CFSTR("OnDemandMatchDomainsAlways")
+#define kSCNetworkConnectionOnDemandMatchDomainsAlways         CFSTR("OnDemandMatchDomainsAlways")     /* CFArray[CFString] */
 
 // a CFArray[CFString] representing those domain (or host) names that, if
 // matched to a target hostname, should result in a DNS query regardless of
 // whether the VPN connection has been established.  If the DNS query returns
 // an [EAI_NONAME] error then we should establish the VPN connection and
 // re-issue / retry the query.
 
 // a CFArray[CFString] representing those domain (or host) names that, if
 // matched to a target hostname, should result in a DNS query regardless of
 // whether the VPN connection has been established.  If the DNS query returns
 // an [EAI_NONAME] error then we should establish the VPN connection and
 // re-issue / retry the query.
-#define kSCNetworkConnectionOnDemandMatchDomainsOnRetry                CFSTR("OnDemandMatchDomainsOnRetry")
+#define kSCNetworkConnectionOnDemandMatchDomainsOnRetry                CFSTR("OnDemandMatchDomainsOnRetry")    /* CFArray[CFString] */
 
 // a CFArray[CFString] representing those domain (or host) names that should
 // be excluded from those that would be used to establish tje VPN connection.
 
 // a CFArray[CFString] representing those domain (or host) names that should
 // be excluded from those that would be used to establish tje VPN connection.
-#define kSCNetworkConnectionOnDemandMatchDomainsNever          CFSTR("OnDemandMatchDomainsNever")
+#define kSCNetworkConnectionOnDemandMatchDomainsNever          CFSTR("OnDemandMatchDomainsNever")      /* CFArray[CFString] */
 
 
+// A CFNumber (0 or 1) indicating whether or not the App Layer rules should be
+// used to decide whether or not to establish the tunnel connection.
+#define kSCNetworkConnectionOnDemandMatchAppEnabled            CFSTR("OnDemandMatchAppEnabled")        /* CFNumber */
 
 Boolean
 __SCNetworkConnectionCopyOnDemandInfoWithName  (SCDynamicStoreRef              *storeP,
 
 Boolean
 __SCNetworkConnectionCopyOnDemandInfoWithName  (SCDynamicStoreRef              *storeP,
index bb681bd6faea74dafd56cc1aab479eb1b56f75d4..b66bcb79710ccec64dfd2ca149b584a3c6722cf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -63,7 +63,9 @@
 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
 #include <IOKit/serial/IOSerialKeys.h>
 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
 #include <IOKit/serial/IOSerialKeys.h>
 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
+#if    !TARGET_IPHONE_SIMULATOR
 #include <IOKit/usb/USB.h>
 #include <IOKit/usb/USB.h>
+#endif // !TARGET_IPHONE_SIMULATOR
 
 #include "dy_framework.h"
 
 
 #include "dy_framework.h"
 
 #define kPCIThunderboltString          "PCI-Thunderbolt"
 #endif
 
 #define kPCIThunderboltString          "PCI-Thunderbolt"
 #endif
 
-#ifndef        kUSBProductString
-#define kUSBProductString              "USB Product Name"
-#endif
-
 #ifndef        kIOUserEthernetInterfaceRoleKey
 #define        kIOUserEthernetInterfaceRoleKey "InterfaceRole"
 #endif
 #ifndef        kIOUserEthernetInterfaceRoleKey
 #define        kIOUserEthernetInterfaceRoleKey "InterfaceRole"
 #endif
@@ -123,6 +121,7 @@ enum {
        kSortBluetoothPAN_GN,
        kSortBluetoothPAN_NAP,
        kSortBluetoothPAN_U,
        kSortBluetoothPAN_GN,
        kSortBluetoothPAN_NAP,
        kSortBluetoothPAN_U,
+       kSortThunderbolt,
        kSortBond,
        kSortBridge,
        kSortVLAN,
        kSortBond,
        kSortBridge,
        kSortVLAN,
@@ -180,12 +179,13 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4        = {
        0,                                      // entryID
        NULL,                                   // overrides
        FALSE,                                  // modemIsV92
        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,                                   // type
        NULL,                                   // unit
        { NULL, 0, 0 },                         // usb { name, vid, pid }
        kSortUnknown,                           // sort_order
        FALSE,                                  // supportsBond
-       { NULL, NULL, NULL },                   // bond { interfaces, options, mode }
+       { NULL, NULL, NULL },                   // bond { interfaces, mode, options }
        FALSE,                                  // supportsBridge
        { NULL, NULL },                         // bridge { interfaces, options }
        FALSE,                                  // supportsVLAN
        FALSE,                                  // supportsBridge
        { NULL, NULL },                         // bridge { interfaces, options }
        FALSE,                                  // supportsVLAN
@@ -223,12 +223,13 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback    = {
        0,                                      // entryID
        NULL,                                   // overrides
        FALSE,                                  // modemIsV92
        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,                                   // type
        NULL,                                   // unit
        { NULL, 0, 0 },                         // usb { name, vid, pid }
        kSortUnknown,                           // sort_order
        FALSE,                                  // supportsBond
-       { NULL, NULL, NULL },                   // bond { interfaces, options, mode }
+       { NULL, NULL, NULL },                   // bond { interfaces, mode, options }
        FALSE,                                  // supportsBridge
        { NULL, NULL },                         // bridge { interfaces, options }
        FALSE,                                  // supportsVLAN
        FALSE,                                  // supportsBridge
        { NULL, NULL },                         // bridge { interfaces, options }
        FALSE,                                  // supportsVLAN
@@ -392,11 +393,11 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
        }
        if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
                CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
        }
        if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
-               int     pid;
-               int     vid;
+               int     pid     = 0;
+               int     vid     = 0;
 
                if (!isA_CFNumber(interfacePrivate->usb.pid) ||
 
                if (!isA_CFNumber(interfacePrivate->usb.pid) ||
-                   !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &pid)) {
+                   !CFNumberGetValue(interfacePrivate->usb.pid, kCFNumberIntType, &pid)) {
                        pid = 0;
                }
                if (!isA_CFNumber(interfacePrivate->usb.vid) ||
                        pid = 0;
                }
                if (!isA_CFNumber(interfacePrivate->usb.vid) ||
@@ -410,8 +411,8 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                }
 
                CFStringAppendFormat(result, NULL, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
                }
 
                CFStringAppendFormat(result, NULL, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
-                                    interfacePrivate->usb.vid,
-                                    interfacePrivate->usb.pid);
+                                    vid,
+                                    pid);
        }
        if (interfacePrivate->configurationAction != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction);
        }
        if (interfacePrivate->configurationAction != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction);
@@ -444,7 +445,7 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                        member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i);
                        CFStringAppendFormat(result, NULL,
                                             CFSTR("%s%@"),
                        member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i);
                        CFStringAppendFormat(result, NULL,
                                             CFSTR("%s%@"),
-                                            (i == 0) ? ", interfaces = " : ", ",
+                                            (i == 0) ? ", interfaces = " : ",",
                                             SCNetworkInterfaceGetBSDName(member));
                }
        }
                                             SCNetworkInterfaceGetBSDName(member));
                }
        }
@@ -466,7 +467,7 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                        member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i);
                        CFStringAppendFormat(result, NULL,
                                             CFSTR("%s%@"),
                        member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i);
                        CFStringAppendFormat(result, NULL,
                                             CFSTR("%s%@"),
-                                            (i == 0) ? ", interfaces = " : ", ",
+                                            (i == 0) ? ", interfaces = " : ",",
                                             SCNetworkInterfaceGetBSDName(member));
                }
        }
                                             SCNetworkInterfaceGetBSDName(member));
                }
        }
@@ -556,6 +557,9 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->overrides != NULL)
                CFRelease(interfacePrivate->overrides);
 
        if (interfacePrivate->overrides != NULL)
                CFRelease(interfacePrivate->overrides);
 
+       if (interfacePrivate->prefix != NULL)
+               CFRelease(interfacePrivate->prefix);
+
        if (interfacePrivate->type != NULL)
                CFRelease(interfacePrivate->type);
 
        if (interfacePrivate->type != NULL)
                CFRelease(interfacePrivate->type);
 
@@ -712,7 +716,7 @@ __SCNetworkInterfaceInitialize(void)
 
        // get mach port used to communication with IOKit
        kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
 
        // get mach port used to communication with IOKit
        kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG,
                      CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
                      kr);
                SCLog(TRUE, LOG_DEBUG,
                      CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
                      kr);
@@ -772,6 +776,7 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef    allocator,
        interfacePrivate->entryID                       = 0;
        interfacePrivate->overrides                     = NULL;
        interfacePrivate->modemIsV92                    = FALSE;
        interfacePrivate->entryID                       = 0;
        interfacePrivate->overrides                     = NULL;
        interfacePrivate->modemIsV92                    = FALSE;
+       interfacePrivate->prefix                        = NULL;
        interfacePrivate->type                          = NULL;
        interfacePrivate->unit                          = NULL;
        interfacePrivate->usb.name                      = NULL;
        interfacePrivate->type                          = NULL;
        interfacePrivate->unit                          = NULL;
        interfacePrivate->usb.name                      = NULL;
@@ -1166,6 +1171,34 @@ IOCopyCFStringValue(CFTypeRef ioVal)
 }
 
 
 }
 
 
+static CFStringRef
+IODictionaryCopyBSDName(CFDictionaryRef io_dict)
+{
+       CFStringRef     if_bsdName;
+       CFStringRef     if_prefix;
+       CFNumberRef     if_unit;
+
+       if_bsdName = CFDictionaryGetValue(io_dict, CFSTR(kIOBSDNameKey));
+       if (if_bsdName != NULL) {
+               return IOCopyCFStringValue(if_bsdName);
+       }
+
+       // no BSD name, get interface prefix and unit
+       if_prefix = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceNamePrefix));
+       if_unit   = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceUnit));
+       if (isA_CFString(if_prefix) && isA_CFNumber(if_unit)) {
+               // if both prefix and unit available, construct BSD name
+               if_bsdName = CFStringCreateWithFormat(NULL,
+                                                     NULL,
+                                                     CFSTR("%@%@"),
+                                                     if_prefix,
+                                                     if_unit);
+       }
+
+       return if_bsdName;
+};
+
+
 static CFStringRef
 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict, CFStringRef io_key)
 {
 static CFStringRef
 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict, CFStringRef io_key)
 {
@@ -1406,33 +1439,33 @@ pci_port(CFTypeRef slot_name, int ift, CFStringRef bsdName)
 
                while ((child = IOIteratorNext(child_iterator)) != MACH_PORT_NULL) {
                        if (IOObjectConformsTo(child, kIONetworkInterfaceClass)) {
 
                while ((child = IOIteratorNext(child_iterator)) != MACH_PORT_NULL) {
                        if (IOObjectConformsTo(child, kIONetworkInterfaceClass)) {
-                               CFNumberRef     child_if_type;
-                               int             child_ift       = ift;
-
-                               child_if_type = IORegistryEntryCreateCFProperty(child,
-                                                                               CFSTR(kIOInterfaceType),
-                                                                               NULL,
-                                                                               0);
-                               if (child_if_type != NULL) {
-                                       if (!isA_CFNumber(child_if_type) ||
-                                           !CFNumberGetValue(child_if_type, kCFNumberIntType, &child_ift)) {
-                                               // assume that it's a match
-                                               child_ift = ift;
+                               CFMutableDictionaryRef  interface_dict  = NULL;
+
+                               (void) IORegistryEntryCreateCFProperties(child, &interface_dict, NULL, kNilOptions);
+                               if (interface_dict != NULL) {
+                                       CFNumberRef     child_if_type;
+                                       int             child_ift       = ift;
+
+                                       child_if_type = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType));
+                                       if (child_if_type != NULL) {
+                                               if (!isA_CFNumber(child_if_type) ||
+                                                   !CFNumberGetValue(child_if_type, kCFNumberIntType, &child_ift)) {
+                                                       // assume that it's a match
+                                                       child_ift = ift;
+                                               }
                                        }
                                        }
-                                       CFRelease(child_if_type);
-                               }
 
 
-                               if (ift == child_ift) {
-                                       CFStringRef     if_bsdName;
+                                       if (ift == child_ift) {
+                                               CFStringRef     if_bsdName;
 
 
-                                       if_bsdName = IORegistryEntryCreateCFProperty(child,
-                                                                                    CFSTR(kIOBSDNameKey),
-                                                                                    NULL,
-                                                                                    0);
-                                       if (if_bsdName != NULL) {
-                                               CFArrayAppendValue(port_names, if_bsdName);
-                                               CFRelease(if_bsdName);
+                                               if_bsdName = IODictionaryCopyBSDName(interface_dict);
+                                               if (if_bsdName != NULL) {
+                                                       CFArrayAppendValue(port_names, if_bsdName);
+                                                       CFRelease(if_bsdName);
+                                               }
                                        }
                                        }
+
+                                       CFRelease(interface_dict);
                                }
                        }
                        IOObjectRelease(child);
                                }
                        }
                        IOObjectRelease(child);
@@ -1447,7 +1480,7 @@ pci_port(CFTypeRef slot_name, int ift, CFStringRef bsdName)
                CFArraySortValues(port_names, CFRangeMake(0, n), compare_bsdNames, NULL);
                n = CFArrayGetFirstIndexOfValue(port_names, CFRangeMake(0, n), bsdName);
                if (n != kCFNotFound) {
                CFArraySortValues(port_names, CFRangeMake(0, n), compare_bsdNames, NULL);
                n = CFArrayGetFirstIndexOfValue(port_names, CFRangeMake(0, n), bsdName);
                if (n != kCFNotFound) {
-                       port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), n + 1);
+                       port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), n + 1);
                }
        }
 
                }
        }
 
@@ -1459,14 +1492,20 @@ pci_port(CFTypeRef slot_name, int ift, CFStringRef bsdName)
 static Boolean
 pci_slot_info(io_registry_entry_t interface, int ift, CFStringRef *slot_name, CFStringRef *port_name)
 {
 static Boolean
 pci_slot_info(io_registry_entry_t interface, int ift, CFStringRef *slot_name, CFStringRef *port_name)
 {
-       CFStringRef     bsd_name;
-       Boolean         ok              = FALSE;
-       CFTypeRef       pci_slot_name;
+       CFStringRef             bsd_name        = NULL;
+       CFMutableDictionaryRef  interface_dict  = NULL;
+       Boolean                 ok              = FALSE;
+       CFTypeRef               pci_slot_name;
 
        *slot_name = NULL;
        *port_name = NULL;
 
 
        *slot_name = NULL;
        *port_name = NULL;
 
-       bsd_name = IORegistryEntryCreateCFProperty(interface, CFSTR(kIOBSDNameKey), NULL, 0);
+       (void) IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
+       if (interface_dict != NULL) {
+               bsd_name = IODictionaryCopyBSDName(interface_dict);
+               CFRelease(interface_dict);
+       }
+
        if (bsd_name == NULL) {
                return FALSE;
        }
        if (bsd_name == NULL) {
                return FALSE;
        }
@@ -1524,6 +1563,7 @@ isBluetoothBuiltin(Boolean *haveController)
        hciController = IOIteratorNext(iter);
        IOObjectRelease(iter);
        if(hciController != MACH_PORT_NULL) {
        hciController = IOIteratorNext(iter);
        IOObjectRelease(iter);
        if(hciController != MACH_PORT_NULL) {
+#if    !TARGET_IPHONE_SIMULATOR
                CFNumberRef     idVendor;
 
                idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0);
                CFNumberRef     idVendor;
 
                idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0);
@@ -1538,6 +1578,7 @@ isBluetoothBuiltin(Boolean *haveController)
 
                        CFRelease(idVendor);
                }
 
                        CFRelease(idVendor);
                }
+#endif // !TARGET_IPHONE_SIMULATOR
 
                IOObjectRelease(hciController);
        }
 
                IOObjectRelease(hciController);
        }
@@ -1574,6 +1615,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef  interfacePrivate,
                    io_registry_entry_t                 bus,
                    CFDictionaryRef                     bus_dict)
 {
                    io_registry_entry_t                 bus,
                    CFDictionaryRef                     bus_dict)
 {
+#if    !TARGET_IPHONE_SIMULATOR
        // capture USB info
        interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
                                                                     kIOServicePlane,
        // capture USB info
        interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
                                                                     kIOServicePlane,
@@ -1590,6 +1632,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef  interfacePrivate,
                                                                     CFSTR(kUSBProductID),
                                                                     NULL,
                                                                     kIORegistryIterateRecursively | kIORegistryIterateParents);
                                                                     CFSTR(kUSBProductID),
                                                                     NULL,
                                                                     kIORegistryIterateRecursively | kIORegistryIterateParents);
+#endif // !TARGET_IPHONE_SIMULATOR
 
        return;
 }
 
        return;
 }
@@ -1687,6 +1730,8 @@ merge_override(SCNetworkInterfacePrivateRef       interfacePrivate,
 }
 
 
 }
 
 
+#define        BT_PAN_NAME     "Bluetooth PAN"
+
 static Boolean
 processNetworkInterface(SCNetworkInterfacePrivateRef   interfacePrivate,
                        io_registry_entry_t             interface,
 static Boolean
 processNetworkInterface(SCNetworkInterfacePrivateRef   interfacePrivate,
                        io_registry_entry_t             interface,
@@ -1717,12 +1762,16 @@ processNetworkInterface(SCNetworkInterfacePrivateRef    interfacePrivate,
                case IFT_ETHER :
                        // Type, Hardware
 
                case IFT_ETHER :
                        // Type, Hardware
 
-                       if ((IOObjectConformsTo(controller, "IO80211Controller")) ||
-                           (IOObjectConformsTo(controller, "AirPortPCI"       )) ||
-                           (IOObjectConformsTo(controller, "AirPortDriver"    ))) {
+                       if (IOObjectConformsTo(controller, "IO80211Controller") ||
+                           IOObjectConformsTo(controller, "AirPortPCI"       ) ||
+                           IOObjectConformsTo(controller, "AirPortDriver"    )) {
                                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeIEEE80211;
                                interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                                interfacePrivate->sort_order            = kSortAirPort;
                                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeIEEE80211;
                                interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                                interfacePrivate->sort_order            = kSortAirPort;
+                       } else if (IOObjectConformsTo(controller, "AppleThunderboltIPPort")) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortThunderbolt;
                        } else if (IOObjectConformsTo(controller, "IOBluetoothBNEPDriver")) {
                                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
                                interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                        } else if (IOObjectConformsTo(controller, "IOBluetoothBNEPDriver")) {
                                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
                                interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
@@ -1745,7 +1794,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                                                                      kIORegistryIterateRecursively | kIORegistryIterateParents);
                                if (val != NULL) {
                                        if (isA_CFString(val)) {
                                                                      kIORegistryIterateRecursively | kIORegistryIterateParents);
                                if (val != NULL) {
                                        if (isA_CFString(val)) {
-                                               if (CFEqual(val, CFSTR("Bluetooth PAN"))) {
+                                               if (CFEqual(val, CFSTR(BT_PAN_NAME))) {
                                                        interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
                                                        interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                                                        interfacePrivate->sort_order            = kSortBluetoothPAN_GN;
                                                        interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
                                                        interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                                                        interfacePrivate->sort_order            = kSortBluetoothPAN_GN;
@@ -1808,6 +1857,11 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
 
                        // location
                        interfacePrivate->location = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOLocation));
 
                        // location
                        interfacePrivate->location = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOLocation));
+                       if ((interfacePrivate->location != NULL) &&
+                           (CFStringGetLength(interfacePrivate->location) == 0)) {
+                               CFRelease(interfacePrivate->location);
+                               interfacePrivate->location = NULL;
+                       }
 
                        // VLAN support
                        num = CFDictionaryGetValue(controller_dict, CFSTR(kIOFeatures));
 
                        // VLAN support
                        num = CFDictionaryGetValue(controller_dict, CFSTR(kIOFeatures));
@@ -1821,6 +1875,14 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                        // localized name
                        if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
                                interfacePrivate->localized_key = CFSTR("airport");
                        // localized name
                        if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
                                interfacePrivate->localized_key = CFSTR("airport");
+                       } else if (interfacePrivate->sort_order == kSortThunderbolt) {
+                               if ((interfacePrivate->location == NULL) ||
+                                   (CFStringGetLength(interfacePrivate->location) == 0)) {
+                                       interfacePrivate->localized_key = CFSTR("thunderbolt");
+                               } else {
+                                       interfacePrivate->localized_key  = CFSTR("multithunderbolt");
+                                       interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->location);
+                               }
                        } else if (interfacePrivate->sort_order == kSortBluetoothPAN_GN) {
                                interfacePrivate->localized_key  = CFSTR("bluetooth-pan-gn");
                        } else if (interfacePrivate->sort_order == kSortBluetoothPAN_NAP) {
                        } else if (interfacePrivate->sort_order == kSortBluetoothPAN_GN) {
                                interfacePrivate->localized_key  = CFSTR("bluetooth-pan-gn");
                        } else if (interfacePrivate->sort_order == kSortBluetoothPAN_NAP) {
@@ -1890,7 +1952,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                                                // set interface "name"
                                                if (!update_interface_name(interfacePrivate, interface, TRUE)) {
                                                        interfacePrivate->localized_key  = CFSTR("usb-ether");
                                                // set interface "name"
                                                if (!update_interface_name(interfacePrivate, interface, TRUE)) {
                                                        interfacePrivate->localized_key  = CFSTR("usb-ether");
-                                                       interfacePrivate->localized_arg1 = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+                                                       interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict);
                                                }
                                        }
                                        CFRelease(provider);
                                                }
                                        }
                                        CFRelease(provider);
@@ -1899,7 +1961,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                                if (interfacePrivate->localized_key == NULL) {
                                        // if no provider, not a PCI device, or no slot information
                                        interfacePrivate->localized_key  = CFSTR("generic-ether");
                                if (interfacePrivate->localized_key == NULL) {
                                        // if no provider, not a PCI device, or no slot information
                                        interfacePrivate->localized_key  = CFSTR("generic-ether");
-                                       interfacePrivate->localized_arg1 = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+                                       interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict);
                                }
                        }
 
                                }
                        }
 
@@ -1956,7 +2018,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
        }
 
        // Device
        }
 
        // Device
-       interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+       interfacePrivate->entity_device = IODictionaryCopyBSDName(interface_dict);
 
        // Hardware (MAC) address
        data = CFDictionaryGetValue(controller_dict, CFSTR(kIOMACAddress));
 
        // Hardware (MAC) address
        data = CFDictionaryGetValue(controller_dict, CFSTR(kIOMACAddress));
@@ -1964,6 +2026,12 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                interfacePrivate->address = CFRetain(data);
        }
 
                interfacePrivate->address = CFRetain(data);
        }
 
+       // interface prefix
+       str = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceNamePrefix));
+       if (isA_CFString(str)) {
+               interfacePrivate->prefix = CFRetain(str);
+       }
+
        // interface unit
        num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceUnit));
        if (isA_CFNumber(num) &&
        // interface unit
        num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceUnit));
        if (isA_CFNumber(num) &&
@@ -2448,40 +2516,41 @@ createInterface(io_registry_entry_t interface, processInterface func)
 
        /* get the controller node */
        kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
 
        /* get the controller node */
        kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the dictionary associated with the node */
        kr = IORegistryEntryCreateCFProperties(controller, &controller_dict, NULL, kNilOptions);
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the dictionary associated with the node */
        kr = IORegistryEntryCreateCFProperties(controller, &controller_dict, NULL, kNilOptions);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the bus node */
        kr = IORegistryEntryGetParentEntry(controller, kIOServicePlane, &bus);
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the bus node */
        kr = IORegistryEntryGetParentEntry(controller, kIOServicePlane, &bus);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the dictionary associated with the node */
        kr = IORegistryEntryCreateCFProperties(bus, &bus_dict, NULL, kNilOptions);
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the dictionary associated with the node */
        kr = IORegistryEntryCreateCFProperties(bus, &bus_dict, NULL, kNilOptions);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the registry entry ID */
        kr = IORegistryEntryGetRegistryEntryID(interface, &entryID);
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        /* get the registry entry ID */
        kr = IORegistryEntryGetRegistryEntryID(interface, &entryID);
-       if (kr != KERN_SUCCESS) {
+       if (kr != kIOReturnSuccess) {
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
                SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x"), kr);
                goto done;
        }
 
        interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
+       assert(interfacePrivate != NULL);
        interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
        interfacePrivate->entryID = entryID;
 
        interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
        interfacePrivate->entryID = entryID;
 
@@ -3360,6 +3429,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef                allocator,
        if (matching_interfaces != NULL) {
                CFIndex                 n;
                SCPreferencesRef        prefs;
        if (matching_interfaces != NULL) {
                CFIndex                 n;
                SCPreferencesRef        prefs;
+               Boolean                 temp_preferences        = FALSE;
 
                n = CFArrayGetCount(matching_interfaces);
                switch (n) {
 
                n = CFArrayGetCount(matching_interfaces);
                switch (n) {
@@ -3377,7 +3447,21 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef               allocator,
                                if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
                                        break;
                                }
                                if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
                                        break;
                                }
-                               prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
+
+                               if (CFDictionaryGetValueIfPresent(interface_entity,
+                                                                 kSCPropUserDefinedName,
+                                                                 (const void **)&ifName) &&
+                                   CFEqual(ifName, CFSTR(BT_PAN_NAME))) {
+                                       break;
+                               }
+
+                               prefs = (service != NULL) ? ((SCNetworkServicePrivateRef)service)->prefs : NULL;
+                               if (prefs == NULL) {
+                                       prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
+                                       if (prefs != NULL) {
+                                               temp_preferences = TRUE;
+                                       }
+                               }
                                if (prefs == NULL) {
                                        break;
                                }
                                if (prefs == NULL) {
                                        break;
                                }
@@ -3395,7 +3479,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef                allocator,
                                    && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
                                        interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
                                }
                                    && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
                                        interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
                                }
-                               CFRelease(prefs);
+                               if (temp_preferences) CFRelease(prefs);
                                break;
                        default :
                                if (ifUnique != NULL) {
                                break;
                        default :
                                if (ifUnique != NULL) {
@@ -3486,6 +3570,12 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef               allocator,
                                if (_SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) {
                                        interfacePrivate->localized_key = CFSTR("iPhone");
                                        interfacePrivate->sort_order    = kSortTethered;
                                if (_SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) {
                                        interfacePrivate->localized_key = CFSTR("iPhone");
                                        interfacePrivate->sort_order    = kSortTethered;
+                               } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("iPad"))) {
+                                       interfacePrivate->localized_key = CFSTR("iPad");
+                                       interfacePrivate->sort_order    = kSortTethered;
+                               } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("thunderbolt"))) {
+                                       interfacePrivate->localized_key = CFSTR("thunderbolt");
+                                       interfacePrivate->sort_order    = kSortThunderbolt;
                                } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) {
                                        interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
                                        interfacePrivate->sort_order    = kSortBluetoothPAN_GN;
                                } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) {
                                        interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
                                        interfacePrivate->sort_order    = kSortBluetoothPAN_GN;
@@ -3651,7 +3741,7 @@ __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
        CFDictionaryRef         matching;
        CFArrayRef              new_interfaces;
 
        CFDictionaryRef         matching;
        CFArrayRef              new_interfaces;
 
-       // get Ethernet, Firewire, and AirPort interfaces
+       // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
 
        matching = IOServiceMatching(kIONetworkInterfaceClass);
        new_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
 
        matching = IOServiceMatching(kIONetworkInterfaceClass);
        new_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
@@ -3721,9 +3811,9 @@ __SCNetworkInterfaceCopyAll_RS232()
 static void
 addBTPANInterface(SCPreferencesRef prefs, CFMutableArrayRef all_interfaces)
 {
 static void
 addBTPANInterface(SCPreferencesRef prefs, CFMutableArrayRef all_interfaces)
 {
-       CFIndex         i;
-       CFIndex         n;
-       CFArrayRef      services;
+       CFIndex                 i;
+       SCNetworkInterfaceRef   interface;
+       CFIndex                 n;
 
        n = CFArrayGetCount(all_interfaces);
        for (i = 0; i < n; i++) {
 
        n = CFArrayGetCount(all_interfaces);
        for (i = 0; i < n; i++) {
@@ -3736,24 +3826,11 @@ addBTPANInterface(SCPreferencesRef prefs, CFMutableArrayRef all_interfaces)
                }
        }
 
                }
        }
 
-       services = SCNetworkServiceCopyAll(prefs);
-       if (services != NULL) {
-               n = CFArrayGetCount(services);
-               for (i = 0; i < n; i++) {
-                       SCNetworkInterfaceRef   interface;
-                       SCNetworkServiceRef     service;
-
-                       service = CFArrayGetValueAtIndex(services, i);
-                       interface = SCNetworkServiceGetInterface(service);
-                       if ((interface != NULL) &&
-                           _SCNetworkInterfaceIsBluetoothPAN(interface)) {
-                               // include BT-PAN interface
-                               CFArrayAppendValue(all_interfaces, interface);
-                               break;
-                       }
-               }
-
-               CFRelease(services);
+       interface = _SCNetworkInterfaceCopyBTPANInterface();
+       if (interface != NULL) {
+               // include BT-PAN interface
+               CFArrayAppendValue(all_interfaces, interface);
+               CFRelease(interface);
        }
 
        return;
        }
 
        return;
@@ -3861,7 +3938,7 @@ _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs)
 
        all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
 
        all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
-       // get Ethernet, Firewire, and AirPort interfaces
+       // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
        new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
        if (new_interfaces != NULL) {
                add_interfaces(all_interfaces, new_interfaces);
        new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
        if (new_interfaces != NULL) {
                add_interfaces(all_interfaces, new_interfaces);
@@ -4563,7 +4640,7 @@ copy_display_name(SCNetworkInterfaceRef interface, Boolean localized, Boolean ol
 }
 
 
 }
 
 
-#if    !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#if    !TARGET_OS_IPHONE
 __private_extern__
 CFStringRef
 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface)
 __private_extern__
 CFStringRef
 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface)
@@ -4594,7 +4671,7 @@ __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
        localized_name = copy_display_name(interface, FALSE, TRUE);
        return localized_name;
 }
        localized_name = copy_display_name(interface, FALSE, TRUE);
        return localized_name;
 }
-#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#endif // !TARGET_OS_IPHONE
 
 
 __private_extern__
 
 
 __private_extern__
@@ -6045,6 +6122,10 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
        CFStringRef                     name;
 
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
        CFStringRef                     name;
 
+       if (interface == NULL) {
+               return NULL;
+       }
+
        info = CFDictionaryCreateMutable(NULL,
                                         0,
                                         &kCFTypeDictionaryKeyCallBacks,
        info = CFDictionaryCreateMutable(NULL,
                                         0,
                                         &kCFTypeDictionaryKeyCallBacks,
@@ -6058,6 +6139,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
 
        // add USB info
        if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
 
        // add USB info
        if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
+#if    !TARGET_IPHONE_SIMULATOR
                if (interfacePrivate->usb.name != NULL) {
                        CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name);
                }
                if (interfacePrivate->usb.name != NULL) {
                        CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name);
                }
@@ -6067,6 +6149,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
                if (interfacePrivate->usb.pid != NULL) {
                        CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
                }
                if (interfacePrivate->usb.pid != NULL) {
                        CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
                }
+#endif // !TARGET_IPHONE_SIMULATOR
        }
 
        if (CFDictionaryGetCount(info) == 0) {
        }
 
        if (CFDictionaryGetCount(info) == 0) {
@@ -6115,6 +6198,15 @@ _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface)
 }
 
 
 }
 
 
+CFStringRef
+_SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       return interfacePrivate->prefix;
+}
+
+
 CFNumberRef
 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
 {
 CFNumberRef
 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
 {
@@ -6164,6 +6256,53 @@ _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface)
 #pragma mark SCNetworkInterface SPIs
 
 
 #pragma mark SCNetworkInterface SPIs
 
 
+#if    !TARGET_OS_EMBEDDED
+
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCopyBTPANInterface(void)
+{
+       CFDictionaryRef         dict;
+       SCNetworkInterfaceRef   interface       = NULL;
+       CFStringRef             key;
+
+       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
+       dict = SCDynamicStoreCopyValue(NULL, key);
+       CFRelease(key);
+       if (dict != NULL) {
+               CFStringRef     if_name;
+
+               if (isA_CFDictionary(dict) &&
+                   CFDictionaryGetValueIfPresent(dict,
+                                                 CFSTR("_" BT_PAN_NAME "_"),
+                                                 (const void **)&if_name) &&
+                   isA_CFString(if_name)) {
+                       CFMutableDictionaryRef  entity;
+
+                       entity = CFDictionaryCreateMutable(NULL,
+                                                          0,
+                                                          &kCFTypeDictionaryKeyCallBacks,
+                                                          &kCFTypeDictionaryValueCallBacks);
+                       CFDictionarySetValue(entity,
+                                            kSCPropNetInterfaceType,
+                                            kSCValNetInterfaceTypeEthernet);
+                       CFDictionarySetValue(entity,
+                                            kSCPropNetInterfaceDeviceName,
+                                            if_name);
+                       CFDictionarySetValue(entity,
+                                            kSCPropUserDefinedName,
+                                            CFSTR(BT_PAN_NAME));
+                       interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL);
+                       CFRelease(entity);
+               }
+
+               CFRelease(dict);
+       }
+
+       return interface;
+}
+#endif // !TARGET_OS_EMBEDDED
+
+
 CFStringRef
 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface)
 {
 CFStringRef
 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface)
 {
@@ -6328,6 +6467,48 @@ _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface)
 }
 
 
 }
 
 
+Boolean
+_SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     interfaceType;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               return FALSE;
+       }
+
+       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+       if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) {
+               CFIndex         i;
+               CFArrayRef      members;
+               CFIndex         n;
+
+               members = SCBridgeInterfaceGetMemberInterfaces(interface);
+               n = (members != NULL) ? CFArrayGetCount(members) : 0;
+               if (n == 0) {
+                       // if an empty bridge
+                       return FALSE;
+               }
+
+               for (i = 0; i < n; i++) {
+                       SCNetworkInterfaceRef           member;
+                       SCNetworkInterfacePrivateRef    memberPrivate;
+
+                       member = CFArrayGetValueAtIndex(members, i);
+                       memberPrivate = (SCNetworkInterfacePrivateRef)member;
+                       if (memberPrivate->sort_order != kSortThunderbolt) {
+                               return FALSE;
+                       }
+               }
+
+               // if Ethernet Bridge interface with only Thunderbolt [IP] members
+               return TRUE;
+       }
+
+       return (interfacePrivate->sort_order == kSortThunderbolt);
+}
+
+
 #pragma mark -
 #pragma mark SCNetworkInterface [internal] SPIs
 
 #pragma mark -
 #pragma mark SCNetworkInterface [internal] SPIs
 
index 73e8ff8a4968be6d989778590ed4079c1002d6ca..efdae042d5d5a2046e0df9a1b892364bdcc9c36a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -44,6 +44,7 @@
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/VPNAppLayerPrivate.h>
 #include <pthread.h>
 #include <libkern/OSAtomic.h>
 
 #include <pthread.h>
 #include <libkern/OSAtomic.h>
 
 #define s6_addr16 __u6_addr.__u6_addr16
 #endif
 
 #define s6_addr16 __u6_addr.__u6_addr16
 #endif
 
+#include "SCNetworkConnectionInternal.h"
+
 #include "SCNetworkReachabilityInternal.h"
 
 #include <ppp/ppp_msg.h>
 #include "SCNetworkReachabilityInternal.h"
 
 #include <ppp/ppp_msg.h>
+#include <network_information.h>
 
 
-#if    !TARGET_IPHONE_SIMULATOR
+#if    defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS)
 #include <ppp/PPPControllerPriv.h>
 #include <ppp/PPPControllerPriv.h>
-#endif // !TARGET_IPHONE_SIMULATOR
-
+#endif // !defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS)
 
 
 
 
-#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)) && !TARGET_IPHONE_SIMULATOR
-#define        HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
-#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)) && !TARGET_IPHONE_SIMULATOR
-
-#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)) && !TARGET_IPHONE_SIMULATOR && !TARGET_OS_EMBEDDED_OTHER
-#define        HAVE_IPSEC_STATUS
-#define        HAVE_VPN_STATUS
-#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)) && !TARGET_IPHONE_SIMULATOR && !TARGET_OS_EMBEDDED_OTHER
 
 
 
 
 
 
 #define        DEBUG_REACHABILITY_TYPE_ADDRESSPAIR             "create w/address pair"
 #define        DEBUG_REACHABILITY_TYPE_ADDRESSPAIR_OPTIONS     "            + options"
 
 #define        DEBUG_REACHABILITY_TYPE_ADDRESSPAIR             "create w/address pair"
 #define        DEBUG_REACHABILITY_TYPE_ADDRESSPAIR_OPTIONS     "            + options"
 
+#define        DNS_FLAGS_FORMAT        "[%s%s%s%s]"
+#define        DNS_FLAGS_VALUES(t)     t->dnsHaveV4      ? "4" : "",   \
+                               t->dnsHaveV6      ? "6" : "",   \
+                               t->dnsHaveTimeout ? "T" : "",   \
+                               t->dnsHaveError   ? "E" : ""
+
 
 static pthread_mutexattr_t     lock_attr;
 
 
 static pthread_mutexattr_t     lock_attr;
 
@@ -136,25 +137,12 @@ _getaddrinfo_interface_async_call(const char                      *nodename,
                                  const char                    *interface,
                                  getaddrinfo_async_callback    callback,
                                  void                          *context);
                                  const char                    *interface,
                                  getaddrinfo_async_callback    callback,
                                  void                          *context);
-#endif /* HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL */
+#endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 
 
 #define SCNETWORKREACHABILITY_TRIGGER_KEY      CFSTR("com.apple.SCNetworkReachability:FORCE-CHANGE")
 
 
 
 
 #define SCNETWORKREACHABILITY_TRIGGER_KEY      CFSTR("com.apple.SCNetworkReachability:FORCE-CHANGE")
 
 
-// how long (minimum time, us) to wait before retrying DNS query after EAI_NONAME
-#define EAI_NONAME_RETRY_DELAY_USEC    250000                  // 250ms
-
-// how long (maximum time, us) after DNS configuration change we accept EAI_NONAME
-// without question.
-#define EAI_NONAME_RETRY_LIMIT_USEC    2500000                 // 2.5s
-
-
-// how long (maximum time, ns) to wait for a long-lived-query callback before
-// we assume EAI_NONAME.
-#define LLQ_TIMEOUT_NSEC               30 * NSEC_PER_SEC       // 30s
-
-
 #define        N_QUICK 64
 
 
 #define        N_QUICK 64
 
 
@@ -211,16 +199,20 @@ static const struct addrinfo      HINTS_DEFAULT   = {
 static const struct timeval    TIME_ZERO       = { 0, 0 };
 
 
 static const struct timeval    TIME_ZERO       = { 0, 0 };
 
 
-static Boolean                 D_llqBypass     = FALSE;
-static int                     llqCount        = 0;
-static DNSServiceRef           llqMain         = NULL;
-static CFMutableSetRef         llqUpdated      = NULL;
+static int                     dnsCount        = 0;
+static DNSServiceRef           dnsMain         = NULL;
+#ifdef USE_DNSSERVICEGETADDRINFO
+static CFMutableSetRef         dnsUpdated      = NULL;
+#endif // USE_DNSSERVICEGETADDRINFO
 
 
 #ifdef HAVE_REACHABILITY_SERVER
 static Boolean                 D_serverBypass  = FALSE;
 #endif // HAVE_REACHABILITY_SERVER
 
 
 
 #ifdef HAVE_REACHABILITY_SERVER
 static Boolean                 D_serverBypass  = FALSE;
 #endif // HAVE_REACHABILITY_SERVER
 
+static Boolean                 D_nwiBypass     = FALSE;
+
+
 
 #if    !TARGET_OS_IPHONE
 /*
 
 #if    !TARGET_OS_IPHONE
 /*
@@ -234,11 +226,39 @@ static IOPMSystemPowerStateCapabilities   power_capabilities      = kIOPMSytemPowerStat
  * host "something has changed" notifications
  */
 
  * host "something has changed" notifications
  */
 
+// Note: protected by _hn_target_queue()
 static SCDynamicStoreRef       hn_store        = NULL;
 static SCDynamicStoreRef       hn_store        = NULL;
-static dispatch_queue_t                hn_dispatchQueue = NULL;
 static CFMutableSetRef         hn_targets      = NULL;
 
 
 static CFMutableSetRef         hn_targets      = NULL;
 
 
+static dispatch_queue_t
+_hn_changes_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q = NULL;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create("SCNetworkReachabilty.handleChanges", NULL);
+       });
+
+       return q;
+}
+
+
+static dispatch_queue_t
+_hn_target_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create("SCNetworkReachabilty.targetManagement", NULL);
+       });
+
+       return q;
+}
+
+
 /*
  * DNS configuration
  */
 /*
  * DNS configuration
  */
@@ -249,60 +269,56 @@ typedef struct {
 } dns_configuration_t;
 
 
 } dns_configuration_t;
 
 
+// Note: protected by "dns_lock"
 static pthread_mutex_t         dns_lock                = PTHREAD_MUTEX_INITIALIZER;
 static dns_configuration_t     *dns_configuration      = NULL;
 static int                     dns_token;
 static Boolean                 dns_token_valid         = FALSE;
 
 
 static pthread_mutex_t         dns_lock                = PTHREAD_MUTEX_INITIALIZER;
 static dns_configuration_t     *dns_configuration      = NULL;
 static int                     dns_token;
 static Boolean                 dns_token_valid         = FALSE;
 
 
+
+
 typedef enum {
        dns_query_sync,
        dns_query_async,
 typedef enum {
        dns_query_sync,
        dns_query_async,
-       dns_query_llq
-} dns_query_type;
+       dns_query_mdns,
+} query_type;
 
 
 static void
 
 
 static void
-__dns_query_start(struct timeval       *dnsQueryStart,
-                 struct timeval        *dnsQueryEnd)
+__mark_operation_start(struct timeval  *queryStart,
+                      struct timeval   *queryEnd)
 {
 {
-       (void) gettimeofday(dnsQueryStart, NULL);
-       *dnsQueryEnd = TIME_ZERO;
+       (void) gettimeofday(queryStart, NULL);
+       *queryEnd = TIME_ZERO;
 
        return;
 }
 
 
 static void
 
        return;
 }
 
 
 static void
-__dns_query_end(SCNetworkReachabilityRef       target,
-               Boolean                         found,
-               dns_query_type                  query_type,
-               struct timeval                  *dnsQueryStart,
-               struct timeval                  *dnsQueryEnd)
+__mark_operation_end(SCNetworkReachabilityRef  target,
+                    Boolean                    found,
+                    query_type                 query_type,
+                    struct timeval             *queryStart,
+                    struct timeval             *queryEnd)
 {
 {
-       struct timeval                  dnsQueryElapsed;
-       Boolean                         firstQuery;
+       struct timeval                  queryElapsed;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
-       // report initial or updated query time
-       firstQuery = !timerisset(dnsQueryEnd);
-
-       (void) gettimeofday(dnsQueryEnd, NULL);
+       (void) gettimeofday(queryEnd, NULL);
 
        if (!_sc_debug) {
                return;
        }
 
 
        if (!_sc_debug) {
                return;
        }
 
-       if (!timerisset(dnsQueryStart)) {
+       if (!timerisset(queryStart)) {
                return;
        }
 
                return;
        }
 
-       timersub(dnsQueryEnd, dnsQueryStart, &dnsQueryElapsed);
+       timersub(queryEnd, queryStart, &queryElapsed);
        switch (query_type) {
 
        switch (query_type) {
 
-//             #define QUERY_TIME__FMT "%d.%3.3d"
-//             #define QUERY_TIME__DIV 1000
-
                #define QUERY_TIME__FMT "%d.%6.6d"
                #define QUERY_TIME__DIV 1
 
                #define QUERY_TIME__FMT "%d.%6.6d"
                #define QUERY_TIME__DIV 1
 
@@ -311,25 +327,25 @@ __dns_query_end(SCNetworkReachabilityRef  target,
                              CFSTR("%ssync DNS complete%s (query time = " QUERY_TIME__FMT ")"),
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
                              CFSTR("%ssync DNS complete%s (query time = " QUERY_TIME__FMT ")"),
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
-                             dnsQueryElapsed.tv_sec,
-                             dnsQueryElapsed.tv_usec / QUERY_TIME__DIV);
+                             queryElapsed.tv_sec,
+                             queryElapsed.tv_usec / QUERY_TIME__DIV);
                        break;
                case dns_query_async :
                        SCLog(TRUE, LOG_INFO,
                              CFSTR("%sasync DNS complete%s (query time = " QUERY_TIME__FMT ")"),
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
                        break;
                case dns_query_async :
                        SCLog(TRUE, LOG_INFO,
                              CFSTR("%sasync DNS complete%s (query time = " QUERY_TIME__FMT ")"),
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
-                             dnsQueryElapsed.tv_sec,
-                             dnsQueryElapsed.tv_usec / QUERY_TIME__DIV);
+                             queryElapsed.tv_sec,
+                             queryElapsed.tv_usec / QUERY_TIME__DIV);
                        break;
                        break;
-               case dns_query_llq :
+               case dns_query_mdns :
                        SCLog(TRUE, LOG_INFO,
                        SCLog(TRUE, LOG_INFO,
-                             CFSTR("%sDNS updated%s (%s = " QUERY_TIME__FMT ")"),
+                             CFSTR("%s[m]DNS query complete%s (query time = " QUERY_TIME__FMT "), " DNS_FLAGS_FORMAT),
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
                              targetPrivate->log_prefix,
                              found ? "" : ", host not found",
-                             firstQuery ? "query time" : "updated after",
-                             dnsQueryElapsed.tv_sec,
-                             dnsQueryElapsed.tv_usec / QUERY_TIME__DIV);
+                             queryElapsed.tv_sec,
+                             queryElapsed.tv_usec / QUERY_TIME__DIV,
+                             DNS_FLAGS_VALUES(targetPrivate));
                        break;
        }
 
                        break;
        }
 
@@ -361,11 +377,27 @@ __reach_changed(ReachabilityInfo *r1, ReachabilityInfo *r2)
 
 
 static __inline__ void
 
 
 static __inline__ void
-_reach_set(ReachabilityInfo *dst, const ReachabilityInfo *src, uint64_t cycle)
+_reach_set(ReachabilityInfo            *dst,
+          const ReachabilityInfo       *src,
+          uint64_t                     cycle,
+          unsigned int                 requested_if_index,
+          const char                   *requested_if_name)
 {
        memcpy(dst, src, sizeof(ReachabilityInfo));
        dst->cycle = cycle;
 
 {
        memcpy(dst, src, sizeof(ReachabilityInfo));
        dst->cycle = cycle;
 
+       if (!(dst->flags & kSCNetworkReachabilityFlagsReachable) ||
+               (dst->flags & kSCNetworkReachabilityFlagsConnectionRequired)) {
+               // if not reachable or connection required, return the
+               // requested if_index and if_name.
+               dst->if_index = requested_if_index;
+               if (requested_if_name != NULL) {
+                       strlcpy(dst->if_name, requested_if_name, sizeof(dst->if_name));
+               } else {
+                       dst->if_name[0] = '\0';
+               }
+       }
+
        return;
 }
 
        return;
 }
 
@@ -510,12 +542,20 @@ ReachabilityStoreInfo_save(ReachabilityStoreInfoRef store_info)
 static Boolean
 ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
 {
 static Boolean
 ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
 {
+       CFStringRef             key;
+       CFMutableArrayRef       keys;
        CFStringRef             pattern;
        CFMutableArrayRef       patterns;
 
        CFStringRef             pattern;
        CFMutableArrayRef       patterns;
 
+       keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
        // get info for IPv4 services
        patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
        // get info for IPv4 services
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetIPv4);
+       CFArrayAppendValue(keys, key);
+       CFRelease(key);
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
                                                              kSCCompAnyRegex,
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
                                                              kSCCompAnyRegex,
@@ -530,6 +570,11 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
        CFRelease(pattern);
 
        // get info for IPv6 services
        CFRelease(pattern);
 
        // get info for IPv6 services
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetIPv6);
+       CFArrayAppendValue(keys, key);
+       CFRelease(key);
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
                                                              kSCCompAnyRegex,
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
                                                              kSCCompAnyRegex,
@@ -557,7 +602,6 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
        CFArrayAppendValue(patterns, pattern);
        CFRelease(pattern);
 
        CFArrayAppendValue(patterns, pattern);
        CFRelease(pattern);
 
-#if    !TARGET_IPHONE_SIMULATOR
        // get info for VPN services
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
        // get info for VPN services
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainSetup,
@@ -571,7 +615,6 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
                                                              kSCEntNetVPN);
        CFArrayAppendValue(patterns, pattern);
        CFRelease(pattern);
                                                              kSCEntNetVPN);
        CFArrayAppendValue(patterns, pattern);
        CFRelease(pattern);
-#endif // !TARGET_IPHONE_SIMULATOR
 
        // get info for IPSec services
 //     pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
 
        // get info for IPSec services
 //     pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
@@ -597,7 +640,8 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info)
 
 
        // get the SCDynamicStore info
 
 
        // get the SCDynamicStore info
-       store_info->dict = SCDynamicStoreCopyMultiple(store_info->store, NULL, patterns);
+       store_info->dict = SCDynamicStoreCopyMultiple(store_info->store, keys, patterns);
+       CFRelease(keys);
        CFRelease(patterns);
        if (store_info->dict == NULL) {
                return FALSE;
        CFRelease(patterns);
        if (store_info->dict == NULL) {
                return FALSE;
@@ -711,6 +755,12 @@ ReachabilityStoreInfo_update(ReachabilityStoreInfoRef      store_info,
 
 
 #pragma mark -
 
 
 #pragma mark -
+#pragma mark Legacy Reachability Functions - to be deprecated.
+
+// Note: these can/should be removed when the iOS simulator will only
+//       be used on a system with the enhanced (with reachability
+//       flags) NWI content.
+
 #pragma mark PPP info
 
 
 #pragma mark PPP info
 
 
@@ -983,12 +1033,9 @@ updatePPPAvailable(ReachabilityStoreInfoRef       store_info,
        return sc_status;
 }
 
        return sc_status;
 }
 
-
-#pragma mark -
 #pragma mark VPN info
 
 
 #pragma mark VPN info
 
 
-#if    !TARGET_IPHONE_SIMULATOR
 static int
 updateVPNStatus(ReachabilityStoreInfoRef       store_info,
                const struct sockaddr           *sa,
 static int
 updateVPNStatus(ReachabilityStoreInfoRef       store_info,
                const struct sockaddr           *sa,
@@ -1216,10 +1263,8 @@ updateVPNAvailable(ReachabilityStoreInfoRef      store_info,
 
        return sc_status;
 }
 
        return sc_status;
 }
-#endif // !TARGET_IPHONE_SIMULATOR
 
 
 
 
-#pragma mark -
 #pragma mark IPSec info
 
 
 #pragma mark IPSec info
 
 
@@ -1398,7 +1443,7 @@ typedef struct {
 
 /*
  * route_get()
 
 /*
  * route_get()
- *     returns zero if route exists an data returned, EHOSTUNREACH
+ *     returns zero if route exists and data returned, EHOSTUNREACH
  *     if no route, or errno for any other error.
  */
 static int
  *     if no route, or errno for any other error.
  */
 static int
@@ -1572,7 +1617,7 @@ route_get(const struct sockaddr   *address,
                        }
                }
        }
                        }
                }
        }
-#endif /* LOG_RTADDRS */
+#endif // LOG_RTADDRS
 
        if ((info->rti_info[RTAX_IFP] == NULL) ||
            (info->rti_info[RTAX_IFP]->sa_family != AF_LINK)) {
 
        if ((info->rti_info[RTAX_IFP] == NULL) ||
            (info->rti_info[RTAX_IFP]->sa_family != AF_LINK)) {
@@ -1591,31 +1636,21 @@ route_get(const struct sockaddr *address,
        return 0;
 }
 
        return 0;
 }
 
-
-static Boolean
-checkAddress(ReachabilityStoreInfoRef  store_info,
-            const struct sockaddr      *address,
-            unsigned int               if_index,
-            ReachabilityInfo           *reach_info,
-            const char                 *log_prefix)
+static int
+checkAddressRoute(const struct sockaddr        *address,
+                 unsigned int          if_index,
+                 char                  *if_name,
+                 struct ifreq          *ifr,
+                 ReachabilityInfo      *reach_info,
+                 route_info            *info,
+                 int                   *sc_status,
+                 const char            *log_prefix)
 {
 {
-       route_info              info;
-       struct ifreq            ifr;
-       char                    if_name[IFNAMSIZ];
        int                     isock           = -1;
        int                     isock           = -1;
-       int                     ret;
-       int                     sc_status       = kSCStatusReachabilityUnknown;
-       CFStringRef             server          = NULL;
+       int                     ret             = 0;
        char                    *statusMessage  = NULL;
        struct sockaddr_in      v4mapped;
 
        char                    *statusMessage  = NULL;
        struct sockaddr_in      v4mapped;
 
-       _reach_set(reach_info, &NOT_REACHABLE, reach_info->cycle);
-
-       if (address == NULL) {
-               /* special case: check only for available paths off the system */
-               goto checkAvailable;
-       }
-
        switch (address->sa_family) {
                case AF_INET :
                case AF_INET6 :
        switch (address->sa_family) {
                case AF_INET :
                case AF_INET6 :
@@ -1645,7 +1680,8 @@ checkAddress(ReachabilityStoreInfoRef     store_info,
                        SCLog(TRUE, LOG_INFO,
                              CFSTR("checkAddress(): unexpected address family %d"),
                              address->sa_family);
                        SCLog(TRUE, LOG_INFO,
                              CFSTR("checkAddress(): unexpected address family %d"),
                              address->sa_family);
-                       sc_status = kSCStatusInvalidArgument;
+                       *sc_status = kSCStatusInvalidArgument;
+                       ret = EPERM;
                        goto done;
        }
 
                        goto done;
        }
 
@@ -1663,16 +1699,16 @@ checkAddress(ReachabilityStoreInfoRef   store_info,
                }
        }
 
                }
        }
 
-       ret = route_get(address, if_index, &info);
+       ret = route_get(address, if_index, info);
        switch (ret) {
                case 0 :
                        break;
                case EHOSTUNREACH :
                        // if no route
        switch (ret) {
                case 0 :
                        break;
                case EHOSTUNREACH :
                        // if no route
-                       goto checkAvailable;
+                       goto done;
                default :
                        // if error
                default :
                        // if error
-                       sc_status = ret;
+                       *sc_status = ret;
                        goto done;
        }
 
                        goto done;
        }
 
@@ -1680,45 +1716,48 @@ checkAddress(ReachabilityStoreInfoRef   store_info,
 
        isock = socket(AF_INET, SOCK_DGRAM, 0);
        if (isock == -1) {
 
        isock = socket(AF_INET, SOCK_DGRAM, 0);
        if (isock == -1) {
+               ret = errno;
                SCLog(TRUE, LOG_ERR, CFSTR("socket() failed: %s"), strerror(errno));
                goto done;
        }
 
                SCLog(TRUE, LOG_ERR, CFSTR("socket() failed: %s"), strerror(errno));
                goto done;
        }
 
-       bzero(&ifr, sizeof(ifr));
-       bcopy(info.sdl->sdl_data, ifr.ifr_name, info.sdl->sdl_nlen);
+       bzero(ifr, sizeof(*ifr));
+       bcopy(info->sdl->sdl_data, ifr->ifr_name, info->sdl->sdl_nlen);
 
 
-       if (ioctl(isock, SIOCGIFFLAGS, (char *)&ifr) == -1) {
-               SCLog(TRUE, LOG_ERR, CFSTR("ioctl() failed: %s"), strerror(errno));
+       if (ioctl(isock, SIOCGIFFLAGS, (char *)ifr) == -1) {
+               ret = errno;
+               SCLog(TRUE, LOG_ERR, CFSTR("ioctl(SIOCGIFFLAGS) failed: %s"), strerror(errno));
                goto done;
        }
 
                goto done;
        }
 
-       if (!(ifr.ifr_flags & IFF_UP)) {
-               goto checkAvailable;
+       if (!(ifr->ifr_flags & IFF_UP)) {
+               ret = EHOSTUNREACH;
+               goto done;
        }
 
        statusMessage = "isReachable";
        reach_info->flags |= kSCNetworkReachabilityFlagsReachable;
 
        }
 
        statusMessage = "isReachable";
        reach_info->flags |= kSCNetworkReachabilityFlagsReachable;
 
-       if (info.rtm->rtm_flags & RTF_LOCAL) {
+       if (info->rtm->rtm_flags & RTF_LOCAL) {
                statusMessage = "isReachable (is a local address)";
                reach_info->flags |= kSCNetworkReachabilityFlagsIsLocalAddress;
                statusMessage = "isReachable (is a local address)";
                reach_info->flags |= kSCNetworkReachabilityFlagsIsLocalAddress;
-       } else if (ifr.ifr_flags & IFF_LOOPBACK) {
+       } else if (ifr->ifr_flags & IFF_LOOPBACK) {
                statusMessage = "isReachable (is loopback network)";
                reach_info->flags |= kSCNetworkReachabilityFlagsIsLocalAddress;
                statusMessage = "isReachable (is loopback network)";
                reach_info->flags |= kSCNetworkReachabilityFlagsIsLocalAddress;
-       } else if ((info.rti_info[RTAX_IFA] != NULL) &&
-                  (info.rti_info[RTAX_IFA]->sa_family != AF_LINK)) {
+       } else if ((info->rti_info[RTAX_IFA] != NULL) &&
+                  (info->rti_info[RTAX_IFA]->sa_family != AF_LINK)) {
                void    *addr1  = (void *)address;
                void    *addr1  = (void *)address;
-               void    *addr2  = (void *)info.rti_info[RTAX_IFA];
+               void    *addr2  = (void *)info->rti_info[RTAX_IFA];
                size_t  len     = address->sa_len;
 
                size_t  len     = address->sa_len;
 
-               if ((address->sa_family != info.rti_info[RTAX_IFA]->sa_family) &&
-                   (address->sa_len    != info.rti_info[RTAX_IFA]->sa_len)) {
+               if ((address->sa_family != info->rti_info[RTAX_IFA]->sa_family) &&
+                   (address->sa_len    != info->rti_info[RTAX_IFA]->sa_len)) {
                        SCLog(TRUE, LOG_NOTICE,
                              CFSTR("address family/length mismatch: %d/%d != %d/%d"),
                              address->sa_family,
                              address->sa_len,
                        SCLog(TRUE, LOG_NOTICE,
                              CFSTR("address family/length mismatch: %d/%d != %d/%d"),
                              address->sa_family,
                              address->sa_len,
-                             info.rti_info[RTAX_IFA]->sa_family,
-                             info.rti_info[RTAX_IFA]->sa_len);
+                             info->rti_info[RTAX_IFA]->sa_family,
+                             info->rti_info[RTAX_IFA]->sa_len);
                        goto done;
                }
 
                        goto done;
                }
 
@@ -1726,7 +1765,7 @@ checkAddress(ReachabilityStoreInfoRef     store_info,
                        case AF_INET :
                                /* ALIGN: cast ok, because only bcmp is used. */
                                addr1 = &((struct sockaddr_in *)(void *)address)->sin_addr;
                        case AF_INET :
                                /* ALIGN: cast ok, because only bcmp is used. */
                                addr1 = &((struct sockaddr_in *)(void *)address)->sin_addr;
-                               addr2 = &((struct sockaddr_in *)(void *)info.rti_info[RTAX_IFA])->sin_addr;
+                               addr2 = &((struct sockaddr_in *)(void *)info->rti_info[RTAX_IFA])->sin_addr;
                                len = sizeof(struct in_addr);
 
                                /*
                                len = sizeof(struct in_addr);
 
                                /*
@@ -1739,9 +1778,9 @@ checkAddress(ReachabilityStoreInfoRef     store_info,
                                }
                                break;
                        case AF_INET6 :
                                }
                                break;
                        case AF_INET6 :
-                                /* ALIGN: cast ok, because only bcmp is used. */
+                               /* ALIGN: cast ok, because only bcmp is used. */
                                addr1 = &((struct sockaddr_in6 *)(void *)address)->sin6_addr;
                                addr1 = &((struct sockaddr_in6 *)(void *)address)->sin6_addr;
-                               addr2 = &((struct sockaddr_in6 *)(void *)info.rti_info[RTAX_IFA])->sin6_addr;
+                               addr2 = &((struct sockaddr_in6 *)(void *)info->rti_info[RTAX_IFA])->sin6_addr;
                                len = sizeof(struct in6_addr);
                                break;
                        default :
                                len = sizeof(struct in6_addr);
                                break;
                        default :
@@ -1754,86 +1793,224 @@ checkAddress(ReachabilityStoreInfoRef  store_info,
                }
        }
 
                }
        }
 
-       if (!(info.rtm->rtm_flags & RTF_GATEWAY) &&
-           (info.rti_info[RTAX_GATEWAY] != NULL) &&
-           (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) &&
-           !(ifr.ifr_flags & IFF_POINTOPOINT)) {
+       if (!(info->rtm->rtm_flags & RTF_GATEWAY) &&
+           (info->rti_info[RTAX_GATEWAY] != NULL) &&
+           (info->rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) &&
+           !(ifr->ifr_flags & IFF_POINTOPOINT)) {
                reach_info->flags |= kSCNetworkReachabilityFlagsIsDirect;
        }
 
                reach_info->flags |= kSCNetworkReachabilityFlagsIsDirect;
        }
 
-       bzero(&if_name, sizeof(if_name));
-       bcopy(info.sdl->sdl_data,
+       bzero(if_name, IFNAMSIZ);
+       bcopy(info->sdl->sdl_data,
              if_name,
              if_name,
-             (info.sdl->sdl_nlen <= IFNAMSIZ) ? info.sdl->sdl_nlen : IFNAMSIZ);
+             (info->sdl->sdl_nlen <= IFNAMSIZ) ? info->sdl->sdl_nlen : IFNAMSIZ);
 
        strlcpy(reach_info->if_name, if_name, sizeof(reach_info->if_name));
 
        strlcpy(reach_info->if_name, if_name, sizeof(reach_info->if_name));
-       reach_info->if_index = info.sdl->sdl_index;
+       reach_info->if_index = info->sdl->sdl_index;
 
        if (_sc_debug) {
                SCLog(TRUE, LOG_INFO, CFSTR("%s  status    = %s"), log_prefix, statusMessage);
 
        if (_sc_debug) {
                SCLog(TRUE, LOG_INFO, CFSTR("%s  status    = %s"), log_prefix, statusMessage);
-               SCLog(TRUE, LOG_INFO, CFSTR("%s  device    = %s (%hu)"), log_prefix, if_name, info.sdl->sdl_index);
-               SCLog(TRUE, LOG_INFO, CFSTR("%s  sdl_type  = 0x%x"), log_prefix, info.sdl->sdl_type);
-               SCLog(TRUE, LOG_INFO, CFSTR("%s  ifr_flags = 0x%04hx"), log_prefix, ifr.ifr_flags);
-               SCLog(TRUE, LOG_INFO, CFSTR("%s  rtm_flags = 0x%08x"), log_prefix, info.rtm->rtm_flags);
-       }
+               SCLog(TRUE, LOG_INFO, CFSTR("%s  device    = %s (%hu)"), log_prefix, if_name, info->sdl->sdl_index);
+               SCLog(TRUE, LOG_INFO, CFSTR("%s  sdl_type  = 0x%x"), log_prefix, info->sdl->sdl_type);
+               SCLog(TRUE, LOG_INFO, CFSTR("%s  ifr_flags = 0x%04hx"), log_prefix, ifr->ifr_flags);
+               SCLog(TRUE, LOG_INFO, CFSTR("%s  rtm_flags = 0x%08x"), log_prefix, info->rtm->rtm_flags);
+       }
+done :
+       if (isock != -1) (void)close(isock);
+       return ret;
+}
+
+static Boolean
+checkAddress_with_nwi(const struct sockaddr     *address,
+                     unsigned int              if_index,
+                     ReachabilityInfo          *reach_info,
+                     const char                *log_prefix)
+{
+       route_info              info;
+       struct ifreq            ifr;
+       char                    if_name[IFNAMSIZ];
+       nwi_ifstate_t           ifstate;
+       nwi_state_t             nwi_state;
+       int                     ret;
+       int                     sc_status       = kSCStatusReachabilityUnknown;
+
+       _reach_set(reach_info, &NOT_REACHABLE, reach_info->cycle, if_index, NULL);
+
+       nwi_state = nwi_state_copy();
 
 
-       sc_status = kSCStatusOK;
+       if (address != NULL) {
+               ret = checkAddressRoute(address,
+                                       if_index,
+                                       if_name,
+                                       &ifr,
+                                       reach_info,
+                                       &info,
+                                       &sc_status,
+                                       log_prefix);
 
 
-       if (ifr.ifr_flags & IFF_POINTOPOINT) {
-               reach_info->flags |= kSCNetworkReachabilityFlagsTransientConnection;
+       }
+       else {
+               /* special case: check only for available paths off the system */
+               ret = EHOSTUNREACH;
        }
 
        }
 
-       if (info.sdl->sdl_type == IFT_PPP) {
-               /*
-                * 1. check if PPP service
-                * 2. check for dial-on-demand PPP link that is not yet connected
-                * 3. get PPP server address
-                */
-               sc_status = updatePPPStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
-       } else if (info.sdl->sdl_type == IFT_OTHER) {
-               /*
-                * 1. check if IPSec service
-                * 2. get IPSec server address
-                */
-               sc_status = updateIPSecStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
+       if (ret == 0) {
+               const struct sockaddr   *vpn_server_address;
 
 
-#if    !TARGET_IPHONE_SIMULATOR
-               if (sc_status == kSCStatusNoKey) {
-                       /*
-                        * 1. check if VPN service
-                        * 2. get VPN server address
-                        */
-                       sc_status = updateVPNStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
+               sc_status = kSCStatusOK;
+
+               ifstate = nwi_state_get_ifstate(nwi_state, if_name);
+
+               if (ifstate == NULL) {
+                       goto done;
+               }
+
+               reach_info->flags |= nwi_ifstate_get_reachability_flags(ifstate);
+
+
+               vpn_server_address = nwi_ifstate_get_vpn_server(ifstate);
+               if (vpn_server_address != NULL) {
+                       char            dst_if_name[IFNAMSIZ];
+                       route_info      dst_info;
+
+                       ret = route_get(vpn_server_address, 0, &dst_info);
+                       if (ret != 0) {
+                               goto done;
+                       }
+
+                       bzero(&dst_if_name, sizeof(dst_if_name));
+                       bcopy(dst_info.sdl->sdl_data,
+                             dst_if_name,
+                             (dst_info.sdl->sdl_nlen <= IFNAMSIZ) ? dst_info.sdl->sdl_nlen : IFNAMSIZ);
+                       if (bcmp(if_name, dst_if_name, sizeof(if_name)) != 0) {
+                               nwi_ifstate_t ifstate;
+
+                               ifstate = nwi_state_get_ifstate(nwi_state, dst_if_name);
+                               if (ifstate != NULL) {
+                                       reach_info->flags |= nwi_ifstate_get_reachability_flags(ifstate);
+                               }
+                       }
+               }
+       } else if (ret == EHOSTUNREACH) {
+               if (if_index == 0) {
+                       sc_status = kSCStatusOK;
+                       reach_info->flags |= nwi_state_get_reachability_flags(nwi_state,
+                                                                             (address != NULL) ? address->sa_family
+                                                                             : AF_UNSPEC);
+               } else {
+                       // if scoped request
+                       sc_status = kSCStatusNoKey;
                }
                }
-#endif // !TARGET_IPHONE_SIMULATOR
+
+       }
+
+done:
+       if (reach_info->flags == 0) {
+               SCLog(_sc_debug, LOG_INFO, CFSTR("%s  cannot be reached"), log_prefix);
+       }
+
+       if (nwi_state != NULL) {
+               nwi_state_release(nwi_state);
+       }
+
+       if ((sc_status != kSCStatusOK) && (sc_status != kSCStatusNoKey)) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
        }
 
+       return TRUE;
+}
+
 
 
-       goto done;
+static Boolean
+checkAddress_bypass_nwi(ReachabilityStoreInfoRef       store_info,
+                       const struct sockaddr           *address,
+                       unsigned int                    if_index,
+                       ReachabilityInfo                *reach_info,
+                       const char                      *log_prefix)
+{
+       route_info              info;
+       struct ifreq            ifr;
+       char                    if_name[IFNAMSIZ];
+       int                     ret;
+       CFStringRef             server = NULL;
+       int                     sc_status       = kSCStatusReachabilityUnknown;
 
 
-    checkAvailable :
+       _reach_set(reach_info, &NOT_REACHABLE, reach_info->cycle, if_index, NULL);
 
 
+       if (address != NULL) {
+               ret = checkAddressRoute(address,
+                                       if_index,
+                                       if_name,
+                                       &ifr,
+                                       reach_info,
+                                       &info,
+                                       &sc_status,
+                                       log_prefix);
 
 
-       sc_status = updatePPPAvailable(store_info, address, &reach_info->flags, log_prefix);
-       if ((sc_status == kSCStatusOK) && (reach_info->flags != 0)) {
-               goto done;
+       }
+       else {
+               /* special case: check only for available paths off the system */
+               ret = EHOSTUNREACH;
        }
 
        }
 
-#if    !TARGET_IPHONE_SIMULATOR
-       sc_status = updateVPNAvailable(store_info, address, &reach_info->flags, log_prefix);
-       if ((sc_status == kSCStatusOK) && (reach_info->flags != 0)) {
-               goto done;
+       if (ret == 0) {
+               sc_status = kSCStatusOK;
+
+               if (ifr.ifr_flags & IFF_POINTOPOINT) {
+                       reach_info->flags |= kSCNetworkReachabilityFlagsTransientConnection;
+               }
+
+               if (info.sdl->sdl_type == IFT_PPP) {
+                       /*
+                        * 1. check if PPP service
+                        * 2. check for dial-on-demand PPP link that is not yet connected
+                        * 3. get PPP server address
+                        */
+                       sc_status = updatePPPStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
+               } else if (info.sdl->sdl_type == IFT_OTHER) {
+                       /*
+                        * 1. check if IPSec service
+                        * 2. get IPSec server address
+                        */
+                       sc_status = updateIPSecStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
+                       if (sc_status == kSCStatusNoKey) {
+                               /*
+                                * 1. check if VPN service
+                                * 2. get VPN server address
+                                */
+                               sc_status = updateVPNStatus(store_info, address, if_name, &reach_info->flags, &server, log_prefix);
+                       }
+               }
+
+       } else if (ret == EHOSTUNREACH) {
+               if (if_index != 0) {
+                       // if scoped request
+                       sc_status = kSCStatusNoKey;
+                       goto done;
+               }
+
+
+               sc_status = updatePPPAvailable(store_info, address, &reach_info->flags, log_prefix);
+               if ((sc_status == kSCStatusOK) && (reach_info->flags != 0)) {
+                       goto done;
+               }
+
+               sc_status = updateVPNAvailable(store_info, address, &reach_info->flags, log_prefix);
+               if ((sc_status == kSCStatusOK) && (reach_info->flags != 0)) {
+                       goto done;
+               }
+
        }
        }
-#endif // !TARGET_IPHONE_SIMULATOR
 
 
-    done :
+done :
 
        if (reach_info->flags == 0) {
                SCLog(_sc_debug, LOG_INFO, CFSTR("%s  cannot be reached"), log_prefix);
        }
 
 
        if (reach_info->flags == 0) {
                SCLog(_sc_debug, LOG_INFO, CFSTR("%s  cannot be reached"), log_prefix);
        }
 
-       if (isock != -1)        (void)close(isock);
        if (server != NULL)     CFRelease(server);
        if (server != NULL)     CFRelease(server);
+
        if ((sc_status != kSCStatusOK) && (sc_status != kSCStatusNoKey)) {
                _SCErrorSet(sc_status);
                return FALSE;
        if ((sc_status != kSCStatusOK) && (sc_status != kSCStatusNoKey)) {
                _SCErrorSet(sc_status);
                return FALSE;
@@ -1843,6 +2020,28 @@ checkAddress(ReachabilityStoreInfoRef    store_info,
 }
 
 
 }
 
 
+static inline Boolean
+checkAddress(ReachabilityStoreInfoRef  store_info,
+            const struct sockaddr      *address,
+            unsigned int               if_index,
+            ReachabilityInfo           *reach_info,
+            const char                 *log_prefix)
+{
+       if (!D_nwiBypass) {
+               return (checkAddress_with_nwi(address,
+                                             if_index,
+                                             reach_info,
+                                             log_prefix));
+
+       }
+
+       return (checkAddress_bypass_nwi(store_info,
+                                       address,
+                                       if_index,
+                                       reach_info,
+                                       log_prefix));
+}
+
 #pragma mark -
 #pragma mark SCNetworkReachability APIs
 
 #pragma mark -
 #pragma mark SCNetworkReachability APIs
 
@@ -1883,14 +2082,7 @@ _SCNetworkReachabilityCopyTargetDescription(SCNetworkReachabilityRef target)
                        break;
                }
                case reachabilityTypeName : {
                        break;
                }
                case reachabilityTypeName : {
-                       if ((targetPrivate->name != NULL)) {
-                               CFStringAppendFormat(str, NULL, CFSTR("name = %s"), targetPrivate->name);
-                       }
-                       if ((targetPrivate->serv != NULL)) {
-                               CFStringAppendFormat(str, NULL, CFSTR("%sserv = %s"),
-                                                    targetPrivate->name != NULL ? ", " : "",
-                                                    targetPrivate->serv);
-                       }
+                       CFStringAppendFormat(str, NULL, CFSTR("name = %s"), targetPrivate->name);
                        break;
                }
        }
                        break;
                }
        }
@@ -1908,7 +2100,7 @@ _SCNetworkReachabilityCopyTargetFlags(SCNetworkReachabilityRef target)
 
        str = CFStringCreateWithFormat(allocator,
                                       NULL,
 
        str = CFStringCreateWithFormat(allocator,
                                       NULL,
-                                      CFSTR("flags = 0x%08x, if_index = %hu%s"),
+                                      CFSTR("flags = 0x%08x, if_index = %u%s"),
                                       targetPrivate->info.flags,
                                       targetPrivate->info.if_index,
                                       targetPrivate->info.sleeping ? ", z" : "");
                                       targetPrivate->info.flags,
                                       targetPrivate->info.if_index,
                                       targetPrivate->info.sleeping ? ", z" : "");
@@ -1935,15 +2127,20 @@ __SCNetworkReachabilityCopyDescription(CFTypeRef cf)
 
        // add additional "name" info
        if (targetPrivate->type == reachabilityTypeName) {
 
        // add additional "name" info
        if (targetPrivate->type == reachabilityTypeName) {
-               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
+               if (targetPrivate->dnsActive) {
                        CFStringAppendFormat(result, NULL, CFSTR(" (DNS query active)"));
                        CFStringAppendFormat(result, NULL, CFSTR(" (DNS query active)"));
-               } else if (targetPrivate->dnsRetry != NULL) {
-                       CFStringAppendFormat(result, NULL, CFSTR(" (DNS retry queued)"));
-               } else if ((targetPrivate->resolvedAddress != NULL) || (targetPrivate->resolvedAddressError != NETDB_SUCCESS)) {
-                       if (targetPrivate->resolvedAddress != NULL) {
-                               if (isA_CFArray(targetPrivate->resolvedAddress)) {
+#ifdef HAVE_REACHABILITY_SERVER
+               } else if (targetPrivate->serverActive &&
+                          (targetPrivate->info.flags & kSCNetworkReachabilityFlagsFirstResolvePending)) {
+                       CFStringAppendFormat(result, NULL, CFSTR(" (server query active)"));
+#endif // HAVE_REACHABILITY_SERVER
+               } else if (targetPrivate->dnsMP != MACH_PORT_NULL) {
+                       CFStringAppendFormat(result, NULL, CFSTR(" (DNS* query active)"));
+               } else if ((targetPrivate->resolvedAddresses != NULL) || (targetPrivate->resolvedError != NETDB_SUCCESS)) {
+                       if (targetPrivate->resolvedAddresses != NULL) {
+                               if (isA_CFArray(targetPrivate->resolvedAddresses)) {
                                        CFIndex i;
                                        CFIndex i;
-                                       CFIndex n       = CFArrayGetCount(targetPrivate->resolvedAddress);
+                                       CFIndex n       = CFArrayGetCount(targetPrivate->resolvedAddresses);
 
                                        CFStringAppendFormat(result, NULL, CFSTR(" ("));
                                        for (i = 0; i < n; i++) {
 
                                        CFStringAppendFormat(result, NULL, CFSTR(" ("));
                                        for (i = 0; i < n; i++) {
@@ -1951,31 +2148,38 @@ __SCNetworkReachabilityCopyDescription(CFTypeRef cf)
                                                char            buf[64];
                                                struct sockaddr *sa;
 
                                                char            buf[64];
                                                struct sockaddr *sa;
 
-                                               address = CFArrayGetValueAtIndex(targetPrivate->resolvedAddress, i);
+                                               address = CFArrayGetValueAtIndex(targetPrivate->resolvedAddresses, i);
                                                sa      = (struct sockaddr *)CFDataGetBytePtr(address);
                                                _SC_sockaddr_to_string(sa, buf, sizeof(buf));
                                                CFStringAppendFormat(result, NULL, CFSTR("%s%s"),
                                                                     i > 0 ? ", " : "",
                                                                     buf);
                                        }
                                                sa      = (struct sockaddr *)CFDataGetBytePtr(address);
                                                _SC_sockaddr_to_string(sa, buf, sizeof(buf));
                                                CFStringAppendFormat(result, NULL, CFSTR("%s%s"),
                                                                     i > 0 ? ", " : "",
                                                                     buf);
                                        }
-                               } else if (CFEqual(targetPrivate->resolvedAddress, kCFNull)) {
-                                       CFStringAppendFormat(result, NULL, CFSTR(" (%s"),
-                                                            gai_strerror(targetPrivate->resolvedAddressError));
+                                       CFStringAppendFormat(result, NULL, CFSTR(")"));
+                               } else if (CFEqual(targetPrivate->resolvedAddresses, kCFNull)) {
+                                       CFStringAppendFormat(result, NULL, CFSTR(" (%s)"),
+                                                            gai_strerror(targetPrivate->resolvedError));
                                } else {
                                } else {
-                                       CFStringAppendFormat(result, NULL, CFSTR(" (no addresses"));
+                                       CFStringAppendFormat(result, NULL, CFSTR(" (no addresses)"));
                                }
                        } else {
                                }
                        } else {
-                               CFStringAppendFormat(result, NULL, CFSTR(" (%s"),
-                                                    gai_strerror(targetPrivate->resolvedAddressError));
-                       }
-                       if (targetPrivate->llqActive) {
-                               CFStringAppendFormat(result, NULL, CFSTR("), DNS llq active"));
-                       } else {
-                               CFStringAppendFormat(result, NULL, CFSTR(")"));
+                               CFStringAppendFormat(result, NULL, CFSTR(" (%s)"),
+                                                    gai_strerror(targetPrivate->resolvedError));
                        }
                        }
-               } else if (targetPrivate->llqActive) {
-                       CFStringAppendFormat(result, NULL, CFSTR(" (DNS llq active)"));
                }
                }
+               if (targetPrivate->dnsFlags != 0) {
+                       CFStringAppendFormat(result, NULL, CFSTR(", " DNS_FLAGS_FORMAT),
+                                            DNS_FLAGS_VALUES(targetPrivate));
+               }
+       }
+
+       if (targetPrivate->onDemandBypass) {
+               CFStringAppendFormat(result, NULL, CFSTR(", !ondemand"));
+       }
+
+
+       if (targetPrivate->resolverBypass) {
+               CFStringAppendFormat(result, NULL, CFSTR(", !resolve"));
        }
 
 
        }
 
 
@@ -2016,11 +2220,8 @@ __SCNetworkReachabilityDeallocate(CFTypeRef cf)
        if (targetPrivate->name != NULL)
                CFAllocatorDeallocate(NULL, (void *)targetPrivate->name);
 
        if (targetPrivate->name != NULL)
                CFAllocatorDeallocate(NULL, (void *)targetPrivate->name);
 
-       if (targetPrivate->serv != NULL)
-               CFAllocatorDeallocate(NULL, (void *)targetPrivate->serv);
-
-       if (targetPrivate->resolvedAddress != NULL)
-               CFRelease(targetPrivate->resolvedAddress);
+       if (targetPrivate->resolvedAddresses != NULL)
+               CFRelease(targetPrivate->resolvedAddresses);
 
        if (targetPrivate->localAddress != NULL)
                CFAllocatorDeallocate(NULL, (void *)targetPrivate->localAddress);
 
        if (targetPrivate->localAddress != NULL)
                CFAllocatorDeallocate(NULL, (void *)targetPrivate->localAddress);
@@ -2081,11 +2282,6 @@ __SCNetworkReachabilityInitialize(void)
                _sc_debug = TRUE;
        }
 
                _sc_debug = TRUE;
        }
 
-       // set per-process "bypass" of the SCNetworkReachability server
-       if (getenv("LONG_LIVED_QUERY_BYPASS") != NULL) {
-               D_llqBypass = TRUE;
-       }
-
 #ifdef HAVE_REACHABILITY_SERVER
        // set per-process "bypass" of the SCNetworkReachability server
        if (getenv("REACH_SERVER_BYPASS") != NULL) {
 #ifdef HAVE_REACHABILITY_SERVER
        // set per-process "bypass" of the SCNetworkReachability server
        if (getenv("REACH_SERVER_BYPASS") != NULL) {
@@ -2093,6 +2289,11 @@ __SCNetworkReachabilityInitialize(void)
        }
 #endif // HAVE_REACHABILITY_SERVER
 
        }
 #endif // HAVE_REACHABILITY_SERVER
 
+
+       if (getenv("NWI_BYPASS") != NULL) {
+               D_nwiBypass = TRUE;
+       }
+
        pthread_mutexattr_init(&lock_attr);
        pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_ERRORCHECK);
 
        pthread_mutexattr_init(&lock_attr);
        pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_ERRORCHECK);
 
@@ -2118,26 +2319,22 @@ __SCNetworkReachability_concurrent_queue()
 
 
 /*
 
 
 /*
- * __SCNetworkReachabilityPerformInlineNoLock
+ * __SCNetworkReachabilityPerformConcurrent
  *
  * Calls reachPerform()
  * - caller must be holding a reference to the target
  * - caller must *not* be holding the target lock
  * - caller must be running on the __SCNetworkReachability_concurrent_queue()
  */
  *
  * Calls reachPerform()
  * - caller must be holding a reference to the target
  * - caller must *not* be holding the target lock
  * - caller must be running on the __SCNetworkReachability_concurrent_queue()
  */
-static __inline__ void
-__SCNetworkReachabilityPerformInlineNoLock(SCNetworkReachabilityRef target, Boolean needResolve)
+__private_extern__
+void
+__SCNetworkReachabilityPerformConcurrent(SCNetworkReachabilityRef target)
 {
        dispatch_queue_t                queue;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_LOCK(&targetPrivate->lock);
 
 {
        dispatch_queue_t                queue;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_LOCK(&targetPrivate->lock);
 
-       if (needResolve) {
-               // allow the DNS query to be [re-]started
-               targetPrivate->needResolve = TRUE;
-       }
-
        queue = targetPrivate->dispatchQueue;
        if (queue != NULL) {
                dispatch_group_t        group;
        queue = targetPrivate->dispatchQueue;
        if (queue != NULL) {
                dispatch_group_t        group;
@@ -2167,71 +2364,36 @@ __SCNetworkReachabilityPerformInlineNoLock(SCNetworkReachabilityRef target, Bool
 }
 
 
 }
 
 
-#ifdef HAVE_REACHABILITY_SERVER
 /*
 /*
- * __SCNetworkReachabilityPerformNoLock
+ * __SCNetworkReachabilityPerform
  *
  * Calls reachPerform()
  *
  * Calls reachPerform()
- * - caller must *not* be holding the target lock
- * - caller must *not* running on the __SCNetworkReachability_concurrent_queue()
+ * - caller can be holding the target lock
+ * - caller can be running on any dispatch queue
  */
 __private_extern__
 void
  */
 __private_extern__
 void
-__SCNetworkReachabilityPerformNoLock(SCNetworkReachabilityRef target)
+__SCNetworkReachabilityPerform(SCNetworkReachabilityRef target)
 {
        CFRetain(target);
        dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{
 {
        CFRetain(target);
        dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{
-               __SCNetworkReachabilityPerformInlineNoLock(target, FALSE);
+               __SCNetworkReachabilityPerformConcurrent(target);
                CFRelease(target);
        });
 
        return;
 }
                CFRelease(target);
        });
 
        return;
 }
-#endif // HAVE_REACHABILITY_SERVER
-
-
-/*
- * __SCNetworkReachabilityPerformConcurrent
- *
- * Calls reachPerform()
- * - caller must be holding the target lock
- * - caller running on the __SCNetworkReachability_concurrent_queue()
- */
-static __inline__ void
-__SCNetworkReachabilityPerformConcurrent(SCNetworkReachabilityRef target)
-{
-       dispatch_queue_t                queue;
-       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
-
-       MUTEX_ASSERT_HELD(&targetPrivate->lock);
-
-       queue = targetPrivate->dispatchQueue;
-       if (queue != NULL) {
-               CFRetain(target);
-               dispatch_group_async(targetPrivate->dispatchGroup, queue, ^{
-                       reachPerform((void *)target);
-                       CFRelease(target);
-               });
-       } else {
-               if (targetPrivate->rls != NULL) {
-                       CFRunLoopSourceSignal(targetPrivate->rls);
-                       _SC_signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
-               }
-       }
-
-       return;
-}
 
 
 /*
 
 
 /*
- * __SCNetworkReachabilityPerform
+ * __SCNetworkReachabilityPerformLocked
  *
  * Calls reachPerform()
  * - caller must be holding the target lock
  * - caller not running on the __SCNetworkReachability_concurrent_queue()
  */
 static void
  *
  * Calls reachPerform()
  * - caller must be holding the target lock
  * - caller not running on the __SCNetworkReachability_concurrent_queue()
  */
 static void
-__SCNetworkReachabilityPerform(SCNetworkReachabilityRef target)
+__SCNetworkReachabilityPerformLocked(SCNetworkReachabilityRef target)
 {
        dispatch_queue_t                queue;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 {
        dispatch_queue_t                queue;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
@@ -2277,79 +2439,18 @@ __SCNetworkReachabilityCreatePrivate(CFAllocatorRef     allocator)
                return NULL;
        }
 
                return NULL;
        }
 
+       bzero((void *)targetPrivate + sizeof(CFRuntimeBase), size);
+
        MUTEX_INIT(&targetPrivate->lock);
 
        MUTEX_INIT(&targetPrivate->lock);
 
-       targetPrivate->name                             = NULL;
-       targetPrivate->serv                             = NULL;
-       targetPrivate->hints                            = HINTS_DEFAULT;
-       targetPrivate->needResolve                      = FALSE;
-       targetPrivate->resolvedAddress                  = NULL;
-       targetPrivate->resolvedAddressError             = NETDB_SUCCESS;
+       targetPrivate->cycle                            = 1;
+       targetPrivate->last_notify                      = NOT_REPORTED;
 
 
-       targetPrivate->if_index                         = 0;
+#ifdef HAVE_REACHABILITY_SERVER
+       targetPrivate->serverBypass                     = D_serverBypass;
+#endif // HAVE_REACHABILITY_SERVER
 
 
-       targetPrivate->localAddress                     = NULL;
-       targetPrivate->remoteAddress                    = NULL;
 
 
-       targetPrivate->cycle                            = 1;
-       targetPrivate->info                             = NOT_REACHABLE;
-       targetPrivate->last_notify                      = NOT_REPORTED;
-
-       targetPrivate->scheduled                        = FALSE;
-       targetPrivate->rls                              = NULL;
-       targetPrivate->rlsFunction                      = NULL;
-       targetPrivate->rlsContext.info                  = NULL;
-       targetPrivate->rlsContext.retain                = NULL;
-       targetPrivate->rlsContext.release               = NULL;
-       targetPrivate->rlsContext.copyDescription       = NULL;
-       targetPrivate->rlList                           = NULL;
-
-       targetPrivate->haveDNS                          = FALSE;
-       targetPrivate->dnsMP                            = MACH_PORT_NULL;
-       targetPrivate->dnsPort                          = NULL;
-       targetPrivate->dnsRLS                           = NULL;
-       targetPrivate->dnsSource                        = NULL;
-       targetPrivate->dnsQueryStart                    = TIME_ZERO;
-       targetPrivate->dnsQueryEnd                      = TIME_ZERO;
-       targetPrivate->dnsRetry                         = NULL;
-       targetPrivate->dnsRetryCount                    = 0;
-
-       targetPrivate->last_dns                         = TIME_ZERO;
-       targetPrivate->last_network                     = TIME_ZERO;
-#if    !TARGET_OS_IPHONE
-       targetPrivate->last_power                       = TIME_ZERO;
-#endif // !TARGET_OS_IPHONE
-       targetPrivate->last_push                        = TIME_ZERO;
-
-       targetPrivate->onDemandBypass                   = FALSE;
-       targetPrivate->onDemandName                     = NULL;
-       targetPrivate->onDemandRemoteAddress            = NULL;
-       targetPrivate->onDemandServer                   = NULL;
-       targetPrivate->onDemandServiceID                = NULL;
-
-#ifdef HAVE_REACHABILITY_SERVER
-       targetPrivate->serverBypass                     = D_serverBypass;
-#endif // HAVE_REACHABILITY_SERVER
-
-
-       targetPrivate->llqActive                        = FALSE;
-       targetPrivate->llqBypass                        = D_llqBypass;
-       targetPrivate->llqTarget                        = NULL;
-       targetPrivate->llqTimer                         = NULL;
-
-#ifdef HAVE_REACHABILITY_SERVER
-       targetPrivate->serverActive                     = FALSE;
-       targetPrivate->serverScheduled                  = FALSE;
-       targetPrivate->serverInfo                       = NOT_REACHABLE;
-
-       targetPrivate->serverDigest                     = NULL;
-       targetPrivate->serverGroup                      = NULL;
-       targetPrivate->serverInfoValid                  = FALSE;
-       targetPrivate->serverQueryActive                = 0;
-       targetPrivate->serverQueue                      = NULL;
-       targetPrivate->serverReferences                 = 0;
-       targetPrivate->serverWatchers                   = NULL;
-#endif // HAVE_REACHABILITY_SERVER
 
        targetPrivate->log_prefix[0] = '\0';
        if (_sc_log > 0) {
 
        targetPrivate->log_prefix[0] = '\0';
        if (_sc_log > 0) {
@@ -2412,6 +2513,8 @@ is_valid_address(const struct sockaddr *address)
 }
 
 
 }
 
 
+
+
 SCNetworkReachabilityRef
 SCNetworkReachabilityCreateWithAddress(CFAllocatorRef          allocator,
                                       const struct sockaddr    *address)
 SCNetworkReachabilityRef
 SCNetworkReachabilityCreateWithAddress(CFAllocatorRef          allocator,
                                       const struct sockaddr    *address)
@@ -2433,6 +2536,7 @@ SCNetworkReachabilityCreateWithAddress(CFAllocatorRef             allocator,
        targetPrivate->remoteAddress = CFAllocatorAllocate(NULL, address->sa_len, 0);
        bcopy(address, targetPrivate->remoteAddress, address->sa_len);
 
        targetPrivate->remoteAddress = CFAllocatorAllocate(NULL, address->sa_len, 0);
        bcopy(address, targetPrivate->remoteAddress, address->sa_len);
 
+
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
              targetPrivate->log_prefix,
              DEBUG_REACHABILITY_TYPE_ADDRESS,
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
              targetPrivate->log_prefix,
              DEBUG_REACHABILITY_TYPE_ADDRESS,
@@ -2487,6 +2591,7 @@ SCNetworkReachabilityCreateWithAddressPair(CFAllocatorRef         allocator,
                bcopy(remoteAddress, targetPrivate->remoteAddress, remoteAddress->sa_len);
        }
 
                bcopy(remoteAddress, targetPrivate->remoteAddress, remoteAddress->sa_len);
        }
 
+
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
              targetPrivate->log_prefix,
              DEBUG_REACHABILITY_TYPE_ADDRESSPAIR,
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
              targetPrivate->log_prefix,
              DEBUG_REACHABILITY_TYPE_ADDRESSPAIR,
@@ -2500,6 +2605,9 @@ SCNetworkReachabilityRef
 SCNetworkReachabilityCreateWithName(CFAllocatorRef     allocator,
                                    const char          *nodename)
 {
 SCNetworkReachabilityCreateWithName(CFAllocatorRef     allocator,
                                    const char          *nodename)
 {
+#ifdef HAVE_REACHABILITY_SERVER
+       CFDictionaryRef                 appLayerVPNProperties;
+#endif // HAVE_REACHABILITY_SERVER
        union {
                struct sockaddr         sa;
                struct sockaddr_in      sin;
        union {
                struct sockaddr         sa;
                struct sockaddr_in      sin;
@@ -2538,6 +2646,14 @@ SCNetworkReachabilityCreateWithName(CFAllocatorRef       allocator,
        targetPrivate->info.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #ifdef HAVE_REACHABILITY_SERVER
        targetPrivate->serverInfo.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
        targetPrivate->info.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #ifdef HAVE_REACHABILITY_SERVER
        targetPrivate->serverInfo.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
+
+       /* make sure AppLayerVPN only is in client mode */
+       appLayerVPNProperties = VPNAppLayerCopyCurrentAppProperties();
+       if (appLayerVPNProperties != NULL) {
+               targetPrivate->useVPNAppLayer = TRUE;
+               targetPrivate->serverBypass = YES;
+               CFRelease(appLayerVPNProperties);
+       }
 #endif // HAVE_REACHABILITY_SERVER
 
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
 #endif // HAVE_REACHABILITY_SERVER
 
        SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s%s %@"),
@@ -2558,16 +2674,13 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef   allocator,
        const struct sockaddr           *addr_l         = NULL;
        const struct sockaddr           *addr_r         = NULL;
        CFDataRef                       data;
        const struct sockaddr           *addr_l         = NULL;
        const struct sockaddr           *addr_r         = NULL;
        CFDataRef                       data;
-       struct addrinfo                 *hints          = NULL;
        CFStringRef                     interface       = NULL;
        CFStringRef                     interface       = NULL;
-       CFBooleanRef                    llqBypass;
        CFStringRef                     nodename;
        CFBooleanRef                    onDemandBypass;
        CFBooleanRef                    resolverBypass;
 #ifdef HAVE_REACHABILITY_SERVER
        CFBooleanRef                    serverBypass;
 #endif // HAVE_REACHABILITY_SERVER
        CFStringRef                     nodename;
        CFBooleanRef                    onDemandBypass;
        CFBooleanRef                    resolverBypass;
 #ifdef HAVE_REACHABILITY_SERVER
        CFBooleanRef                    serverBypass;
 #endif // HAVE_REACHABILITY_SERVER
-       CFStringRef                     servname;
        SCNetworkReachabilityRef        target;
        SCNetworkReachabilityPrivateRef targetPrivate;
 
        SCNetworkReachabilityRef        target;
        SCNetworkReachabilityPrivateRef targetPrivate;
 
@@ -2582,12 +2695,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef    allocator,
                _SCErrorSet(kSCStatusInvalidArgument);
                return NULL;
        }
                _SCErrorSet(kSCStatusInvalidArgument);
                return NULL;
        }
-       servname = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionServName);
-       if ((servname != NULL) &&
-           (!isA_CFString(servname) || (CFStringGetLength(servname) == 0))) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
        data = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionLocalAddress);
        if (data != NULL) {
                if (!isA_CFData(data) || (CFDataGetLength(data) < sizeof(struct sockaddr_in))) {
        data = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionLocalAddress);
        if (data != NULL) {
                if (!isA_CFData(data) || (CFDataGetLength(data) < sizeof(struct sockaddr_in))) {
@@ -2604,23 +2711,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef    allocator,
                }
                addr_r = (const struct sockaddr *)CFDataGetBytePtr(data);
        }
                }
                addr_r = (const struct sockaddr *)CFDataGetBytePtr(data);
        }
-       data = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionHints);
-       if (data != NULL) {
-               if (!isA_CFData(data) || (CFDataGetLength(data) != sizeof(targetPrivate->hints))) {
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       return NULL;
-               }
-
-               /* ALIGN: CF aligns to >8 byte boundries */
-               hints = (struct addrinfo *)(void *)CFDataGetBytePtr(data);
-               if ((hints->ai_addrlen   != 0)    ||
-                   (hints->ai_addr      != NULL) ||
-                   (hints->ai_canonname != NULL) ||
-                   (hints->ai_next      != NULL)) {
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       return NULL;
-               }
-       }
        interface = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionInterface);
        if ((interface != NULL) &&
            (!isA_CFString(interface) || (CFStringGetLength(interface) == 0))) {
        interface = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionInterface);
        if ((interface != NULL) &&
            (!isA_CFString(interface) || (CFStringGetLength(interface) == 0))) {
@@ -2639,12 +2729,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef    allocator,
        }
 
 
        }
 
 
-       llqBypass = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionLongLivedQueryBypass);
-       if ((llqBypass != NULL) && !isA_CFBoolean(llqBypass)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
-
 #ifdef HAVE_REACHABILITY_SERVER
        serverBypass = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionServerBypass);
        if ((serverBypass != NULL) && !isA_CFBoolean(serverBypass)) {
 #ifdef HAVE_REACHABILITY_SERVER
        serverBypass = CFDictionaryGetValue(options, kSCNetworkReachabilityOptionServerBypass);
        if ((serverBypass != NULL) && !isA_CFBoolean(serverBypass)) {
@@ -2653,11 +2737,12 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef   allocator,
        }
 #endif // HAVE_REACHABILITY_SERVER
 
        }
 #endif // HAVE_REACHABILITY_SERVER
 
-       if ((nodename != NULL) || (servname != NULL)) {
+
+       if (nodename != NULL) {
                const char      *name;
 
                if ((addr_l != NULL) || (addr_r != NULL)) {
                const char      *name;
 
                if ((addr_l != NULL) || (addr_r != NULL)) {
-                       // can't have both a name/serv and an address
+                       // can't have both a nodename and an address
                        _SCErrorSet(kSCStatusInvalidArgument);
                        return NULL;
                }
                        _SCErrorSet(kSCStatusInvalidArgument);
                        return NULL;
                }
@@ -2671,7 +2756,7 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef     allocator,
                } else if (addr_r != NULL) {
                        target = SCNetworkReachabilityCreateWithAddress(NULL, addr_r);
                } else if (addr_l != NULL) {
                } else if (addr_r != NULL) {
                        target = SCNetworkReachabilityCreateWithAddress(NULL, addr_r);
                } else if (addr_l != NULL) {
-                       target = SCNetworkReachabilityCreateWithAddress(NULL, addr_l);
+                       target = SCNetworkReachabilityCreateWithAddressPair(NULL, addr_l, NULL);
                } else {
                        _SCErrorSet(kSCStatusInvalidArgument);
                        return NULL;
                } else {
                        _SCErrorSet(kSCStatusInvalidArgument);
                        return NULL;
@@ -2682,14 +2767,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef    allocator,
        }
 
        targetPrivate = (SCNetworkReachabilityPrivateRef)target;
        }
 
        targetPrivate = (SCNetworkReachabilityPrivateRef)target;
-       if (targetPrivate->type == reachabilityTypeName) {
-               if (servname != NULL) {
-                       targetPrivate->serv = _SC_cfstring_to_cstring(servname, NULL, 0, kCFStringEncodingUTF8);
-               }
-               if (hints != NULL) {
-                       bcopy(hints, &targetPrivate->hints, sizeof(targetPrivate->hints));
-               }
-       }
 
        if (interface != NULL) {
                if ((_SC_cfstring_to_cstring(interface,
 
        if (interface != NULL) {
                if ((_SC_cfstring_to_cstring(interface,
@@ -2704,10 +2781,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef    allocator,
        }
 
 
        }
 
 
-       if (llqBypass != NULL) {
-               targetPrivate->llqBypass = CFBooleanGetValue(llqBypass);
-       }
-
        if (onDemandBypass != NULL) {
                targetPrivate->onDemandBypass = CFBooleanGetValue(onDemandBypass);
        }
        if (onDemandBypass != NULL) {
                targetPrivate->onDemandBypass = CFBooleanGetValue(onDemandBypass);
        }
@@ -2717,11 +2790,13 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef   allocator,
        }
 
 #ifdef HAVE_REACHABILITY_SERVER
        }
 
 #ifdef HAVE_REACHABILITY_SERVER
-       if (serverBypass != NULL) {
+       /* if by name, make sure AppLayerVPN only is in client mode */
+       if (serverBypass != NULL && targetPrivate->useVPNAppLayer == FALSE) {
                targetPrivate->serverBypass = CFBooleanGetValue(serverBypass);
        }
 #endif // HAVE_REACHABILITY_SERVER
 
                targetPrivate->serverBypass = CFBooleanGetValue(serverBypass);
        }
 #endif // HAVE_REACHABILITY_SERVER
 
+
        if (_sc_debug && (_sc_log > 0)) {
                const char      *opt;
 
        if (_sc_debug && (_sc_log > 0)) {
                const char      *opt;
 
@@ -2775,12 +2850,12 @@ SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef       target,
        }
 
        if (error_num) {
        }
 
        if (error_num) {
-               *error_num = targetPrivate->resolvedAddressError;
+               *error_num = targetPrivate->resolvedError;
        }
 
        }
 
-       if (targetPrivate->resolvedAddress != NULL) {
-               if (isA_CFArray(targetPrivate->resolvedAddress)) {
-                       return CFRetain(targetPrivate->resolvedAddress);
+       if (targetPrivate->resolvedAddresses != NULL) {
+               if (isA_CFArray(targetPrivate->resolvedAddresses)) {
+                       return CFRetain(targetPrivate->resolvedAddresses);
                } else {
                        /* if status is known but no resolved addresses to return */
                        _SCErrorSet(kSCStatusOK);
                } else {
                        /* if status is known but no resolved addresses to return */
                        _SCErrorSet(kSCStatusOK);
@@ -2794,18 +2869,18 @@ SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef       target,
 
 
 static void
 
 
 static void
-__SCNetworkReachabilitySetResolvedAddress(int32_t                      status,
-                                         struct addrinfo               *res,
-                                         SCNetworkReachabilityRef      target)
+__SCNetworkReachabilitySetResolvedAddresses(int32_t                    status,
+                                           struct addrinfo             *res,
+                                           SCNetworkReachabilityRef    target)
 {
        struct addrinfo                         *resP;
        SCNetworkReachabilityPrivateRef         targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
 {
        struct addrinfo                         *resP;
        SCNetworkReachabilityPrivateRef         targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
-       if (targetPrivate->resolvedAddress != NULL) {
-               CFRelease(targetPrivate->resolvedAddress);
-               targetPrivate->resolvedAddress = NULL;
+       if (targetPrivate->resolvedAddresses != NULL) {
+               CFRelease(targetPrivate->resolvedAddresses);
+               targetPrivate->resolvedAddresses = NULL;
        }
 
        if ((status == 0) && (res != NULL)) {
        }
 
        if ((status == 0) && (res != NULL)) {
@@ -2827,23 +2902,23 @@ __SCNetworkReachabilitySetResolvedAddress(int32_t                       status,
                }
 
                /* save the resolved address[es] */
                }
 
                /* save the resolved address[es] */
-               targetPrivate->resolvedAddress      = addresses;
-               targetPrivate->resolvedAddressError = NETDB_SUCCESS;
+               targetPrivate->resolvedAddresses = addresses;
+               targetPrivate->resolvedError     = NETDB_SUCCESS;
        } else {
                SCLog(_sc_debug, LOG_INFO, CFSTR("%sgetaddrinfo() failed: %s"),
                      targetPrivate->log_prefix,
                      gai_strerror(status));
 
                /* save the error associated with the attempt to resolve the name */
        } else {
                SCLog(_sc_debug, LOG_INFO, CFSTR("%sgetaddrinfo() failed: %s"),
                      targetPrivate->log_prefix,
                      gai_strerror(status));
 
                /* save the error associated with the attempt to resolve the name */
-               targetPrivate->resolvedAddress      = CFRetain(kCFNull);
-               targetPrivate->resolvedAddressError = status;
+               targetPrivate->resolvedAddresses = CFRetain(kCFNull);
+               targetPrivate->resolvedError     = status;
        }
        targetPrivate->needResolve = FALSE;
 
        if (res != NULL)        freeaddrinfo(res);
 
        if (targetPrivate->scheduled) {
        }
        targetPrivate->needResolve = FALSE;
 
        if (res != NULL)        freeaddrinfo(res);
 
        if (targetPrivate->scheduled) {
-               __SCNetworkReachabilityPerform(target);
+               __SCNetworkReachabilityPerformLocked(target);
        }
 
        return;
        }
 
        return;
@@ -2851,18 +2926,18 @@ __SCNetworkReachabilitySetResolvedAddress(int32_t                       status,
 
 
 static void
 
 
 static void
-__SCNetworkReachabilityCallbackSetResolvedAddress(int32_t status, struct addrinfo *res, void *context)
+__SCNetworkReachabilityCallbackSetResolvedAddresses(int32_t status, struct addrinfo *res, void *context)
 {
        SCNetworkReachabilityRef        target          = (SCNetworkReachabilityRef)context;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
 {
        SCNetworkReachabilityRef        target          = (SCNetworkReachabilityRef)context;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
-       __dns_query_end(target,
-                       ((status == 0) && (res != NULL)),       // if successful query
-                       dns_query_async,                        // async
-                       &targetPrivate->dnsQueryStart,          // start time
-                       &targetPrivate->dnsQueryEnd);           // end time
+       __mark_operation_end(target,
+                            ((status == 0) && (res != NULL)),  // if successful query
+                            dns_query_async,                   // async
+                            &targetPrivate->dnsQueryStart,     // start time
+                            &targetPrivate->dnsQueryEnd);      // end time
 
 
-       __SCNetworkReachabilitySetResolvedAddress(status, res, target);
+       __SCNetworkReachabilitySetResolvedAddresses(status, res, target);
        return;
 }
 
        return;
 }
 
@@ -2896,12 +2971,8 @@ replyMPCopyDescription(const void *info)
 
        return CFStringCreateWithFormat(NULL,
                                        NULL,
 
        return CFStringCreateWithFormat(NULL,
                                        NULL,
-                                       CFSTR("<getaddrinfo_async_start reply MP> {%s%s%s%s%s, target = %p}"),
-                                       targetPrivate->name != NULL ? "name = " : "",
-                                       targetPrivate->name != NULL ? targetPrivate->name : "",
-                                       targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                                       targetPrivate->serv != NULL ? "serv = " : "",
-                                       targetPrivate->serv != NULL ? targetPrivate->serv : "",
+                                       CFSTR("<getaddrinfo_async_start reply MP> {name = %s, target = %p}"),
+                                       targetPrivate->name,
                                        target);
 }
 
                                        target);
 }
 
@@ -2984,11 +3055,11 @@ enqueueAsyncDNSQuery_dispatch(SCNetworkReachabilityRef target)
        });
 
        dispatch_source_set_cancel_handler(source, ^{
        });
 
        dispatch_source_set_cancel_handler(source, ^{
-#if    !TARGET_OS_EMBEDDED
+#if    !TARGET_OS_IPHONE
                mach_vm_address_t       context;
                mach_vm_address_t       context;
-#else  // !TARGET_OS_EMBEDDED
+#else  // !TARGET_OS_IPHONE
                mach_port_context_t     context;
                mach_port_context_t     context;
-#endif // !TARGET_OS_EMBEDDED
+#endif // !TARGET_OS_IPHONE
                kern_return_t           kr;
                mach_port_t             mp;
 
                kern_return_t           kr;
                mach_port_t             mp;
 
@@ -3084,7 +3155,7 @@ enqueueAsyncDNSQuery_CF(SCNetworkReachabilityRef target)
 
 
 static Boolean
 
 
 static Boolean
-enqueueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp)
+requeueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp)
 {
        Boolean                         ok              = FALSE;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 {
        Boolean                         ok              = FALSE;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
@@ -3109,6 +3180,50 @@ enqueueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp)
 }
 
 
 }
 
 
+static Boolean
+enqueueAsyncDNSQuery(SCNetworkReachabilityRef target)
+{
+       int                             error   = 0;
+       mach_port_t                     mp      = MACH_PORT_NULL;
+       Boolean                         ok;
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       // track the DNS resolution time
+       __mark_operation_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd);
+
+#ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
+       if (targetPrivate->if_index == 0) {
+#endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
+               error = getaddrinfo_async_start(&mp,
+                                               targetPrivate->name,
+                                               NULL,
+                                               &HINTS_DEFAULT,
+                                               __SCNetworkReachabilityCallbackSetResolvedAddresses,
+                                               (void *)target);
+#ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
+       } else {
+               mp = _getaddrinfo_interface_async_call(targetPrivate->name,
+                                                      NULL,
+                                                      &HINTS_DEFAULT,
+                                                      targetPrivate->if_name,
+                                                      __SCNetworkReachabilityCallbackSetResolvedAddresses,
+                                                      (void *)target);
+               if (mp == MACH_PORT_NULL) {
+                       error = EAI_SYSTEM;
+               }
+       }
+#endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
+       if (error != 0) {
+               /* save the error associated with the attempt to resolve the name */
+               __SCNetworkReachabilityCallbackSetResolvedAddresses(error, NULL, (void *)target);
+               return FALSE;
+       }
+
+       ok = requeueAsyncDNSQuery(target, mp);
+       return ok;
+}
+
+
 static void
 dequeueAsyncDNSQuery(SCNetworkReachabilityRef target, Boolean cancel)
 {
 static void
 dequeueAsyncDNSQuery(SCNetworkReachabilityRef target, Boolean cancel)
 {
@@ -3166,13 +3281,13 @@ getaddrinfo_async_handleCFReply(CFMachPortRef port, void *msg, CFIndex size, voi
        dequeueAsyncDNSQuery(target, FALSE);
        status = getaddrinfo_async_handle_reply(msg);
        if ((status == 0) &&
        dequeueAsyncDNSQuery(target, FALSE);
        status = getaddrinfo_async_handle_reply(msg);
        if ((status == 0) &&
-           (targetPrivate->resolvedAddress == NULL) && (targetPrivate->resolvedAddressError == NETDB_SUCCESS)) {
+           (targetPrivate->resolvedAddresses == NULL) && (targetPrivate->resolvedError == NETDB_SUCCESS)) {
                Boolean ok;
 
                // if the request is not complete and needs to be re-queued
                Boolean ok;
 
                // if the request is not complete and needs to be re-queued
-               ok = enqueueAsyncDNSQuery(target, mp);
+               ok = requeueAsyncDNSQuery(target, mp);
                if (!ok) {
                if (!ok) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("processAsyncDNSReply enqueueAsyncDNSQuery() failed"));
+                       SCLog(TRUE, LOG_ERR, CFSTR("processAsyncDNSReply requeueAsyncDNSQuery() failed"));
                }
        }
 
                }
        }
 
@@ -3195,36 +3310,10 @@ check_resolver_reachability(ReachabilityStoreInfoRef    store_info,
        if (resolver_if_index) *resolver_if_index = 0;
 
        if (resolver->n_nameserver > 0) {
        if (resolver_if_index) *resolver_if_index = 0;
 
        if (resolver->n_nameserver > 0) {
-#if    !TARGET_IPHONE_SIMULATOR
                *flags   = (SCNetworkReachabilityFlags)resolver->reach_flags;
                if (resolver_if_index != NULL) {
                        *resolver_if_index = resolver->if_index;
                }
                *flags   = (SCNetworkReachabilityFlags)resolver->reach_flags;
                if (resolver_if_index != NULL) {
                        *resolver_if_index = resolver->if_index;
                }
-#else  // !TARGET_IPHONE_SIMULATOR
-               int     i;
-
-               *flags = kSCNetworkReachabilityFlagsReachable;
-
-               for (i = 0; i < resolver->n_nameserver; i++) {
-                       struct sockaddr         *address        = resolver->nameserver[i];
-                       ReachabilityInfo        ns_info;
-
-                       ok = checkAddress(store_info, address, resolver->if_index, &ns_info, log_prefix);
-                       if (!ok) {
-                               /* not today */
-                               break;
-                       }
-
-                       if ((i == 0) ||
-                           (rankReachability(ns_info.flags) < rankReachability(*flags))) {
-                               /* return the worst case result */
-                               *flags = ns_info.flags;
-                               if (resolver_if_index != NULL) {
-                                       *resolver_if_index = ns_info.if_index;
-                               }
-                       }
-               }
-#endif // !TARGET_IPHONE_SIMULATOR
                *haveDNS = TRUE;
        } else {
                *flags   = kSCNetworkReachabilityFlagsReachable;
                *haveDNS = TRUE;
        } else {
                *flags   = kSCNetworkReachabilityFlagsReachable;
@@ -3489,7 +3578,6 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef  store_info,
                                SCNetworkReachabilityFlags      *flags,
                                Boolean                         *haveDNS,
                                const char                      *nodename,
                                SCNetworkReachabilityFlags      *flags,
                                Boolean                         *haveDNS,
                                const char                      *nodename,
-                               const char                      *servname,
                                unsigned int                    if_index,
                                uint32_t                        *resolver_if_index,
                                int                             *dns_config_index,
                                unsigned int                    if_index,
                                uint32_t                        *resolver_if_index,
                                int                             *dns_config_index,
@@ -3523,10 +3611,8 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef store_info,
 
        len = (nodename != NULL) ? strlen(nodename) : 0;
        if (len == 0) {
 
        len = (nodename != NULL) ? strlen(nodename) : 0;
        if (len == 0) {
-               if ((servname == NULL) || (strlen(servname) == 0)) {
-                       // if no nodename or servname, return not reachable
-                       *flags = 0;
-               }
+               // if no nodename, return not reachable
+               *flags = 0;
                return ok;
        }
 
                return ok;
        }
 
@@ -3537,7 +3623,8 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef  store_info,
                goto done;
        }
 
                goto done;
        }
 
-       if (dns->config->n_resolver == 0) {
+       default_resolver = get_default_resolver(dns->config, if_index);
+       if (default_resolver == NULL) {
                // if no resolver configuration
                SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS: no resolvers"), log_prefix);
                goto done;
                // if no resolver configuration
                SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS: no resolvers"), log_prefix);
                goto done;
@@ -3555,8 +3642,6 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef  store_info,
                }
        }
 
                }
        }
 
-       default_resolver = get_default_resolver(dns->config, if_index);
-
        /*
         * check if the provided name matches a supplemental domain
         */
        /*
         * check if the provided name matches a supplemental domain
         */
@@ -3599,7 +3684,8 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef  store_info,
                        if (*cp == '.') dots++;
                }
 
                        if (*cp == '.') dots++;
                }
 
-               if (dots > ndots) {
+               /* Per KB: HT4845 */
+               if (dots >= ndots) {
                        useDefault = TRUE;
                }
        }
                        useDefault = TRUE;
                }
        }
@@ -3701,37 +3787,11 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef        store_info,
 }
 
 
 }
 
 
-Boolean
-_SC_checkResolverReachability(SCDynamicStoreRef                        *storeP,
-                             SCNetworkReachabilityFlags        *flags,
-                             Boolean                           *haveDNS,
-                             const char                        *nodename,
-                             const char                        *servname)
-{
-       Boolean                 ok;
-       ReachabilityStoreInfo   store_info;
-
-       ReachabilityStoreInfo_init(&store_info);
-       ok = ReachabilityStoreInfo_update(&store_info, storeP, AF_UNSPEC);
-       if (!ok) {
-               goto done;
-       }
-
-       ok = _SC_R_checkResolverReachability(&store_info, flags, haveDNS, nodename,
-                                            servname, 0, NULL, NULL, "");
-
-    done :
-
-       ReachabilityStoreInfo_free(&store_info);
-       return ok;
-}
-
 Boolean
 __SC_checkResolverReachabilityInternal(SCDynamicStoreRef               *storeP,
                                       SCNetworkReachabilityFlags       *flags,
                                       Boolean                          *haveDNS,
                                       const char                       *nodename,
 Boolean
 __SC_checkResolverReachabilityInternal(SCDynamicStoreRef               *storeP,
                                       SCNetworkReachabilityFlags       *flags,
                                       Boolean                          *haveDNS,
                                       const char                       *nodename,
-                                      const char                       *servname,
                                       uint32_t                         *resolver_if_index,
                                       int                              *dns_config_index)
 {
                                       uint32_t                         *resolver_if_index,
                                       int                              *dns_config_index)
 {
@@ -3745,9 +3805,9 @@ __SC_checkResolverReachabilityInternal(SCDynamicStoreRef          *storeP,
        }
 
        ok = _SC_R_checkResolverReachability(&store_info, flags, haveDNS, nodename,
        }
 
        ok = _SC_R_checkResolverReachability(&store_info, flags, haveDNS, nodename,
-                                            servname, 0, resolver_if_index, dns_config_index, "");
+                                            0, resolver_if_index, dns_config_index, "");
 
 
-    done :
+       done :
 
        ReachabilityStoreInfo_free(&store_info);
        return ok;
 
        ReachabilityStoreInfo_free(&store_info);
        return ok;
@@ -3843,7 +3903,7 @@ _SC_checkResolverReachabilityByAddress(SCDynamicStoreRef          *storeP,
                        goto done;
        }
 
                        goto done;
        }
 
-       ok = _SC_R_checkResolverReachability(&store_info, flags, haveDNS, ptr_name, NULL, 0, NULL, NULL, "");
+       ok = _SC_R_checkResolverReachability(&store_info, flags, haveDNS, ptr_name, 0, NULL, NULL, "");
 
     done :
 
 
     done :
 
@@ -3852,153 +3912,198 @@ _SC_checkResolverReachabilityByAddress(SCDynamicStoreRef              *storeP,
 }
 
 
 }
 
 
-static Boolean
-startAsyncDNSQuery(SCNetworkReachabilityRef target)
-{
-       int                             error   = 0;
-       mach_port_t                     mp      = MACH_PORT_NULL;
-       Boolean                         ok;
-       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+#pragma mark -
+#pragma mark DNSServiceGetAddrInfo support
 
 
-       __dns_query_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd);
 
 
-#ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
-       if (targetPrivate->if_index == 0) {
-#endif /* HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL */
-               error = getaddrinfo_async_start(&mp,
-                                               targetPrivate->name,
-                                               targetPrivate->serv,
-                                               &targetPrivate->hints,
-                                               __SCNetworkReachabilityCallbackSetResolvedAddress,
-                                               (void *)target);
-#ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
-       } else {
-               mp = _getaddrinfo_interface_async_call(targetPrivate->name,
-                                                      targetPrivate->serv,
-                                                      &targetPrivate->hints,
-                                                      targetPrivate->if_name,
-                                                      __SCNetworkReachabilityCallbackSetResolvedAddress,
-                                                      (void *)target);
-               if (mp == MACH_PORT_NULL) {
-                       error = EAI_SYSTEM;
-               }
-       }
-#endif /* HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL */
-       if (error != 0) {
-               /* save the error associated with the attempt to resolve the name */
-               __SCNetworkReachabilityCallbackSetResolvedAddress(error, NULL, (void *)target);
-               return FALSE;
-       }
+#ifdef USE_DNSSERVICEGETADDRINFO
 
 
-       ok = enqueueAsyncDNSQuery(target, mp);
-       return ok;
-}
+/*
+ * DNS query handling
+ *
+ * Notes :
+ *
+ * 1. We have a "contract" with mDNSResponder that for EVERY network
+ *    or DNS configuration change that should warrant our [re-]starting
+ *    a query, mDNSResponder will acknowledge the latest DNS configuration.
+ *
+ * 2. IPMonitor also posts a notification AFTER every network or DNS
+ *    configuration change.
+ *
+ * 3. We use IPMonitor's "trailing edge" as a signal to restart any
+ *    by-name queries.
+ */
 
 
 
 
-#pragma mark -
+// Note: protected by _hn_changes_queue()
+static SCDynamicStoreCallBack  dns_callback            = NULL;
+static int                     dns_refresh_token;
+static Boolean                 dns_refresh_token_valid = FALSE;
+static SCDynamicStoreRef       dns_store               = NULL;
 
 
 
 
-static Boolean
-enqueueAsyncDNSRetry(SCNetworkReachabilityRef  target)
+/*
+ * dns_refresh_handler
+ *
+ * Called to notify/update all SCNetworkReachability by-name targets of
+ * a network/DNS change.  The change should [re-]start a DNS query to
+ * resolve the name.
+ * - caller must be running on the _hn_changes_queue()
+ */
+static void
+dns_refresh_handler()
 {
 {
-       int64_t                         delay;
-       dispatch_source_t               source;
-       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
-
-       MUTEX_ASSERT_HELD(&targetPrivate->lock);
+       CFArrayRef      changes;
+       CFStringRef     key;
 
 
-       source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
-                                       0,
-                                       0,
-                                       __SCNetworkReachability_concurrent_queue());
-       if (source == NULL) {
-               SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability retry dispatch_source_create() failed"));
-               return FALSE;
+       if (!dns_refresh_token_valid || (dns_callback == NULL)) {
+               return;
        }
 
        }
 
-       // retain the target ... and release it when the [timer] source is released
-       CFRetain(target);
-       dispatch_set_context(source, (void *)target);
-       dispatch_set_finalizer_f(source, (dispatch_function_t)CFRelease);
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetDNS);
+       changes = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
+       (*dns_callback)(dns_store, changes, NULL);
+       CFRelease(changes);
+       CFRelease(key);
 
 
-       dispatch_source_set_event_handler(source, ^(void) {
-               __SCNetworkReachabilityPerformInlineNoLock(target, TRUE);
-       });
+       return;
+}
 
 
-       // start a one-shot timer
-       delay = targetPrivate->dnsRetryCount * EAI_NONAME_RETRY_DELAY_USEC * NSEC_PER_USEC;
-       dispatch_source_set_timer(source,
-                                 dispatch_time(DISPATCH_TIME_NOW, delay),      // start
-                                 0,                                            // interval
-                                 10 * NSEC_PER_MSEC);                          // leeway
 
 
-       targetPrivate->dnsRetry = source;
-       dispatch_resume(source);
+/*
+ * dns_refresh_enable
+ *
+ * Called to monitor for network/DNS changes that should restart a DNS query.
+ * - caller must be running on the _hn_changes_queue()
+ */
+static Boolean
+dns_refresh_enable(dispatch_queue_t q, SCDynamicStoreRef store, SCDynamicStoreCallBack callback)
+{
+       uint32_t        status;
+
+       dns_callback = callback;
+       dns_store = CFRetain(store);
+
+       status = notify_register_dispatch(_SC_NOTIFY_NETWORK_CHANGE,
+                                         &dns_refresh_token,
+                                         q,
+                                         ^(int token){
+                                                 dns_refresh_handler();
+                                         });
+       if (status != NOTIFY_STATUS_OK) {
+               SCLog(TRUE, LOG_INFO, CFSTR("notify_register_dispatch() failed, status=%lu"), status);
+               return FALSE;
+       }
+
+       dns_refresh_token_valid = TRUE;
 
        return TRUE;
 }
 
 
 
        return TRUE;
 }
 
 
+/*
+ * dns_refresh_disable
+ *
+ * Called to stop monitoring for network/DNS changes
+ * - caller must be running on the _hn_changes_queue()
+ */
 static void
 static void
-dequeueAsyncDNSRetry(SCNetworkReachabilityRef  target)
+dns_refresh_disable()
 {
 {
-       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
-
-       MUTEX_ASSERT_HELD(&targetPrivate->lock);
-
-       if (targetPrivate->dnsRetry != NULL) {
-               dispatch_source_cancel(targetPrivate->dnsRetry);
-               dispatch_release(targetPrivate->dnsRetry);
-               targetPrivate->dnsRetry = NULL;
-       }
-
+       (void)notify_cancel(dns_refresh_token);
+       dns_refresh_token_valid = FALSE;
+       CFRelease(dns_store);
+       dns_store = NULL;
+       dns_callback = NULL;
        return;
 }
 
        return;
 }
 
+#endif // USE_DNSSERVICEGETADDRINFO
+
 
 #pragma mark -
 
 #pragma mark -
+#pragma mark [m]DNS Queries
+
+
+static void
+dequeueDNSQuery(SCNetworkReachabilityRef target);
 
 
 static dispatch_queue_t
 
 
 static dispatch_queue_t
-_llq_queue()
+_dns_queue()
 {
        static dispatch_once_t  once;
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
 {
        static dispatch_once_t  once;
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
-               q = dispatch_queue_create("SCNetworkReachabilty.longLivedQueries", NULL);
+               q = dispatch_queue_create("SCNetworkReachabilty.DNSService", NULL);
        });
 
        return q;
 }
 
 
        });
 
        return q;
 }
 
 
+#ifdef USE_DNSSERVICEGETADDRINFO
+
+/*
+ * _dns_complete
+ */
+static __inline__ Boolean
+_dns_complete(SCNetworkReachabilityRef target)
+{
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       if ((targetPrivate->dnsHaveV4 && targetPrivate->dnsHaveV6) ||
+           targetPrivate->dnsHaveError ||
+           targetPrivate->dnsHaveTimeout) {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+
 /*
 /*
- * _llq_notify
+ * _dns_notify
  *
  * Called to push out a target's DNS changes
  *
  * Called to push out a target's DNS changes
- * - caller must be running on the _llq_queue()
+ * - caller must be running on the _dns_queue()
  */
 static void
  */
 static void
-_llq_notify(const void *value, void *context)
+_dns_notify(const void *value, void *context)
 {
        SCNetworkReachabilityRef        target          = (SCNetworkReachabilityRef)value;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_LOCK(&targetPrivate->lock);
 
 {
        SCNetworkReachabilityRef        target          = (SCNetworkReachabilityRef)value;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_LOCK(&targetPrivate->lock);
 
-       __dns_query_end(target,
-                       (targetPrivate->resolvedAddressError == NETDB_SUCCESS), // if successful query
-                       dns_query_llq,                                          // long-lived-query
-                       &targetPrivate->dnsQueryStart,                          // start time
-                       &targetPrivate->dnsQueryEnd);                           // end time
+       if (_dns_complete(target)) {
+               __mark_operation_end(target,
+                                    (targetPrivate->resolvedError == NETDB_SUCCESS),   // if successful query
+                                    dns_query_mdns,                                    // [m]DNS query
+                                    &targetPrivate->dnsQueryStart,                     // start time
+                                    &targetPrivate->dnsQueryEnd);                      // end time
 
 
-       if (targetPrivate->scheduled) {
-               __SCNetworkReachabilityPerform(target);
-       }
+               // update target info
+               if (targetPrivate->resolvedAddresses != NULL) {
+                       CFRelease(targetPrivate->resolvedAddresses);
+               }
+               targetPrivate->resolvedAddresses = targetPrivate->dnsAddresses;
+               targetPrivate->dnsAddresses      = NULL;
 
 
-       // last long-lived-query end time is new start time
-       targetPrivate->dnsQueryStart = targetPrivate->dnsQueryEnd;
+               targetPrivate->resolvedError     = targetPrivate->dnsError;
+               targetPrivate->dnsError          = NETDB_SUCCESS;
+
+               dequeueDNSQuery(target);
+
+               targetPrivate->needResolve = FALSE;
+
+               if (targetPrivate->scheduled) {
+                       __SCNetworkReachabilityPerformLocked(target);
+               }
+       }
 
        MUTEX_UNLOCK(&targetPrivate->lock);
        return;
 
        MUTEX_UNLOCK(&targetPrivate->lock);
        return;
@@ -4006,13 +4111,44 @@ _llq_notify(const void *value, void *context)
 
 
 /*
 
 
 /*
- * _llq_callback
+ * _dns_mark
+ */
+static __inline__ void
+_dns_mark(SCNetworkReachabilityRef target, Boolean valid, const struct sockaddr *sa)
+{
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       if (!valid) {
+               targetPrivate->dnsHaveError = TRUE;
+               return;
+       }
+
+       if (sa == NULL) {
+               targetPrivate->dnsHaveTimeout = TRUE;
+               return;
+       }
+
+       switch (sa->sa_family) {
+               case AF_INET :
+                       targetPrivate->dnsHaveV4 = TRUE;
+                       break;
+               case AF_INET6 :
+                       targetPrivate->dnsHaveV6 = TRUE;
+                       break;
+       }
+
+       return;
+}
+
+
+/*
+ * _dns_callback
  *
  *
- * Called to process mDNSResponder long-lived-query updates
- * - caller must be running on the _llq_queue()
+ * Called to process [m]DNS query updates
+ * - caller must be running on the _dns_queue()
  */
 static void
  */
 static void
-_llq_callback(DNSServiceRef            sdRef,
+_dns_callback(DNSServiceRef            sdRef,
              DNSServiceFlags           flags,
              uint32_t                  interfaceIndex,
              DNSServiceErrorType       errorCode,
              DNSServiceFlags           flags,
              uint32_t                  interfaceIndex,
              DNSServiceErrorType       errorCode,
@@ -4026,81 +4162,105 @@ _llq_callback(DNSServiceRef            sdRef,
 
        MUTEX_LOCK(&targetPrivate->lock);
 
 
        MUTEX_LOCK(&targetPrivate->lock);
 
-       if (targetPrivate->llqTimer != NULL) {
-               dispatch_source_cancel(targetPrivate->llqTimer);
-               dispatch_release(targetPrivate->llqTimer);
-               targetPrivate->llqTimer = NULL;
+       if (sdRef != targetPrivate->dnsTarget) {
+               // if this DNSServiceRef is no longer associated with
+               // this target
+               MUTEX_UNLOCK(&targetPrivate->lock);
+               return;
        }
 
        switch (errorCode) {
                case kDNSServiceErr_NoError :
                        if (address != NULL) {
                                CFMutableArrayRef       addresses;
        }
 
        switch (errorCode) {
                case kDNSServiceErr_NoError :
                        if (address != NULL) {
                                CFMutableArrayRef       addresses;
-                               CFDataRef               llqAddress;
+                               CFDataRef               dnsAddress;
+                               CFIndex                 i;
+
+                               _dns_mark(target, TRUE, address);
 
 
-                               if (targetPrivate->resolvedAddress != NULL) {
-                                       if (isA_CFArray(targetPrivate->resolvedAddress)) {
-                                               addresses = CFArrayCreateMutableCopy(NULL, 0, targetPrivate->resolvedAddress);
+                               if (targetPrivate->dnsAddresses != NULL) {
+                                       if (isA_CFArray(targetPrivate->dnsAddresses)) {
+                                               addresses = CFArrayCreateMutableCopy(NULL, 0, targetPrivate->dnsAddresses);
                                        } else {
                                                addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                                        }
 
                                        } else {
                                                addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                                        }
 
-                                       CFRelease(targetPrivate->resolvedAddress);
-                                       targetPrivate->resolvedAddress = NULL;
+                                       CFRelease(targetPrivate->dnsAddresses);
+                                       targetPrivate->dnsAddresses = NULL;
                                } else {
                                        addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                                }
 
                                } else {
                                        addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
                                }
 
-                               llqAddress = CFDataCreate(NULL, (void *)address, address->sa_len);
+                               dnsAddress = CFDataCreate(NULL, (void *)address, address->sa_len);
+                               i = CFArrayGetFirstIndexOfValue(addresses,
+                                                               CFRangeMake(0, CFArrayGetCount(addresses)),
+                                                               dnsAddress);
                                if (flags & kDNSServiceFlagsAdd) {
                                        // add address
                                if (flags & kDNSServiceFlagsAdd) {
                                        // add address
-                                       CFArrayAppendValue(addresses, llqAddress);
+                                       if (i == kCFNotFound) {
+                                               CFArrayAppendValue(addresses, dnsAddress);
+                                       }
+#ifdef HANDLE_RMV_REQUESTS
                                } else {
                                } else {
-                                       CFIndex i;
-
                                        // remove address
                                        // remove address
-                                       i = CFArrayGetFirstIndexOfValue(addresses,
-                                                                       CFRangeMake(0, CFArrayGetCount(addresses)),
-                                                                       llqAddress);
                                        if (i != kCFNotFound) {
                                                CFArrayRemoveValueAtIndex(addresses, i);
                                        }
                                        if (i != kCFNotFound) {
                                                CFArrayRemoveValueAtIndex(addresses, i);
                                        }
+#endif // HANDLE_RMV_REQUESTS
                                }
                                }
-                               CFRelease(llqAddress);
+                               CFRelease(dnsAddress);
 
                                if (CFArrayGetCount(addresses) > 0) {
 
                                if (CFArrayGetCount(addresses) > 0) {
-                                       targetPrivate->resolvedAddress      = addresses;
-                                       targetPrivate->resolvedAddressError = NETDB_SUCCESS;
+                                       targetPrivate->dnsAddresses = addresses;
+                                       targetPrivate->dnsError     = NETDB_SUCCESS;
                                } else {
                                        // if host not found
                                } else {
                                        // if host not found
-                                       targetPrivate->resolvedAddress      = CFRetain(kCFNull);
-                                       targetPrivate->resolvedAddressError = EAI_NONAME;
+                                       targetPrivate->dnsAddresses = CFRetain(kCFNull);
+                                       targetPrivate->dnsError     = EAI_NONAME;
                                        CFRelease(addresses);
                                }
 
                                        CFRelease(addresses);
                                }
 
-                               targetPrivate->needResolve = FALSE;
                        }
                        break;
                        }
                        break;
-               case kDNSServiceErr_NoSuchRecord :
+               case kDNSServiceErr_BadParam :
+                       _dns_mark(target, FALSE, NULL);
+
+                       if (targetPrivate->dnsAddresses != NULL) {
+                               CFRelease(targetPrivate->dnsAddresses);
+                       }
+                       targetPrivate->dnsAddresses = CFRetain(kCFNull);
+                       targetPrivate->dnsError     = EAI_NONAME;
+                       break;
+               case kDNSServiceErr_NoSuchRecord :
                        if (address != NULL) {
                                // no IPv4/IPv6 address for name (NXDOMAIN)
                        if (address != NULL) {
                                // no IPv4/IPv6 address for name (NXDOMAIN)
-                               if (targetPrivate->resolvedAddress == NULL) {
-                                       targetPrivate->resolvedAddress      = CFRetain(kCFNull);
-                                       targetPrivate->resolvedAddressError = EAI_NONAME;
+
+                               _dns_mark(target, TRUE, address);
+
+                               if (targetPrivate->dnsAddresses == NULL) {
+                                       targetPrivate->dnsAddresses = CFRetain(kCFNull);
+                                       targetPrivate->dnsError     = EAI_NONAME;
                                }
                                }
-                               targetPrivate->needResolve = FALSE;
                        }
                        break;
                case kDNSServiceErr_Timeout :
                        }
                        break;
                case kDNSServiceErr_Timeout :
-                       if (targetPrivate->resolvedAddress == NULL) {
-                               targetPrivate->resolvedAddress      = CFRetain(kCFNull);
-                               targetPrivate->resolvedAddressError = EAI_NONAME;
+                       _dns_mark(target, TRUE, NULL);
+
+                       if (targetPrivate->dnsAddresses == NULL) {
+                               targetPrivate->dnsAddresses = CFRetain(kCFNull);
+                               targetPrivate->dnsError     = EAI_NONAME;
                        }
                        }
-                       targetPrivate->needResolve = FALSE;
                        break;
                        break;
+               case kDNSServiceErr_ServiceNotRunning :
+                       // mDNSResponder crashed, restart query
+                       DNSServiceRefDeallocate(dnsMain);
+                       dnsMain = NULL;
+                       dnsCount = 0;
                default :
                default :
+                       _dns_mark(target, FALSE, NULL);
+
                        SCLog(TRUE, LOG_ERR,
                        SCLog(TRUE, LOG_ERR,
-                             CFSTR("%sSCNetworkReachability _llq_callback w/error=%d"),
+                             CFSTR("%sSCNetworkReachability _dns_callback w/error=%d"),
                              targetPrivate->log_prefix,
                              errorCode);
                        break;
                              targetPrivate->log_prefix,
                              errorCode);
                        break;
@@ -4108,20 +4268,34 @@ _llq_callback(DNSServiceRef             sdRef,
 
        MUTEX_UNLOCK(&targetPrivate->lock);
 
 
        MUTEX_UNLOCK(&targetPrivate->lock);
 
+       if (errorCode == kDNSServiceErr_ServiceNotRunning) {
+               dispatch_async(_hn_changes_queue(), ^{
+                       dns_refresh_handler();
+               });
+
+               // and flush the dnsUpdated queue as any DNS results we may have
+               // accumulated are no longer valid.
+               if (dnsUpdated != NULL) {
+                       CFRelease(dnsUpdated);
+                       dnsUpdated = NULL;
+               }
+               return;
+       }
+
        // the "more coming" flag applies to DNSService callouts for any/all
        // hosts that are being watched so we need to keep track of the targets
        // we have updated.  When we [finally] have the last callout then we
        // push our notifications for all of the updated targets.
 
        // the "more coming" flag applies to DNSService callouts for any/all
        // hosts that are being watched so we need to keep track of the targets
        // we have updated.  When we [finally] have the last callout then we
        // push our notifications for all of the updated targets.
 
-       if (llqUpdated == NULL) {
-               llqUpdated = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+       if (dnsUpdated == NULL) {
+               dnsUpdated = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
        }
        }
-       CFSetAddValue(llqUpdated, target);
+       CFSetAddValue(dnsUpdated, target);
 
        if (!(flags & kDNSServiceFlagsMoreComing)) {
 
        if (!(flags & kDNSServiceFlagsMoreComing)) {
-               CFSetApplyFunction(llqUpdated, _llq_notify, NULL);
-               CFRelease(llqUpdated);
-               llqUpdated = NULL;
+               CFSetApplyFunction(dnsUpdated, _dns_notify, NULL);
+               CFRelease(dnsUpdated);
+               dnsUpdated = NULL;
        }
 
        return;
        }
 
        return;
@@ -4129,191 +4303,271 @@ _llq_callback(DNSServiceRef           sdRef,
 
 
 static Boolean
 
 
 static Boolean
-enqueueLongLivedQuery(SCNetworkReachabilityRef target)
+enqueueDNSQuery(SCNetworkReachabilityRef target)
 {
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
 {
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
-       if (targetPrivate->serv != NULL) {
-               // if "serv" provided, can't use DNSServiceGetAddrInfo
-               return FALSE;
-       }
-
-       if (memcmp(&targetPrivate->hints, &HINTS_DEFAULT, sizeof(targetPrivate->hints)) != 0) {
-               // non-default "hints" provided, can't use DNSServiceGetAddrInfo
-               return FALSE;
-       }
-
-       // mark the long lived query active
-       targetPrivate->llqActive = TRUE;
+       // clear DNS flags, mark the [m]DNS query active
+       targetPrivate->dnsFlags = 0;
+       targetPrivate->dnsActive = TRUE;
 
        // track the DNS resolution time
 
        // track the DNS resolution time
-       __dns_query_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd);
+       __mark_operation_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd);
 
        CFRetain(target);
 
        CFRetain(target);
-       dispatch_async(_llq_queue(), ^{
-               DNSServiceErrorType     err;
-               dispatch_source_t       source;
+       dispatch_async(_dns_queue(), ^{
+               DNSServiceErrorType     err     = kDNSServiceErr_NoError;
+               DNSServiceRef           sdRef   = NULL;
 
 
-               MUTEX_LOCK(&targetPrivate->lock);
-
-               if (targetPrivate->llqTarget != NULL) {
+               if (targetPrivate->dnsTarget != NULL) {
                        // if already running
                        // if already running
-                       MUTEX_UNLOCK(&targetPrivate->lock);
                        CFRelease(target);
                        return;
                }
 
                // if needed, start interacting with mDNSResponder
                        CFRelease(target);
                        return;
                }
 
                // if needed, start interacting with mDNSResponder
+               // Note: we must not hold a [target] lock while interacting
 
 
-               if (llqMain == NULL) {
-                       err = DNSServiceCreateConnection(&llqMain);
+               if (dnsMain == NULL) {
+                       err = DNSServiceCreateConnection(&dnsMain);
                        if (err != kDNSServiceErr_NoError) {
                                SCLog(TRUE, LOG_ERR,
                        if (err != kDNSServiceErr_NoError) {
                                SCLog(TRUE, LOG_ERR,
-                                     CFSTR("DNSServiceCreateConnection(&llqMain) failed, error = %d"),
+                                     CFSTR("DNSServiceCreateConnection(&dnsMain) failed, error = %d"),
                                      err);
                                      err);
-
-                               targetPrivate->llqActive = FALSE;
-
-                               MUTEX_UNLOCK(&targetPrivate->lock);
-                               CFRelease(target);
-                               return;
+                               goto done;
                        }
 
                        }
 
-                       err = DNSServiceSetDispatchQueue(llqMain, _llq_queue());
+                       err = DNSServiceSetDispatchQueue(dnsMain, _dns_queue());
                        if (err != kDNSServiceErr_NoError) {
                                SCLog(TRUE, LOG_ERR,
                                      CFSTR("DNSServiceSetDispatchQueue() failed, error = %d"),
                                      err);
                        if (err != kDNSServiceErr_NoError) {
                                SCLog(TRUE, LOG_ERR,
                                      CFSTR("DNSServiceSetDispatchQueue() failed, error = %d"),
                                      err);
-                               DNSServiceRefDeallocate(llqMain);
-                               llqMain = NULL;
-
-                               targetPrivate->llqActive = FALSE;
-
-                               MUTEX_UNLOCK(&targetPrivate->lock);
-                               CFRelease(target);
-                               return;
+                               DNSServiceRefDeallocate(dnsMain);
+                               dnsMain = NULL;
+                               goto done;
                        }
                }
 
                        }
                }
 
-               // start a long-lived-query for this target
+               // start an [m]DNS query for this target
 
 
-               targetPrivate->llqTarget = llqMain;
-               err = DNSServiceGetAddrInfo(&targetPrivate->llqTarget,          // sdRef
+               sdRef = dnsMain;
+               err = DNSServiceGetAddrInfo(&sdRef,                             // sdRef
                                            kDNSServiceFlagsReturnIntermediates // flags
                                            kDNSServiceFlagsReturnIntermediates // flags
-                                           | kDNSServiceFlagsShareConnection,
+                                           | kDNSServiceFlagsShareConnection
+                                           | kDNSServiceFlagsTimeout,
                                            targetPrivate->if_index,            // interfaceIndex
                                            0,                                  // protocol
                                            targetPrivate->name,                // hostname
                                            targetPrivate->if_index,            // interfaceIndex
                                            0,                                  // protocol
                                            targetPrivate->name,                // hostname
-                                           _llq_callback,                      // callback
+                                           _dns_callback,                      // callback
                                            (void *)target);                    // context
                                            (void *)target);                    // context
-               if (err != kDNSServiceErr_NoError) {
-                       SCLog(TRUE, LOG_ERR,
-                             CFSTR("DNSServiceGetAddrInfo() failed, error = %d"),
-                             err);
-                       targetPrivate->llqTarget = NULL;
-                       if (llqCount == 0) {
-                               // if this was the first request
-                               DNSServiceRefDeallocate(llqMain);
-                               llqMain = NULL;
+               if (err == kDNSServiceErr_NoError) {
+                       dnsCount++;
+               } else {
+                       sdRef = NULL;
+                       if ((dnsCount == 0) || (err == kDNSServiceErr_ServiceNotRunning)) {
+                               // if this was the first request or the service is dead
+                               DNSServiceRefDeallocate(dnsMain);
+                               dnsMain = NULL;
+                               dnsCount = 0;
                        }
                        }
-
-                       targetPrivate->llqActive = FALSE;
-
-                       MUTEX_UNLOCK(&targetPrivate->lock);
-                       CFRelease(target);
-                       return;
                }
 
                }
 
-               llqCount++;
-
-               // if case we don't get any callbacks from our long-lived-query (this
-               // could happen if the DNS servers do not respond), we start a timer
-               // to ensure that we fire off at least one reachability callback.
-
-               source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
-                                               0,
-                                               0,
-                                               _llq_queue());
-               if (source != NULL) {
-                       // retain the target ... and release it when the [timer] source is released
-                       CFRetain(target);
-                       dispatch_set_context(source, (void *)target);
-                       dispatch_set_finalizer_f(source, (dispatch_function_t)CFRelease);
-
-                       dispatch_source_set_event_handler(source, ^(void) {
-                               _llq_callback(NULL,                     // sdRef
-                                             0,                        // flags
-                                             0,                        // interfaceIndex
-                                             kDNSServiceErr_Timeout,   // errorCode
-                                             NULL,                     // hostname
-                                             NULL,                     // address
-                                             0,                        // ttl
-                                             (void *)target);          // context
-                       });
+               switch (err) {
+                       case kDNSServiceErr_NoError :
+                               break;
+                       case kDNSServiceErr_BadParam :
+                               CFRetain(target);
+                               dispatch_async(_dns_queue(), ^{
+                                       _dns_callback(NULL,                     // sdRef
+                                                     0,                        // flags
+                                                     0,                        // interfaceIndex
+                                                     kDNSServiceErr_BadParam,  // errorCode
+                                                     NULL,                     // hostname
+                                                     NULL,                     // address
+                                                     0,                        // ttl
+                                                     (void *)target);          // context
+                                       CFRelease(target);
+                               });
+                               break;
+                       default :
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("DNSServiceGetAddrInfo() failed, error = %d"),
+                                     err);
+                               break;
+               }
 
 
-                       dispatch_source_set_timer(source,
-                                                 dispatch_time(DISPATCH_TIME_NOW,
-                                                               LLQ_TIMEOUT_NSEC),      // start
-                                                 0,                                    // interval
-                                                 10 * NSEC_PER_MSEC);                  // leeway
+           done :
 
 
-                       targetPrivate->llqTimer = source;
-                       dispatch_resume(source);
+               MUTEX_LOCK(&targetPrivate->lock);
+               if (err == kDNSServiceErr_NoError) {
+                       // query active, save DNSServiceRef, retain target reference
+                       targetPrivate->dnsMain = dnsMain;
+                       targetPrivate->dnsTarget = sdRef;
+                       MUTEX_UNLOCK(&targetPrivate->lock);
                } else {
                } else {
-                       SCLog(TRUE, LOG_ERR,
-                             CFSTR("SCNetworkReachability llq dispatch_source_create(no-reply) failed"));
+                       // query no longer active, release target reference
+                       targetPrivate->dnsActive = FALSE;
+                       MUTEX_UNLOCK(&targetPrivate->lock);
+                       CFRelease(target);
+                       if (err == kDNSServiceErr_ServiceNotRunning) {
+                               dispatch_async(_hn_changes_queue(), ^{
+                                       dns_refresh_handler();
+                               });
+                       }
                }
 
                }
 
-               MUTEX_UNLOCK(&targetPrivate->lock);
                return;
        });
 
        return TRUE;
 }
 
                return;
        });
 
        return TRUE;
 }
 
+#endif // USE_DNSSERVICEGETADDRINFO
+
 
 static void
 
 static void
-dequeueLongLivedQuery(SCNetworkReachabilityRef target)
+dequeueDNSQuery(SCNetworkReachabilityRef target)
 {
        DNSServiceRef                   sdRef;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
 {
        DNSServiceRef                   sdRef;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
-       // terminate the [target] llq timer
-       if (targetPrivate->llqTimer != NULL) {
-               dispatch_source_cancel(targetPrivate->llqTimer);
-               dispatch_release(targetPrivate->llqTimer);
-               targetPrivate->llqTimer = NULL;
-       }
-
-       // terminate the [target] long lived query
-       sdRef = targetPrivate->llqTarget;
-       targetPrivate->llqTarget = NULL;
+       // terminate the [target] [m]DNS query
+       sdRef = targetPrivate->dnsTarget;
+       targetPrivate->dnsTarget = NULL;
 
 
-       // mark the long lived query NOT active
-       targetPrivate->llqActive = FALSE;
+       // mark the [m]DNS query NOT active
+       targetPrivate->dnsActive = FALSE;
 
 
-       if (sdRef != NULL) {
-               dispatch_async(_llq_queue(), ^{
+       // don't do anything if the sdRef is not valid (e.g., "dnsMain" changed)
+       if (sdRef != NULL
+           && targetPrivate->dnsMain == dnsMain) {
+               dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC),
+                              _dns_queue(),
+                              ^{
                        DNSServiceRefDeallocate(sdRef);
                        CFRelease(target);
 
                        DNSServiceRefDeallocate(sdRef);
                        CFRelease(target);
 
-                       llqCount--;
-                       if (llqCount == 0) {
+                       dnsCount--;
+                       if (dnsCount == 0) {
                                // if no more queries active
                                // if no more queries active
-                               DNSServiceRefDeallocate(llqMain);
-                               llqMain = NULL;
+                               DNSServiceRefDeallocate(dnsMain);
+                               dnsMain = NULL;
                        }
                });
        }
 
                        }
                });
        }
 
+       if (targetPrivate->dnsAddresses != NULL) {
+               CFRelease(targetPrivate->dnsAddresses);
+               targetPrivate->dnsAddresses = NULL;
+       }
+       targetPrivate->dnsError = NETDB_SUCCESS;
+
+       return;
+}
+
+
+#pragma mark -
+#pragma mark Network Information support
+
+
+// Note: protected by _hn_changes_queue()
+static SCDynamicStoreCallBack  network_changed_callback        = NULL;
+static int                     network_changed_token;
+static Boolean                 network_changed_token_valid     = FALSE;
+static SCDynamicStoreRef       network_change_store            = NULL;
+
+
+/*
+ * nwi_refresh_handler
+ *
+ * Called to notify/update network changed events
+ * - caller must be running on the _hn_changes_queue()
+ */
+static void
+nwi_refresh_handler()
+{
+       CFArrayRef      changes;
+       CFStringRef     key;
+
+       if (!network_changed_token_valid || (network_changed_callback == NULL)) {
+               return;
+       }
+
+       // Fake a network change.
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetIPv4);
+
+       changes = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
+       (*network_changed_callback)(network_change_store, changes, NULL);
+       CFRelease(changes);
+       CFRelease(key);
+
        return;
 }
 
 
        return;
 }
 
 
+/*
+ * nwi_refresh_enable
+ *
+ * Called to monitor for network changes.
+ * - caller must be running on the _hn_changes_queue()
+ */
+static Boolean
+nwi_refresh_enable(dispatch_queue_t q, SCDynamicStoreRef store, SCDynamicStoreCallBack callback)
+{
+       uint32_t        status;
+
+       network_changed_callback = callback;
+       network_change_store = CFRetain(store);
+
+       status = notify_register_dispatch(_SC_NOTIFY_NETWORK_CHANGE_NWI,        // trailing nwi_state_get_notify_key()
+                                         &network_changed_token,
+                                         q,
+                                         ^(int token){
+                                                 nwi_refresh_handler();
+                                         });
+       if (status != NOTIFY_STATUS_OK) {
+               SCLog(TRUE, LOG_INFO, CFSTR("notify_register_dispatch() failed for network changes, status=%lu"), status);
+               return FALSE;
+       }
+
+       network_changed_token_valid = TRUE;
+
+       return TRUE;
+}
+
+
+/*
+ * nwi_refresh_disable
+ *
+ * Called to stop monitoring for network changes
+ * - caller must be running on the _hn_changes_queue()
+ */
+static void
+nwi_refresh_disable()
+{
+       if (network_changed_token_valid) {
+               (void)notify_cancel(network_changed_token);
+               network_changed_token_valid = FALSE;
+       }
+       if (network_change_store != NULL) {
+               CFRelease(network_change_store);
+               network_change_store = NULL;
+               network_changed_callback = NULL;
+       }
+       return;
+}
+
+
+
+
+
+
 #pragma mark -
 #pragma mark OnDemand
 
 #pragma mark -
 #pragma mark OnDemand
 
@@ -4363,9 +4617,16 @@ __SCNetworkReachabilityOnDemandCheckCallback(SCNetworkReachabilityRef    onDemandSe
                return;
        }
 
                return;
        }
 
-       SCLog(_sc_debug, LOG_INFO, CFSTR("%sOnDemand \"server\" status changed"),
-             targetPrivate->log_prefix);
-       __SCNetworkReachabilityPerform(target);
+       SCLog(_sc_debug, LOG_INFO, CFSTR("%sOnDemand \"server\" status changed (now 0x%08x)"),
+             targetPrivate->log_prefix,
+             onDemandFlags);
+
+       if (targetPrivate->type == reachabilityTypeName) {
+               // make sure that we resolve the name again
+               targetPrivate->needResolve = TRUE;
+       }
+
+       __SCNetworkReachabilityPerformLocked(target);
 
        MUTEX_UNLOCK(&targetPrivate->lock);
 
 
        MUTEX_UNLOCK(&targetPrivate->lock);
 
@@ -4379,21 +4640,20 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef   store_info,
                                     Boolean                    onDemandRetry,
                                     SCNetworkReachabilityFlags *flags)
 {
                                     Boolean                    onDemandRetry,
                                     SCNetworkReachabilityFlags *flags)
 {
-       Boolean                         ok;
-       Boolean                         onDemand                = FALSE;
+       SCNetworkConnectionRef          connection              = NULL;
+       SCNetworkConnectionType         connectionType          = kSCNetworkConnectionTypeUnknown;
+       Boolean                         isAppLayerVPN           = FALSE;
+       Boolean                         isOnDemandService       = FALSE;
+       Boolean                         ok                      = FALSE;
        CFStringRef                     onDemandRemoteAddress   = NULL;
        CFStringRef                     onDemandServiceID       = NULL;
        CFStringRef                     onDemandRemoteAddress   = NULL;
        CFStringRef                     onDemandServiceID       = NULL;
-       SCNetworkConnectionStatus       onDemandStatus;
-       SCDynamicStoreRef               store;
+       SCNetworkConnectionStatus       onDemandStatus          = kSCNetworkConnectionInvalid;
+       CFMutableDictionaryRef          selectOptions           = NULL;
+       Boolean                         success                 = FALSE;
        SCNetworkReachabilityPrivateRef targetPrivate           = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
        SCNetworkReachabilityPrivateRef targetPrivate           = (SCNetworkReachabilityPrivateRef)target;
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
-//     SCLog(_sc_debug, LOG_INFO,
-//           CFSTR("%s__SCNetworkReachabilityOnDemandCheck %s"),
-//           targetPrivate->log_prefix,
-//           onDemandRetry ? "after" : "before");
-
        if (targetPrivate->onDemandName == NULL) {
                targetPrivate->onDemandName = CFStringCreateWithCString(NULL, targetPrivate->name, kCFStringEncodingUTF8);
        }
        if (targetPrivate->onDemandName == NULL) {
                targetPrivate->onDemandName = CFStringCreateWithCString(NULL, targetPrivate->name, kCFStringEncodingUTF8);
        }
@@ -4401,17 +4661,70 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef   store_info,
        /*
         * check if an OnDemand VPN configuration matches the name.
         */
        /*
         * check if an OnDemand VPN configuration matches the name.
         */
-       store = store_info->store;
-       ok = __SCNetworkConnectionCopyOnDemandInfoWithName(&store,
-                                                          targetPrivate->onDemandName,
-                                                          onDemandRetry,
-                                                          &onDemandServiceID,
-                                                          &onDemandStatus,
-                                                          &onDemandRemoteAddress);
-       if ((store_info->store == NULL) && (store != NULL)) {
-               // if an SCDynamicStore session was added, keep it
-               store_info->store = store;
+
+       connection = SCNetworkConnectionCreate(kCFAllocatorDefault, NULL, NULL);
+       if (connection == NULL) {
+               goto done;
+       }
+
+       /* set select options */
+       selectOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       if (selectOptions == NULL) {
+               goto done;
+       }
+
+       CFDictionaryAddValue(selectOptions, kSCNetworkConnectionSelectionOptionOnDemandHostName, targetPrivate->onDemandName);
+       CFDictionaryAddValue(selectOptions, kSCNetworkConnectionSelectionOptionOnDemandRetry, onDemandRetry ? kCFBooleanTrue : kCFBooleanFalse);
+       CFDictionaryAddValue(selectOptions, kSCNetworkConnectionSelectionOptionNoUserPrefs, kCFBooleanTrue);
+
+       /* select service. May be On Demand or App Layer VPN */
+       if (!SCNetworkConnectionSelectServiceWithOptions(connection, selectOptions)) {
+               goto done;
+       }
+
+       /* get reachability flags (of VPN server) */
+       (void) SCNetworkConnectionGetReachabilityInfo(connection, flags, NULL);
+
+       connectionType = SCNetworkConnectionGetType(connection);
+       if (connectionType == kSCNetworkConnectionTypeAppLayerVPN) {
+               isAppLayerVPN = TRUE;
+       }
+
+       /* get on-demand info */
+       onDemandServiceID = SCNetworkConnectionCopyServiceID(connection);
+       if (SCNetworkConnectionCopyOnDemandInfo(connection, &onDemandRemoteAddress, &onDemandStatus)) {
+               isOnDemandService = TRUE;
+               ok = TRUE;
+       }
+
+       /* handle non-OnDemand App-Layer VPN */
+       if (isAppLayerVPN && !isOnDemandService) {
+               SCLog(_sc_debug, LOG_INFO, CFSTR("%s  status  * = 0x%08x (App-Layer VPN)"),
+                     targetPrivate->log_prefix,
+                     *flags);
+               if (*flags & kSCNetworkReachabilityFlagsReachable) {
+                       // if VPN "server" is reachable
+
+                       if (!(*flags & kSCNetworkReachabilityFlagsTransientConnection)) {
+                               // start w/clean flags if not already layered on a transient network
+                               *flags = kSCNetworkReachabilityFlagsReachable;
+                       }
+
+                       *flags |= kSCNetworkReachabilityFlagsTransientConnection;
+                       if (onDemandStatus != kSCNetworkConnectionConnected) {
+                               *flags |= kSCNetworkReachabilityFlagsConnectionRequired;
+                       }
+
+                       SCLog(_sc_debug, LOG_INFO, CFSTR("%s  status    = isReachable%s"),
+                             (onDemandStatus != kSCNetworkConnectionConnected)
+                                       ? " (after App Layer connect)" : "",
+                             targetPrivate->log_prefix);
+               }
+
+               success = TRUE;
+               goto done;
        }
        }
+
        if (!_SC_CFEqual(targetPrivate->onDemandRemoteAddress, onDemandRemoteAddress) ||
            !_SC_CFEqual(targetPrivate->onDemandServiceID, onDemandServiceID)) {
                if (targetPrivate->onDemandRemoteAddress != NULL) {
        if (!_SC_CFEqual(targetPrivate->onDemandRemoteAddress, onDemandRemoteAddress) ||
            !_SC_CFEqual(targetPrivate->onDemandServiceID, onDemandServiceID)) {
                if (targetPrivate->onDemandRemoteAddress != NULL) {
@@ -4420,6 +4733,7 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef     store_info,
                }
 
                if (targetPrivate->onDemandServer != NULL) {
                }
 
                if (targetPrivate->onDemandServer != NULL) {
+                       SCNetworkReachabilitySetCallback(targetPrivate->onDemandServer, NULL, NULL);
                        if (targetPrivate->dispatchQueue != NULL) {
                                // unschedule
                                __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE);
                        if (targetPrivate->dispatchQueue != NULL) {
                                // unschedule
                                __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE);
@@ -4446,6 +4760,7 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef     store_info,
                        targetPrivate->onDemandServiceID = NULL;
                }
        }
                        targetPrivate->onDemandServiceID = NULL;
                }
        }
+
        if (ok) {
                if (onDemandStatus != kSCNetworkConnectionConnected) {
                        /*
        if (ok) {
                if (onDemandStatus != kSCNetworkConnectionConnected) {
                        /*
@@ -4453,6 +4768,7 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef     store_info,
                         * bring the VPN up.  Combine our flags with those of the VPN server.
                         */
                        if (targetPrivate->onDemandServer == NULL) {
                         * bring the VPN up.  Combine our flags with those of the VPN server.
                         */
                        if (targetPrivate->onDemandServer == NULL) {
+                               SCNetworkReachabilityPrivateRef demandPrivate;
                                CFMutableDictionaryRef          options;
 
                                options = CFDictionaryCreateMutable(NULL,
                                CFMutableDictionaryRef          options;
 
                                options = CFDictionaryCreateMutable(NULL,
@@ -4462,11 +4778,17 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef   store_info,
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, onDemandRemoteAddress);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionConnectionOnDemandBypass, kCFBooleanTrue);
 #ifdef HAVE_REACHABILITY_SERVER
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, onDemandRemoteAddress);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionConnectionOnDemandBypass, kCFBooleanTrue);
 #ifdef HAVE_REACHABILITY_SERVER
-                               CFDictionarySetValue(options, kSCNetworkReachabilityOptionServerBypass, kCFBooleanTrue);
+                               if (targetPrivate->serverBypass) {
+                                       CFDictionarySetValue(options, kSCNetworkReachabilityOptionServerBypass, kCFBooleanTrue);
+                               }
 #endif // HAVE_REACHABILITY_SERVER
                                targetPrivate->onDemandServer = SCNetworkReachabilityCreateWithOptions(NULL, options);
                                CFRelease(options);
 
 #endif // HAVE_REACHABILITY_SERVER
                                targetPrivate->onDemandServer = SCNetworkReachabilityCreateWithOptions(NULL, options);
                                CFRelease(options);
 
+                               // indent OnDemand target
+                               demandPrivate = (SCNetworkReachabilityPrivateRef)targetPrivate->onDemandServer;
+                               strlcat(demandPrivate->log_prefix, ".... ", sizeof(demandPrivate->log_prefix));
+
                                if (targetPrivate->scheduled) {
                                        SCNetworkReachabilityContext    context = { 0, NULL, CFRetain, CFRelease, CFCopyDescription };
 
                                if (targetPrivate->scheduled) {
                                        SCNetworkReachabilityContext    context = { 0, NULL, CFRetain, CFRelease, CFCopyDescription };
 
@@ -4493,20 +4815,28 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef   store_info,
                                }
                        }
 
                                }
                        }
 
-                       ok = SCNetworkReachabilityGetFlags(targetPrivate->onDemandServer, flags);
                        SCLog(_sc_debug, LOG_INFO, CFSTR("%s  status  * = 0x%08x"),
                              targetPrivate->log_prefix,
                              *flags);
                        SCLog(_sc_debug, LOG_INFO, CFSTR("%s  status  * = 0x%08x"),
                              targetPrivate->log_prefix,
                              *flags);
-                       if (ok && (*flags & kSCNetworkReachabilityFlagsReachable)) {
+
+
+                       if ((*flags & kSCNetworkReachabilityFlagsReachable) && !(*flags & kSCNetworkReachabilityFlagsConnectionRequired)) {
+                               // if VPN "server" is [still] reachable
+
                                if (!(*flags & kSCNetworkReachabilityFlagsTransientConnection)) {
                                if (!(*flags & kSCNetworkReachabilityFlagsTransientConnection)) {
-                                       // start clean if not already layered on a transient network
-                                       *flags = 0;
+                                       // start w/clean flags if not already layered on a transient network
+                                       *flags = kSCNetworkReachabilityFlagsReachable;
                                }
                                }
-                               *flags |= kSCNetworkReachabilityFlagsReachable;
+
                                *flags |= kSCNetworkReachabilityFlagsTransientConnection;
                                *flags |= kSCNetworkReachabilityFlagsConnectionRequired;
                                *flags |= kSCNetworkReachabilityFlagsConnectionOnDemand;
 
                                *flags |= kSCNetworkReachabilityFlagsTransientConnection;
                                *flags |= kSCNetworkReachabilityFlagsConnectionRequired;
                                *flags |= kSCNetworkReachabilityFlagsConnectionOnDemand;
 
+                               // set 'InterventionRequired' if the OnDemand connection is paused
+                               if (SCNetworkConnectionIsOnDemandSuspended(connection)) {
+                                       *flags |= kSCNetworkReachabilityFlagsInterventionRequired;
+                               }
+
                                if (_sc_debug) {
                                        SCLog(TRUE, LOG_INFO, CFSTR("%s  service * = %@"),
                                              targetPrivate->log_prefix,
                                if (_sc_debug) {
                                        SCLog(TRUE, LOG_INFO, CFSTR("%s  service * = %@"),
                                              targetPrivate->log_prefix,
@@ -4515,28 +4845,140 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef  store_info,
                                              targetPrivate->log_prefix);
                                }
 
                                              targetPrivate->log_prefix);
                                }
 
-                               onDemand = TRUE;
+                               success = TRUE;
                        }
                }
 
                if (onDemandRemoteAddress != NULL) {
                        if (targetPrivate->onDemandRemoteAddress == NULL) {
                        }
                }
 
                if (onDemandRemoteAddress != NULL) {
                        if (targetPrivate->onDemandRemoteAddress == NULL) {
-                               targetPrivate->onDemandRemoteAddress = onDemandRemoteAddress;
-                       } else {
-                               CFRelease(onDemandRemoteAddress);
+                               targetPrivate->onDemandRemoteAddress = CFRetain(onDemandRemoteAddress);
                        }
                }
 
                if (onDemandServiceID != NULL) {
                        if (targetPrivate->onDemandServiceID == NULL) {
                        }
                }
 
                if (onDemandServiceID != NULL) {
                        if (targetPrivate->onDemandServiceID == NULL) {
-                               targetPrivate->onDemandServiceID = onDemandServiceID;
-                       } else {
-                               CFRelease(onDemandServiceID);
+                               targetPrivate->onDemandServiceID = CFRetain(onDemandServiceID);
                        }
                }
        }
 
                        }
                }
        }
 
-       return onDemand;
+    done:
+
+       if (onDemandServiceID != NULL) {
+               CFRelease(onDemandServiceID);
+       }
+       if (onDemandRemoteAddress != NULL) {
+               CFRelease(onDemandRemoteAddress);
+       }
+       if (connection != NULL) {
+               CFRelease(connection);
+       }
+       if (selectOptions != NULL) {
+               CFRelease(selectOptions);
+       }
+       return success;
+}
+
+
+/*
+ * OnDemand configuration handling
+ *
+ * Notes :
+ *
+ * 1. We have a "contract" with mDNSResponder that for EVERY network
+ *    or DNS configuration change that should warrant our [re-]starting
+ *    a query, mDNSResponder will acknowledge the latest DNS configuration.
+ *
+ * 2. IPMonitor also posts a notification AFTER every network or DNS
+ *    configuration change.
+ *
+ * 3. We use IPMonitor's "trailing edge" as a signal to restart any
+ *    by-name queries.
+ */
+
+
+// Note: protected by _hn_changes_queue()
+static SCDynamicStoreCallBack  onDemand_callback               = NULL;
+static int                     onDemand_refresh_token;
+static Boolean                 onDemand_refresh_token_valid    = FALSE;
+static SCDynamicStoreRef       onDemand_store                  = NULL;
+
+
+/*
+ * onDemand_refresh_handler
+ *
+ * Called to notify/update all SCNetworkReachability targets of
+ * OnDemand changes.
+ * - caller must be running on the _hn_changes_queue()
+ */
+static void
+onDemand_refresh_handler()
+{
+       CFArrayRef      changes;
+       CFStringRef     key;
+
+       if (!onDemand_refresh_token_valid || (onDemand_callback == NULL)) {
+               return;
+       }
+
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetOnDemand);
+       changes = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
+       (*onDemand_callback)(onDemand_store, changes, NULL);
+       CFRelease(changes);
+       CFRelease(key);
+
+       return;
+}
+
+
+/*
+ * onDemand_refresh_enable
+ *
+ * Called to monitor for OnDemand changes.
+ * - caller must be running on the _hn_changes_queue()
+ */
+static Boolean
+onDemand_refresh_enable(dispatch_queue_t q, SCDynamicStoreRef store, SCDynamicStoreCallBack callback)
+{
+       uint32_t        status;
+
+       onDemand_callback = callback;
+       onDemand_store = CFRetain(store);
+
+       status = notify_register_dispatch(kSCNETWORKCONNECTION_ONDEMAND_NOTIFY_KEY,
+                                         &onDemand_refresh_token,
+                                         q,
+                                         ^(int token){
+                                                 onDemand_refresh_handler();
+                                         });
+       if (status != NOTIFY_STATUS_OK) {
+               SCLog(TRUE, LOG_INFO, CFSTR("notify_register_dispatch() failed, status=%lu"), status);
+               return FALSE;
+       }
+
+       onDemand_refresh_token_valid = TRUE;
+
+       return TRUE;
+}
+
+
+/*
+ * onDemand_refresh_disable
+ *
+ * Called to stop monitoring for OnDemand changes
+ * - caller must be running on the _hn_changes_queue()
+ */
+static void
+onDemand_refresh_disable()
+{
+       (void)notify_cancel(onDemand_refresh_token);
+       onDemand_refresh_token_valid = FALSE;
+       CFRelease(onDemand_store);
+       onDemand_store = NULL;
+       onDemand_callback = NULL;
+       return;
 }
 
 
 }
 
 
@@ -4564,8 +5006,6 @@ reply_callback(int32_t status, struct addrinfo *res, void *context)
 
 static int
 getaddrinfo_interface_sync(const char                  *nodename,
 
 static int
 getaddrinfo_interface_sync(const char                  *nodename,
-                          const char                   *servname,
-                          const struct addrinfo        *hints,
                           const char                   *interface,
                           struct addrinfo              **res)
 {
                           const char                   *interface,
                           struct addrinfo              **res)
 {
@@ -4573,8 +5013,8 @@ getaddrinfo_interface_sync(const char                     *nodename,
        reply_info      reply   = { NETDB_SUCCESS, NULL };
 
        mp = _getaddrinfo_interface_async_call(nodename,
        reply_info      reply   = { NETDB_SUCCESS, NULL };
 
        mp = _getaddrinfo_interface_async_call(nodename,
-                                              servname,
-                                              hints,
+                                              NULL,
+                                              &HINTS_DEFAULT,
                                               interface,
                                               reply_callback,
                                               (void *)&reply);
                                               interface,
                                               reply_callback,
                                               (void *)&reply);
@@ -4621,7 +5061,7 @@ getaddrinfo_interface_sync(const char                     *nodename,
        *res = reply.res;
        return reply.status;
 }
        *res = reply.res;
        return reply.status;
 }
-#endif /* HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL */
+#endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 
 
 static Boolean
 
 
 static Boolean
@@ -4637,7 +5077,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
 
        MUTEX_ASSERT_HELD(&targetPrivate->lock);
 
-       _reach_set(reach_info, &NOT_REACHABLE, reach_info->cycle);
+       _reach_set(reach_info, &NOT_REACHABLE, reach_info->cycle, targetPrivate->if_index, targetPrivate->if_name);
 
        if (!isA_SCNetworkReachability(target)) {
                _SCErrorSet(kSCStatusInvalidArgument);
 
        if (!isA_SCNetworkReachability(target)) {
                _SCErrorSet(kSCStatusInvalidArgument);
@@ -4647,6 +5087,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
 #ifdef HAVE_REACHABILITY_SERVER
        if (!targetPrivate->serverBypass) {
                if (!targetPrivate->serverActive) {
 #ifdef HAVE_REACHABILITY_SERVER
        if (!targetPrivate->serverBypass) {
                if (!targetPrivate->serverActive) {
+
                        ok = __SCNetworkReachabilityServer_targetAdd(target);
                        if (!ok) {
                                targetPrivate->serverBypass = TRUE;
                        ok = __SCNetworkReachabilityServer_targetAdd(target);
                        if (!ok) {
                                targetPrivate->serverBypass = TRUE;
@@ -4663,7 +5104,11 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info,
                        }
 
                        targetPrivate->cycle = targetPrivate->serverInfo.cycle;
                        }
 
                        targetPrivate->cycle = targetPrivate->serverInfo.cycle;
-                       _reach_set(&my_info, &targetPrivate->serverInfo, targetPrivate->cycle);
+                       _reach_set(&my_info,
+                                  &targetPrivate->serverInfo,
+                                  targetPrivate->serverInfo.cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
                        goto done;
                }
        }
                        goto done;
                }
        }
@@ -4724,8 +5169,9 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
                        struct timeval                  dnsQueryStart;
                        struct timeval                  dnsQueryEnd;
                        int                             error;
                        struct timeval                  dnsQueryStart;
                        struct timeval                  dnsQueryEnd;
                        int                             error;
-                       SCNetworkReachabilityFlags      ns_flags;
-                       uint32_t                        ns_if_index;
+                       int                             ns_dns_config   = -1;
+                       SCNetworkReachabilityFlags      ns_flags        = 0;
+                       uint32_t                        ns_if_index     = 0;
                        struct addrinfo                 *res;
 
                        addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
                        struct addrinfo                 *res;
 
                        addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
@@ -4733,186 +5179,100 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef      store_info,
                                /* if resolved or an error had been detected */
                                if (!async) {
                                        /* if not an async request */
                                /* if resolved or an error had been detected */
                                if (!async) {
                                        /* if not an async request */
-                                       goto checkResolvedAddress;
-                               } else if (targetPrivate->llqActive) {
-                                       /* if long-lived-query active */
-                                       goto checkResolvedAddress;
+                                       goto checkResolvedAddresses;
+                               } else if (targetPrivate->dnsActive) {
+                                       /* if [m]DNS query active */
+                                       goto checkResolvedAddresses;
                                } else if ((targetPrivate->dnsMP == MACH_PORT_NULL) && !targetPrivate->needResolve) {
                                } else if ((targetPrivate->dnsMP == MACH_PORT_NULL) && !targetPrivate->needResolve) {
-                                       struct timeval          elapsed;
-                                       const struct timeval    retry_limit     = { EAI_NONAME_RETRY_LIMIT_USEC / USEC_PER_SEC,
-                                                                                   EAI_NONAME_RETRY_LIMIT_USEC % USEC_PER_SEC };
-
                                        /*
                                         * if this is an async request (i.e. someone is watching the reachability
                                         * of this target), if no query active, and if no query is needed
                                         */
                                        /*
                                         * if this is an async request (i.e. someone is watching the reachability
                                         * of this target), if no query active, and if no query is needed
                                         */
-
-                                       if ((error != EAI_NONAME)
-#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
-                                           && (error != EAI_NODATA)
-#endif
-                                          ) {
-                                               /* if not "host not found" */
-                                               goto checkResolvedAddress;
-                                       }
-
-                                       /*
-                                        * if our last DNS query returned EAI_NONAME then we
-                                        * "may" want to retry.
-                                        *
-                                        * Specifically, if the [DNS] configuration was updated a while
-                                        * back then we'll trust the EAI_NONAME reply. Otherwise, we
-                                        * want to try again to ensure that we didn't get caught in a
-                                        * race between the time when the configuration was changed and
-                                        * when mDNSResponder is really ready to handle the query.
-                                        *
-                                        * Retry handling details :
-                                        *
-                                        * Compare the time when the DNS configuration was last changed and
-                                        * when our DNS reply was started (->last_dns vs ->dnsQueryStart).
-                                        *
-                                        * Expected: 0 < last_dns (t1) < dnsQueryStart (t2)
-                                        *
-                                        * last  start  end   description                        action
-                                        * ====  =====  ====  =================================  ========
-                                        *  0     N/A    N/A  no change, query error             no retry
-                                        *  0     N/A    N/A  no change, query complete          no retry
-                                        *  N/A   N/A    0    changed, query in-flight or error  no retry
-                                        *  t1 >  t2          query started, then [DNS] changed  no retry
-                                        *  t1 == t2          changed & query started together   no retry
-                                        *  t1 <  t2          changed, then query started        retry
-                                        */
-
-                                       if (!timerisset(&targetPrivate->last_dns)) {
-                                               /*
-                                                * if we have not yet seen a DNS configuration
-                                                * change
-                                                */
-                                               goto checkResolvedAddress;
-                                       }
-
-                                       if (!timerisset(&targetPrivate->dnsQueryEnd)) {
-                                               /*
-                                                * if no query end time (new request in flight)
-                                                */
-                                               goto checkResolvedAddress;
-                                       }
-
-                                       if (timercmp(&targetPrivate->last_dns,
-                                                    &targetPrivate->dnsQueryStart,
-                                                    >=)) {
-                                               /*
-                                                * if our DNS query started and then, a
-                                                * short time later, the DNS configuration
-                                                * was changed we don't need to retry
-                                                * because we will be re-issuing (and not
-                                                * retrying) the query.
-                                                */
-                                               goto checkResolvedAddress;
-                                       }
-
-                                       timersub(&targetPrivate->dnsQueryStart,
-                                                &targetPrivate->last_dns,
-                                                &elapsed);
-                                       if (timercmp(&elapsed, &retry_limit, >)) {
-                                               /*
-                                                * if the DNS query started after mDNSResponder
-                                                * had a chance to apply the last configuration
-                                                * then we should trust the EAI_NONAME reply.
-                                                */
-                                               goto checkResolvedAddress;
-                                       }
-
-                                       /* retry the DNS query */
-
-                                       if (targetPrivate->dnsRetry != NULL) {
-                                               // no need to schedule if we already have a
-                                               // retry query in flight
-                                               break;
-                                       }
-
-                                       targetPrivate->dnsRetryCount++;
-
-                                       SCLog(_sc_debug, LOG_INFO,
-                                             CFSTR("%sretry [%d] DNS query for %s%s%s%s%s"),
-                                             targetPrivate->log_prefix,
-                                             targetPrivate->dnsRetryCount,
-                                             targetPrivate->name != NULL ? "name = " : "",
-                                             targetPrivate->name != NULL ? targetPrivate->name : "",
-                                             targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                                             targetPrivate->serv != NULL ? "serv = " : "",
-                                             targetPrivate->serv != NULL ? targetPrivate->serv : "");
-
-                                       enqueueAsyncDNSRetry(target);
-                                       break;
+                                       goto checkResolvedAddresses;
                                }
                        }
 
                        if (!targetPrivate->onDemandBypass) {
                                }
                        }
 
                        if (!targetPrivate->onDemandBypass) {
-                               Boolean onDemand;
+                               Boolean                         onDemand;
+                               SCNetworkReachabilityFlags      onDemandFlags   = 0;
 
                                /*
                                 * before we attempt our initial DNS query, check if there is
                                 * an OnDemand configuration that we should be using.
                                 */
 
                                /*
                                 * before we attempt our initial DNS query, check if there is
                                 * an OnDemand configuration that we should be using.
                                 */
-                               onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, FALSE, &my_info.flags);
+                               onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, FALSE, &onDemandFlags);
                                if (onDemand) {
                                        /* if OnDemand connection is needed */
                                if (onDemand) {
                                        /* if OnDemand connection is needed */
+                                       my_info.flags = onDemandFlags;
                                        goto done;
                                }
                        }
 
                                        goto done;
                                }
                        }
 
+                       targetPrivate->dnsBlocked = FALSE;
+
                        /* check the reachability of the DNS servers */
                        ok = _SC_R_checkResolverReachability(store_info,
                                                             &ns_flags,
                                                             &targetPrivate->haveDNS,
                                                             targetPrivate->name,
                        /* check the reachability of the DNS servers */
                        ok = _SC_R_checkResolverReachability(store_info,
                                                             &ns_flags,
                                                             &targetPrivate->haveDNS,
                                                             targetPrivate->name,
-                                                            targetPrivate->serv,
                                                             targetPrivate->if_index,
                                                             &ns_if_index,
                                                             targetPrivate->if_index,
                                                             &ns_if_index,
-                                                            NULL,
+                                                            &ns_dns_config,
                                                             targetPrivate->log_prefix);
                        if (!ok) {
                                /* if we could not get DNS server info */
                                SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server reachability unknown"),
                                      targetPrivate->log_prefix);
                                                             targetPrivate->log_prefix);
                        if (!ok) {
                                /* if we could not get DNS server info */
                                SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server reachability unknown"),
                                      targetPrivate->log_prefix);
+                               targetPrivate->resolverFlags = kSCNetworkReachabilityFlagsReachable;
                                goto error;
                                goto error;
-                       } else if (rankReachability(ns_flags) < 2) {
-                               /*
-                                * if DNS servers are not (or are no longer) reachable, set
-                                * flags based on the availability of configured (but not
-                                * active) services.
-                                */
+                       } else {
 
 
-                               SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server(s) not available"),
-                                     targetPrivate->log_prefix);
+                               // save resolver reachability flags
+                               targetPrivate->resolverFlags = ns_flags;
 
 
-                               ok = checkAddress(store_info,
-                                                 NULL,
-                                                 targetPrivate->if_index,
-                                                 &my_info,
-                                                 targetPrivate->log_prefix);
-                               if (!ok) {
-                                       SCLog(_sc_debug, LOG_INFO, CFSTR("%sNo available networks"),
-                                             targetPrivate->log_prefix);
-                                       goto error;
-                               }
-
-                               if (async && targetPrivate->scheduled) {
+                               if (rankReachability(ns_flags) < 2) {
                                        /*
                                        /*
-                                        * return "host not found", set flags appropriately,
-                                        * and schedule notification.
+                                        * if DNS servers are not (or are no longer) reachable, set
+                                        * flags based on the availability of configured (but not
+                                        * active) services.
                                         */
                                         */
-                                       __SCNetworkReachabilityCallbackSetResolvedAddress(EAI_NONAME,
-                                                                                         NULL,
-                                                                                         (void *)target);
-                                       my_info.flags |= (targetPrivate->info.flags & kSCNetworkReachabilityFlagsFirstResolvePending);
 
 
-                                       SCLog(_sc_debug, LOG_INFO, CFSTR("%sno DNS servers are reachable"),
+                                       SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server(s) not available"),
                                              targetPrivate->log_prefix);
                                              targetPrivate->log_prefix);
-                                       __SCNetworkReachabilityPerform(target);
+
+                                       if (!targetPrivate->dnsBlocked) {
+                                               ok = checkAddress(store_info,
+                                                                 NULL,
+                                                                 targetPrivate->if_index,
+                                                                 &my_info,
+                                                                 targetPrivate->log_prefix);
+                                               if (!ok) {
+                                                       SCLog(_sc_debug, LOG_INFO, CFSTR("%sNo available networks"),
+                                                             targetPrivate->log_prefix);
+                                                       goto error;
+                                               }
+                                       } else {
+                                               // if not checking "available" networks
+                                               my_info.flags = ns_flags;
+                                               my_info.if_index = ns_if_index;
+                                       }
+
+                                       if (async && targetPrivate->scheduled) {
+                                               /*
+                                                * return "host not found", set flags appropriately,
+                                                * and schedule notification.
+                                                */
+                                               __SCNetworkReachabilityCallbackSetResolvedAddresses(EAI_NONAME,
+                                                                                                   NULL,
+                                                                                                   (void *)target);
+                                               my_info.flags |= (targetPrivate->info.flags & kSCNetworkReachabilityFlagsFirstResolvePending);
+
+                                               SCLog(_sc_debug, LOG_INFO, CFSTR("%sno DNS servers are reachable"),
+                                                     targetPrivate->log_prefix);
+                                               __SCNetworkReachabilityPerformLocked(target);
+                                       }
+                                       break;
                                }
                                }
-                               break;
                        }
 
                        if (targetPrivate->resolverBypass) {
                        }
 
                        if (targetPrivate->resolverBypass) {
@@ -4927,118 +5287,95 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef       store_info,
                                /* for async requests we return the last known status */
                                my_info = targetPrivate->info;
 
                                /* for async requests we return the last known status */
                                my_info = targetPrivate->info;
 
-                               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
-                                       /* if request already in progress */
+                               if (targetPrivate->dnsActive) {
+                                       /* if [m]DNS query active */
                                        SCLog(_sc_debug, LOG_INFO,
                                              CFSTR("%swaiting for DNS reply"),
                                              targetPrivate->log_prefix);
                                        if ((addresses != NULL) || (error != NETDB_SUCCESS)) {
                                                /* updated reachability based on the previous reply */
                                        SCLog(_sc_debug, LOG_INFO,
                                              CFSTR("%swaiting for DNS reply"),
                                              targetPrivate->log_prefix);
                                        if ((addresses != NULL) || (error != NETDB_SUCCESS)) {
                                                /* updated reachability based on the previous reply */
-                                               goto checkResolvedAddress;
+                                               goto checkResolvedAddresses;
                                        }
                                        break;
                                }
 
                                        }
                                        break;
                                }
 
-                               if (targetPrivate->dnsRetry != NULL) {
-                                       /* if we already have a "retry" queued */
-                                       break;
-                               }
-
-                               if (targetPrivate->llqActive) {
-                                       /* if long-lived-query active */
+                               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
+                                       /* if request already in progress */
                                        SCLog(_sc_debug, LOG_INFO,
                                        SCLog(_sc_debug, LOG_INFO,
-                                             CFSTR("%swaiting for DNS updates"),
+                                             CFSTR("%swaiting for DNS* reply"),
                                              targetPrivate->log_prefix);
                                        if ((addresses != NULL) || (error != NETDB_SUCCESS)) {
                                                /* updated reachability based on the previous reply */
                                              targetPrivate->log_prefix);
                                        if ((addresses != NULL) || (error != NETDB_SUCCESS)) {
                                                /* updated reachability based on the previous reply */
-                                               goto checkResolvedAddress;
+                                               goto checkResolvedAddresses;
                                        }
                                        break;
                                }
 
                                        }
                                        break;
                                }
 
-                               if (!targetPrivate->llqBypass) {
-                                       SCLog(_sc_debug, LOG_INFO,
-                                             CFSTR("%sstart long-lived DNS query for %s%s%s%s%s"),
-                                             targetPrivate->log_prefix,
-                                             targetPrivate->name != NULL ? "name = " : "",
-                                             targetPrivate->name != NULL ? targetPrivate->name : "",
-                                             targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                                             targetPrivate->serv != NULL ? "serv = " : "",
-                                             targetPrivate->serv != NULL ? targetPrivate->serv : "");
-
-                                       /*
-                                        * initiate an long-lived DNS query
-                                        */
-                                       if (enqueueLongLivedQuery(target)) {
-                                               /* request initiated */
-                                               break;
-                                       }
-                               }
-
                                SCLog(_sc_debug, LOG_INFO,
                                SCLog(_sc_debug, LOG_INFO,
-                                     CFSTR("%sstart DNS query for %s%s%s%s%s"),
+                                     CFSTR("%sstart DNS query for name = %s"),
                                      targetPrivate->log_prefix,
                                      targetPrivate->log_prefix,
-                                     targetPrivate->name != NULL ? "name = " : "",
-                                     targetPrivate->name != NULL ? targetPrivate->name : "",
-                                     targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                                     targetPrivate->serv != NULL ? "serv = " : "",
-                                     targetPrivate->serv != NULL ? targetPrivate->serv : "");
+                                     targetPrivate->name);
+
+#ifdef USE_DNSSERVICEGETADDRINFO
+                               /*
+                                * initiate an DNS query w/DNSServiceGetAddrInfo
+                                */
+                               if (enqueueDNSQuery(target)) {
+                                       /* request initiated */
+                                       break;
+                               }
+#endif // USE_DNSSERVICEGETADDRINFO
 
                                /*
 
                                /*
-                                * initiate an async DNS query
+                                * if we were unable to use DNSServiceGetAddrInfo
+                                * then try with getaddrinfo[_async_start]
                                 */
                                 */
-                               if (startAsyncDNSQuery(target)) {
+                               if (enqueueAsyncDNSQuery(target)) {
                                        /* request initiated */
                                        break;
                                }
 
                                /* if we could not initiate the request, process error */
                                        /* request initiated */
                                        break;
                                }
 
                                /* if we could not initiate the request, process error */
-                               goto checkResolvedAddress;
+                               goto checkResolvedAddresses;
                        }
 
                        SCLog(_sc_debug, LOG_INFO,
                        }
 
                        SCLog(_sc_debug, LOG_INFO,
-                             CFSTR("%scheck DNS for %s%s%s%s%s"),
+                             CFSTR("%scheck DNS for name = %s"),
                              targetPrivate->log_prefix,
                              targetPrivate->log_prefix,
-                             targetPrivate->name != NULL ? "name = " : "",
-                             targetPrivate->name != NULL ? targetPrivate->name : "",
-                             targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                             targetPrivate->serv != NULL ? "serv = " : "",
-                             targetPrivate->serv != NULL ? targetPrivate->serv : "");
+                             targetPrivate->name);
 
                        /*
                         * OK, all of the DNS name servers are available.  Let's
                         * resolve the nodename into an address.
                         */
 
                        /*
                         * OK, all of the DNS name servers are available.  Let's
                         * resolve the nodename into an address.
                         */
-                       __dns_query_start(&dnsQueryStart, &dnsQueryEnd);
+                       __mark_operation_start(&dnsQueryStart, &dnsQueryEnd);
 
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                        if (targetPrivate->if_index == 0) {
 #endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                                error = getaddrinfo(targetPrivate->name,
 
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                        if (targetPrivate->if_index == 0) {
 #endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                                error = getaddrinfo(targetPrivate->name,
-                                                   targetPrivate->serv,
-                                                   &targetPrivate->hints,
+                                                   NULL,
+                                                   &HINTS_DEFAULT,
                                                    &res);
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                        } else {
                                error = getaddrinfo_interface_sync(targetPrivate->name,
                                                    &res);
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                        } else {
                                error = getaddrinfo_interface_sync(targetPrivate->name,
-                                                                  targetPrivate->serv,
-                                                                  &targetPrivate->hints,
                                                                   targetPrivate->if_name,
                                                                   &res);
                        }
 #endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 
                                                                   targetPrivate->if_name,
                                                                   &res);
                        }
 #endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 
-                       __dns_query_end(target,
-                                        ((error == 0) && (res != NULL)),       // if successful query
-                                        dns_query_sync,                        // sync
-                                        &dnsQueryStart,                        // start time
-                                        &dnsQueryEnd);                         // end time
+                       __mark_operation_end(target,
+                                            ((error == 0) && (res != NULL)),   // if successful query
+                                            dns_query_sync,                    // sync
+                                            &dnsQueryStart,                    // start time
+                                            &dnsQueryEnd);                     // end time
 
 
-                       __SCNetworkReachabilitySetResolvedAddress(error, res, target);
+                       __SCNetworkReachabilitySetResolvedAddresses(error, res, target);
 
                        addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
 
 
                        addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
 
-                   checkResolvedAddress :
+                   checkResolvedAddresses :
 
                        /*
                         * We first assume that the requested host is NOT available.
 
                        /*
                         * We first assume that the requested host is NOT available.
@@ -5085,19 +5422,22 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef        store_info,
                                         * the target host name could not be resolved
                                         */
                                        if (!targetPrivate->onDemandBypass) {
                                         * the target host name could not be resolved
                                         */
                                        if (!targetPrivate->onDemandBypass) {
-                                               Boolean onDemand;
+                                               Boolean                         onDemand;
+                                               SCNetworkReachabilityFlags      onDemandFlags   = 0;
 
                                                /*
                                                 * our initial DNS query failed, check again to see if there
                                                 * there is an OnDemand configuration that we should be using.
                                                 */
 
                                                /*
                                                 * our initial DNS query failed, check again to see if there
                                                 * there is an OnDemand configuration that we should be using.
                                                 */
-                                               onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, TRUE, &my_info.flags);
+                                               onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, TRUE, &onDemandFlags);
                                                if (onDemand) {
                                                        /* if OnDemand connection is needed */
                                                if (onDemand) {
                                                        /* if OnDemand connection is needed */
+                                                       my_info.flags = onDemandFlags;
                                                        goto done;
                                                }
                                        }
 
                                                        goto done;
                                                }
                                        }
 
+
                                        if (!targetPrivate->haveDNS) {
                                                /*
                                                 * No DNS servers are defined. Set flags based on
                                        if (!targetPrivate->haveDNS) {
                                                /*
                                                 * No DNS servers are defined. Set flags based on
@@ -5134,7 +5474,8 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
 
     done:
 
 
     done:
 
-       _reach_set(reach_info, &my_info, targetPrivate->cycle);
+
+       _reach_set(reach_info, &my_info, targetPrivate->cycle, targetPrivate->if_index, targetPrivate->if_name);
 
     error :
 
 
     error :
 
@@ -5143,9 +5484,8 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
 }
 
 int
 }
 
 int
-SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef        target)
+SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target)
 {
 {
-       SCNetworkReachabilityFlags      flags;
        int                             if_index        = -1;
        Boolean                         ok              = TRUE;
        ReachabilityStoreInfo           store_info;
        int                             if_index        = -1;
        Boolean                         ok              = TRUE;
        ReachabilityStoreInfo           store_info;
@@ -5162,19 +5502,17 @@ SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target)
 
        if (targetPrivate->scheduled) {
                // if being watched, return the last known (and what should be current) status
 
        if (targetPrivate->scheduled) {
                // if being watched, return the last known (and what should be current) status
-               flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending;
                goto done;
        }
 
 
        ok = __SCNetworkReachabilityGetFlags(&store_info, target, &targetPrivate->info, FALSE);
                goto done;
        }
 
 
        ok = __SCNetworkReachabilityGetFlags(&store_info, target, &targetPrivate->info, FALSE);
-       flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending;
 
     done :
 
        /* Only return the if_index if the connection is reachable not for reachable connection
         * required etc ... */
 
     done :
 
        /* Only return the if_index if the connection is reachable not for reachable connection
         * required etc ... */
-       if (ok && rankReachability(flags) == 2) {
+       if (ok && rankReachability(targetPrivate->info.flags) == 2) {
                if_index = targetPrivate->info.if_index;
        }
 
                if_index = targetPrivate->info.if_index;
        }
 
@@ -5203,13 +5541,17 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef          target,
 
        if (targetPrivate->scheduled) {
                // if being watched, return the last known (and what should be current) status
 
        if (targetPrivate->scheduled) {
                // if being watched, return the last known (and what should be current) status
-               *flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending;
+               *flags = targetPrivate->info.flags & kSCNetworkReachabilityFlagsMask;
                goto done;
        }
 
 
        ok = __SCNetworkReachabilityGetFlags(&store_info, target, &targetPrivate->info, FALSE);
                goto done;
        }
 
 
        ok = __SCNetworkReachabilityGetFlags(&store_info, target, &targetPrivate->info, FALSE);
-       *flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending;
+       if (_sc_debug) {
+               SCLog(TRUE, LOG_INFO, CFSTR("%s  flags     = 0x%08x"), targetPrivate->log_prefix, targetPrivate->info.flags);
+       }
+
+       *flags = targetPrivate->info.flags & kSCNetworkReachabilityFlagsMask;
 
     done :
 
 
     done :
 
@@ -5224,7 +5566,7 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef            target,
 
 
 static void
 
 
 static void
-__SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef  store)
+__SCNetworkReachabilitySetNotifications(SCDynamicStoreRef      store)
 {
        CFStringRef                     key;
        CFMutableArrayRef               keys;
 {
        CFStringRef                     key;
        CFMutableArrayRef               keys;
@@ -5234,113 +5576,117 @@ __SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef store)
        keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
        keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
-       // Setup:/Network/Global/IPv4 (for the ServiceOrder)
-       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
-                                                        kSCDynamicStoreDomainSetup,
-                                                        kSCEntNetIPv4);
-       CFArrayAppendValue(keys, key);
-       CFRelease(key);
-
-       // State:/Network/Global/DNS
-       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
-                                                        kSCDynamicStoreDomainState,
-                                                        kSCEntNetDNS);
-       CFArrayAppendValue(keys, key);
-       CFRelease(key);
-
-       // State:/Network/Global/IPv4 (default route)
-       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
-                                                        kSCDynamicStoreDomainState,
-                                                        kSCEntNetIPv4);
-       CFArrayAppendValue(keys, key);
-       CFRelease(key);
-
-       // State:/Network/Global/OnDemand
-       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
-                                                        kSCDynamicStoreDomainState,
-                                                        kSCEntNetOnDemand);
-       CFArrayAppendValue(keys, key);
-       CFRelease(key);
-
-       // Setup: per-service Interface info
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetInterface);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
+       // If we are bypassing nwi, then we need to get the info from the store.
+       if (D_nwiBypass) {
+               // Setup:/Network/Global/IPv4 (for the ServiceOrder)
+               key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                                kSCDynamicStoreDomainSetup,
+                                                                kSCEntNetIPv4);
+               CFArrayAppendValue(keys, key);
+               CFRelease(key);
 
 
-       // per-service IPv4 info
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPv4);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainState,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPv4);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
+#ifndef        USE_DNSSERVICEGETADDRINFO
+               // State:/Network/Global/DNS
+               key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                                kSCDynamicStoreDomainState,
+                                                                kSCEntNetDNS);
+               CFArrayAppendValue(keys, key);
+               CFRelease(key);
+#endif // USE_DNSSERVICEGETADDRINFO
 
 
-       // per-service IPv6 info
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPv6);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainState,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPv6);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
+               // State:/Network/Global/IPv4 (default route)
+               key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                                kSCDynamicStoreDomainState,
+                                                                kSCEntNetIPv4);
+               CFArrayAppendValue(keys, key);
+               CFRelease(key);
 
 
-       // per-service PPP info (for existence, kSCPropNetPPPDialOnDemand, kSCPropNetPPPStatus)
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetPPP);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainState,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetPPP);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
+               // State:/Network/Global/OnDemand
+               key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                                kSCDynamicStoreDomainState,
+                                                                kSCEntNetOnDemand);
+               CFArrayAppendValue(keys, key);
+               CFRelease(key);
 
 
-#if    !TARGET_IPHONE_SIMULATOR
-       // per-service VPN info (for existence, kSCPropNetVPNStatus)
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetVPN);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainState,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetVPN);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-#endif // !TARGET_IPHONE_SIMULATOR
+               // Setup: per-service Interface info
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetInterface);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+
+               // per-service IPv4 info
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPv4);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainState,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPv4);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+
+               // per-service IPv6 info
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPv6);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainState,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPv6);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+
+               // per-service PPP info (for existence, kSCPropNetPPPDialOnDemand, kSCPropNetPPPStatus)
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetPPP);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainState,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetPPP);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+
+               // per-service VPN info (for existence, kSCPropNetVPNStatus)
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetVPN);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainState,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetVPN);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+
+               // per-service IPSec info (for existence, kSCPropNetIPSecStatus)
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainSetup,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPSec);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
+               pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                     kSCDynamicStoreDomainState,
+                                                                     kSCCompAnyRegex,
+                                                                     kSCEntNetIPSec);
+               CFArrayAppendValue(patterns, pattern);
+               CFRelease(pattern);
 
 
-       // per-service IPSec info (for existence, kSCPropNetIPSecStatus)
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainSetup,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPSec);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
-       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                             kSCDynamicStoreDomainState,
-                                                             kSCCompAnyRegex,
-                                                             kSCEntNetIPSec);
-       CFArrayAppendValue(patterns, pattern);
-       CFRelease(pattern);
+       }
 
 #if    !TARGET_OS_IPHONE
        // State: Power Management Capabilities
 
 #if    !TARGET_OS_IPHONE
        // State: Power Management Capabilities
@@ -5351,7 +5697,6 @@ __SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef     store)
        CFRelease(key);
 #endif // TARGET_OS_IPHONE
 
        CFRelease(key);
 #endif // TARGET_OS_IPHONE
 
-
        // SCDynamicStore key to force posting a reachability change
        CFArrayAppendValue(keys, SCNETWORKREACHABILITY_TRIGGER_KEY);
 
        // SCDynamicStore key to force posting a reachability change
        CFArrayAppendValue(keys, SCNETWORKREACHABILITY_TRIGGER_KEY);
 
@@ -5363,28 +5708,11 @@ __SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef   store)
 }
 
 
 }
 
 
-static dispatch_queue_t
-_hn_queue()
-{
-       static dispatch_once_t  once;
-       static dispatch_queue_t q;
-
-       dispatch_once(&once, ^{
-               q = dispatch_queue_create("SCNetworkReachabilty.changes", NULL);
-       });
-
-       return q;
-}
-
-
 static void
 __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store,
                                     CFArrayRef         changedKeys,
                                     void               *info)
 {
 static void
 __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store,
                                     CFArrayRef         changedKeys,
                                     void               *info)
 {
-#if    !TARGET_OS_IPHONE
-       Boolean                 cpuStatusChanged        = FALSE;
-#endif // !TARGET_OS_IPHONE
        Boolean                 dnsConfigChanged        = FALSE;
        CFIndex                 i;
        Boolean                 forcedChange            = FALSE;
        Boolean                 dnsConfigChanged        = FALSE;
        CFIndex                 i;
        Boolean                 forcedChange            = FALSE;
@@ -5394,6 +5722,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef    store,
        CFIndex                 nTargets;
        Boolean                 networkConfigChanged    = FALSE;
        struct timeval          now;
        CFIndex                 nTargets;
        Boolean                 networkConfigChanged    = FALSE;
        struct timeval          now;
+       Boolean                 onDemandConfigChanged   = FALSE;
 #if    !TARGET_OS_IPHONE
        Boolean                 powerStatusChanged      = FALSE;
 #endif // !TARGET_OS_IPHONE
 #if    !TARGET_OS_IPHONE
        Boolean                 powerStatusChanged      = FALSE;
 #endif // !TARGET_OS_IPHONE
@@ -5411,7 +5740,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef    store,
        /* "something" changed, start fresh */
        ReachabilityStoreInfo_save(NULL);
 
        /* "something" changed, start fresh */
        ReachabilityStoreInfo_save(NULL);
 
-       dispatch_sync(_hn_queue(), ^{
+       dispatch_sync(_hn_target_queue(), ^{
                /* grab the currently watched targets */
                if (hn_targets != NULL) {
                        watchers = CFSetCreateCopy(NULL, hn_targets);
                /* grab the currently watched targets */
                if (hn_targets != NULL) {
                        watchers = CFSetCreateCopy(NULL, hn_targets);
@@ -5438,30 +5767,15 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
 
                num = SCDynamicStoreCopyValue(store, key);
                if (num != NULL) {
 
                num = SCDynamicStoreCopyValue(store, key);
                if (num != NULL) {
-                       if (isA_CFNumber(num) &&
-                           CFNumberGetValue(num, kCFNumberSInt32Type, &power_capabilities)) {
-                               static Boolean  haveCPU_old     = TRUE;
-                               Boolean         haveCPU_new;
-
-                               haveCPU_new = (power_capabilities & kIOPMSystemPowerStateCapabilityCPU) != 0;
-                               if ((haveCPU_old != haveCPU_new) && haveCPU_new) {
-                                       /*
-                                        * if the power state now shows CPU availability
-                                        * then we will assume that the DNS configuration
-                                        * has changed.  This will force us to re-issue
-                                        * our DNS queries since mDNSResponder does not
-                                        * attempt to resolve names when "sleeping".
-                                        */
-                                       cpuStatusChanged = TRUE;
-                                       dnsConfigChanged = TRUE;
-                               }
-                               haveCPU_old = haveCPU_new;
-                       } else {
+                       if (!isA_CFNumber(num) ||
+                           !CFNumberGetValue(num, kCFNumberSInt32Type, &power_capabilities)) {
+                               // data not as expected, use default
                                power_capabilities = kIOPMSytemPowerStateCapabilitiesMask;
                        }
 
                        CFRelease(num);
                } else {
                                power_capabilities = kIOPMSytemPowerStateCapabilitiesMask;
                        }
 
                        CFRelease(num);
                } else {
+                       // data not available, use default
                        power_capabilities = kIOPMSytemPowerStateCapabilitiesMask;
                }
 
                        power_capabilities = kIOPMSytemPowerStateCapabilitiesMask;
                }
 
@@ -5479,6 +5793,19 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
        }
        CFRelease(key);
 
        }
        CFRelease(key);
 
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetOnDemand);
+       if (CFArrayContainsValue(changedKeys, CFRangeMake(0, nChanges), key)) {
+               nGlobals++;
+               onDemandConfigChanged = TRUE;   /* the OnDemand configuration has changed */
+
+               // force OnDemand configuration refresh (if SC notification arrives before BSD notify)
+               __SCNetworkConnectionForceOnDemandConfigurationRefresh();
+       }
+       CFRelease(key);
+
+
        if (CFArrayContainsValue(changedKeys, CFRangeMake(0, nChanges), SCNETWORKREACHABILITY_TRIGGER_KEY)) {
                nGlobals++;
                forcedChange = TRUE;            /* an SCDynamicStore driven "network" change */
        if (CFArrayContainsValue(changedKeys, CFRangeMake(0, nChanges), SCNETWORKREACHABILITY_TRIGGER_KEY)) {
                nGlobals++;
                forcedChange = TRUE;            /* an SCDynamicStore driven "network" change */
@@ -5496,31 +5823,39 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
                        "network ",
                        "DNS ",
                        "network and DNS ",
                        "network ",
                        "DNS ",
                        "network and DNS ",
+                       "OnDemand ",
+                       "network and OnDemand ",
+                       "DNS and OnDemand ",
+                       "network, DNS, and OnDemand ",
 #if    !TARGET_OS_IPHONE
                        // with "power" status change
                        "power ",
                        "network and power ",
                        "DNS and power ",
                        "network, DNS, and power ",
 #if    !TARGET_OS_IPHONE
                        // with "power" status change
                        "power ",
                        "network and power ",
                        "DNS and power ",
                        "network, DNS, and power ",
-
-                       // with "power" status change (including CPU "on")
-                       "power* ",
-                       "network and power* ",
-                       "DNS and power* ",
-                       "network, DNS, and power* ",
+                       "power ",
+                       "network, OnDemand, and power ",
+                       "DNS, OnDemand, and power ",
+                       "network, DNS, OnDemand, and power ",
+                       "OnDemand and power ",
+                       "network, OnDemand, and power ",
+                       "DNS, OnDemand, and power ",
+                       "network, DNS, OnDemand, and power ",
 #endif // !TARGET_OS_IPHONE
                };
 
 #if    !TARGET_OS_IPHONE
 #endif // !TARGET_OS_IPHONE
                };
 
 #if    !TARGET_OS_IPHONE
-               #define PWR     4
+               #define PWR     8
                if (powerStatusChanged) {
                        changes |= PWR;
                if (powerStatusChanged) {
                        changes |= PWR;
-                       if (cpuStatusChanged) {
-                               changes += PWR;
-                       }
                }
 #endif // !TARGET_OS_IPHONE
 
                }
 #endif // !TARGET_OS_IPHONE
 
+               #define VOD     4
+               if (onDemandConfigChanged) {
+                       changes |= VOD;
+               }
+
                #define DNS     2
                if (dnsConfigChanged) {
                        changes |= DNS;
                #define DNS     2
                if (dnsConfigChanged) {
                        changes |= DNS;
@@ -5532,7 +5867,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef    store,
                }
 
                SCLog(TRUE, LOG_INFO,
                }
 
                SCLog(TRUE, LOG_INFO,
-                     CFSTR("process %s%sconfiguration change"),
+                     CFSTR("process %s%s%sconfiguration change"),
                      forcedChange ? "[forced] " : "",
                      change_strings[changes]);
        }
                      forcedChange ? "[forced] " : "",
                      change_strings[changes]);
        }
@@ -5543,14 +5878,15 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
                targets = CFAllocatorAllocate(NULL, nTargets * sizeof(CFTypeRef), 0);
        CFSetGetValues(watchers, targets);
        for (i = 0; i < nTargets; i++) {
                targets = CFAllocatorAllocate(NULL, nTargets * sizeof(CFTypeRef), 0);
        CFSetGetValues(watchers, targets);
        for (i = 0; i < nTargets; i++) {
+               Boolean                         dnsNeedsUpdate  = FALSE;
                SCNetworkReachabilityRef        target          = targets[i];
                SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
                MUTEX_LOCK(&targetPrivate->lock);
 
                SCNetworkReachabilityRef        target          = targets[i];
                SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
                MUTEX_LOCK(&targetPrivate->lock);
 
+
                if (dnsConfigChanged) {
                        targetPrivate->last_dns = now;
                if (dnsConfigChanged) {
                        targetPrivate->last_dns = now;
-                       targetPrivate->dnsRetryCount = 0;
                }
 
                if (networkConfigChanged) {
                }
 
                if (networkConfigChanged) {
@@ -5564,14 +5900,19 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
 #endif // !TARGET_OS_IPHONE
 
                if (targetPrivate->type == reachabilityTypeName) {
 #endif // !TARGET_OS_IPHONE
 
                if (targetPrivate->type == reachabilityTypeName) {
-                       Boolean         dnsChanged      = dnsConfigChanged;
+                       Boolean         dnsChanged      = (dnsConfigChanged     |
+                                                          dnsNeedsUpdate       |
+                                                          onDemandConfigChanged);
 
                        if (!dnsChanged) {
                                /*
                                 * if the DNS configuration didn't change we still need to
                                 * check that the DNS servers are accessible.
                                 */
 
                        if (!dnsChanged) {
                                /*
                                 * if the DNS configuration didn't change we still need to
                                 * check that the DNS servers are accessible.
                                 */
-                               SCNetworkReachabilityFlags      ns_flags;
+                               Boolean                         ns_blocked      = FALSE;
+                               int                             ns_dns_config   = -1;
+                               SCNetworkReachabilityFlags      ns_flags        = 0;
+                               uint32_t                        ns_if_index     = 0;
                                Boolean                         ok;
 
                                /* check the reachability of the DNS servers */
                                Boolean                         ok;
 
                                /* check the reachability of the DNS servers */
@@ -5581,10 +5922,9 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
                                                                             &ns_flags,
                                                                             &targetPrivate->haveDNS,
                                                                             targetPrivate->name,
                                                                             &ns_flags,
                                                                             &targetPrivate->haveDNS,
                                                                             targetPrivate->name,
-                                                                            targetPrivate->serv,
                                                                             targetPrivate->if_index,
                                                                             targetPrivate->if_index,
-                                                                            NULL,
-                                                                            NULL,
+                                                                            &ns_if_index,
+                                                                            &ns_dns_config,
                                                                             targetPrivate->log_prefix);
                                }
 
                                                                             targetPrivate->log_prefix);
                                }
 
@@ -5592,36 +5932,48 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
                                        /* if we could not get DNS server info */
                                        SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server reachability unknown"),
                                              targetPrivate->log_prefix);
                                        /* if we could not get DNS server info */
                                        SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server reachability unknown"),
                                              targetPrivate->log_prefix);
+                                       ns_flags = kSCNetworkReachabilityFlagsReachable;
                                        dnsChanged = TRUE;
                                        dnsChanged = TRUE;
-                               } else if (rankReachability(ns_flags) < 2) {
-                                       /*
-                                        * if DNS servers are not (or are no longer) reachable, set
-                                        * flags based on the availability of configured (but not
-                                        * active) services.
-                                        */
-                                       SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server(s) not available"),
-                                             targetPrivate->log_prefix);
+                               } else {
+
+                                       if (rankReachability(ns_flags) < 2) {
+                                               /*
+                                                * if DNS servers are not (or are no longer) reachable, set
+                                                * flags based on the availability of configured (but not
+                                                * active) services.
+                                                */
+                                               SCLog(_sc_debug, LOG_INFO, CFSTR("%sDNS server(s) not available"),
+                                                     targetPrivate->log_prefix);
+                                               dnsChanged = TRUE;
+                                       }
+                               }
+
+                               if ((targetPrivate->dnsBlocked != ns_blocked) ||
+                                   (targetPrivate->resolverFlags != ns_flags)) {
+                                       // if the DNS blocked or resolver reachability changed
+                                       targetPrivate->dnsBlocked = ns_blocked;
+                                       targetPrivate->resolverFlags = ns_flags;
                                        dnsChanged = TRUE;
                                }
                        }
 
                        if (dnsChanged) {
                                        dnsChanged = TRUE;
                                }
                        }
 
                        if (dnsChanged) {
-                               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
-                                       /* cancel the outstanding DNS query */
+                               if (targetPrivate->dnsActive) {
+                                       // if we have an outstanding [m]DNS query
                                        SCLog(_sc_debug, LOG_INFO,
                                        SCLog(_sc_debug, LOG_INFO,
-                                             CFSTR("%scancel DNS query for %s%s%s%s%s"),
+                                             CFSTR("%scancel [m]DNS query for name = %s"),
                                              targetPrivate->log_prefix,
                                              targetPrivate->log_prefix,
-                                             targetPrivate->name != NULL ? "name = " : "",
-                                             targetPrivate->name != NULL ? targetPrivate->name : "",
-                                             targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
-                                             targetPrivate->serv != NULL ? "serv = " : "",
-                                             targetPrivate->serv != NULL ? targetPrivate->serv : "");
-                                       dequeueAsyncDNSQuery(target, TRUE);
+                                             targetPrivate->name);
+                                       dequeueDNSQuery(target);
                                }
 
                                }
 
-                               if (targetPrivate->dnsRetry != NULL) {
-                                       /* cancel the outstanding DNS retry */
-                                       dequeueAsyncDNSRetry(target);
+                               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
+                                       /* if we have an outstanding [async] DNS query */
+                                       SCLog(_sc_debug, LOG_INFO,
+                                             CFSTR("%scancel DNS query for name = %s"),
+                                             targetPrivate->log_prefix,
+                                             targetPrivate->name);
+                                       dequeueAsyncDNSQuery(target, TRUE);
                                }
 
                                /* schedule request to resolve the name again */
                                }
 
                                /* schedule request to resolve the name again */
@@ -5634,7 +5986,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef    store,
                }
 
                if (targetPrivate->scheduled) {
                }
 
                if (targetPrivate->scheduled) {
-                       __SCNetworkReachabilityPerform(target);
+                       __SCNetworkReachabilityPerformLocked(target);
                }
 
                MUTEX_UNLOCK(&targetPrivate->lock);
                }
 
                MUTEX_UNLOCK(&targetPrivate->lock);
@@ -5710,11 +6062,6 @@ reachPerform(void *info)
 
        MUTEX_LOCK(&targetPrivate->lock);
 
 
        MUTEX_LOCK(&targetPrivate->lock);
 
-       if (targetPrivate->dnsRetry != NULL) {
-               // cancel DNS retry
-               dequeueAsyncDNSRetry(target);
-       }
-
        if (!targetPrivate->scheduled) {
                // if not currently scheduled
                MUTEX_UNLOCK(&targetPrivate->lock);
        if (!targetPrivate->scheduled) {
                // if not currently scheduled
                MUTEX_UNLOCK(&targetPrivate->lock);
@@ -5799,7 +6146,10 @@ reachPerform(void *info)
              forced ? ", forced" : "");
 
        /* update flags / interface */
              forced ? ", forced" : "");
 
        /* update flags / interface */
-       _reach_set(&targetPrivate->info, &reach_info, cycle);
+       _reach_set(&targetPrivate->info, &reach_info, cycle, targetPrivate->if_index, targetPrivate->if_name);
+
+       /* save last notification info */
+       _reach_set(&targetPrivate->last_notify, &reach_info, cycle, targetPrivate->if_index, targetPrivate->if_name);
 
        /* as needed, defer the notification */
        if (defer) {
 
        /* as needed, defer the notification */
        if (defer) {
@@ -5807,9 +6157,6 @@ reachPerform(void *info)
                return;
        }
 
                return;
        }
 
-       /* save last notification info */
-       _reach_set(&targetPrivate->last_notify, &reach_info, cycle);
-
        /* save last notification time */
        (void)gettimeofday(&targetPrivate->last_push, NULL);
 
        /* save last notification time */
        (void)gettimeofday(&targetPrivate->last_push, NULL);
 
@@ -5827,7 +6174,7 @@ reachPerform(void *info)
 
        if (rlsFunction != NULL) {
                (*rlsFunction)(target,
 
        if (rlsFunction != NULL) {
                (*rlsFunction)(target,
-                              reach_info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending,
+                              reach_info.flags & kSCNetworkReachabilityFlagsMask,
                               context_info);
        }
 
                               context_info);
        }
 
@@ -5905,6 +6252,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef       target,
 #ifdef HAVE_REACHABILITY_SERVER
        if (!targetPrivate->serverBypass) {
                if (!targetPrivate->serverActive) {
 #ifdef HAVE_REACHABILITY_SERVER
        if (!targetPrivate->serverBypass) {
                if (!targetPrivate->serverActive) {
+
                        ok = __SCNetworkReachabilityServer_targetAdd(target);
                        if (!ok) {
                                targetPrivate->serverBypass = TRUE;
                        ok = __SCNetworkReachabilityServer_targetAdd(target);
                        if (!ok) {
                                targetPrivate->serverBypass = TRUE;
@@ -5925,6 +6273,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef       target,
                                goto done;
                        }
 
                                goto done;
                        }
 
+
                        goto watch;
                }
        }
                        goto watch;
                }
        }
@@ -5932,51 +6281,86 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef     target,
 
        /* schedule the SCNetworkReachability did-something-change handler */
 
 
        /* schedule the SCNetworkReachability did-something-change handler */
 
-       dispatch_sync(_hn_queue(), ^{
+       dispatch_sync(_hn_target_queue(), ^{
                ok = FALSE;
 
                if (!onDemand && (hn_store == NULL)) {
                ok = FALSE;
 
                if (!onDemand && (hn_store == NULL)) {
-                       /*
-                        * if we are not monitoring any hosts, start watching
-                        */
-                       if (!dns_configuration_watch()) {
-                               // if error
-                               _SCErrorSet(kSCStatusFailed);
-                               return;
-                       }
-
                        hn_store = SCDynamicStoreCreate(NULL,
                                                        CFSTR("SCNetworkReachability"),
                                                        __SCNetworkReachabilityHandleChanges,
                                                        NULL);
                        if (hn_store == NULL) {
                                SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed"));
                        hn_store = SCDynamicStoreCreate(NULL,
                                                        CFSTR("SCNetworkReachability"),
                                                        __SCNetworkReachabilityHandleChanges,
                                                        NULL);
                        if (hn_store == NULL) {
                                SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed"));
-                               dns_configuration_unwatch();
                                return;
                        }
 
                                return;
                        }
 
-                       __SCNetworkReachabilityReachabilitySetNotifications(hn_store);
+                       __SCNetworkReachabilitySetNotifications(hn_store);
 
 
-                       hn_dispatchQueue = dispatch_queue_create("SCNetworkReachabilty.changes", NULL);
-                       if (hn_dispatchQueue == NULL) {
-                               SCLog(TRUE, LOG_ERR, CFSTR("__SCNetworkReachabilityScheduleWithRunLoop dispatch_queue_create() failed"));
+                       ok = SCDynamicStoreSetDispatchQueue(hn_store, _hn_changes_queue());
+                       if (!ok) {
+                               SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetDispatchQueue() failed"));
                                CFRelease(hn_store);
                                hn_store = NULL;
                                CFRelease(hn_store);
                                hn_store = NULL;
-                               dns_configuration_unwatch();
-                               _SCErrorSet(kSCStatusFailed);
                                return;
                        }
 
                                return;
                        }
 
-                       ok = SCDynamicStoreSetDispatchQueue(hn_store, hn_dispatchQueue);
-                       if (!ok) {
-                               SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetDispatchQueue() failed"));
-                               dispatch_release(hn_dispatchQueue);
-                               hn_dispatchQueue = NULL;
+                       if (!dns_configuration_watch()) {
+                               // if error
+                               SCDynamicStoreSetDispatchQueue(hn_store, NULL);
                                CFRelease(hn_store);
                                hn_store = NULL;
                                CFRelease(hn_store);
                                hn_store = NULL;
+                               _SCErrorSet(kSCStatusFailed);
+                               return;
+                       }
+
+#ifdef USE_DNSSERVICEGETADDRINFO
+                       if (!dns_refresh_enable(_hn_changes_queue(),
+                                               hn_store,
+                                               __SCNetworkReachabilityHandleChanges)) {
+                               // if error
                                dns_configuration_unwatch();
                                dns_configuration_unwatch();
+                               SCDynamicStoreSetDispatchQueue(hn_store, NULL);
+                               CFRelease(hn_store);
+                               hn_store = NULL;
+                               _SCErrorSet(kSCStatusFailed);
                                return;
                        }
                                return;
                        }
+#endif // USE_DNSSERVICEGETADDRINFO
+
+                       if (!D_nwiBypass) {
+                               if (!onDemand_refresh_enable(_hn_changes_queue(),
+                                                            hn_store,
+                                                            __SCNetworkReachabilityHandleChanges)) {
+                                       // if error
+                                       dns_configuration_unwatch();
+#ifdef USE_DNSSERVICEGETADDRINFO
+                                       dns_refresh_disable();
+#endif // USE_DNSSERVICEGETADDRINFO
+                                       SCDynamicStoreSetDispatchQueue(hn_store, NULL);
+                                       CFRelease(hn_store);
+                                       hn_store = NULL;
+                                       _SCErrorSet(kSCStatusFailed);
+                                       return;
+                               }
+
+                               if (!nwi_refresh_enable(_hn_changes_queue(),
+                                                       hn_store,
+                                                       __SCNetworkReachabilityHandleChanges)) {
+                                       // if error
+                                       dns_configuration_unwatch();
+#ifdef USE_DNSSERVICEGETADDRINFO
+                                       dns_refresh_disable();
+#endif // USE_DNSSERVICEGETADDRINFO
+                                       onDemand_refresh_disable();
+                                       SCDynamicStoreSetDispatchQueue(hn_store, NULL);
+                                       CFRelease(hn_store);
+                                       hn_store = NULL;
+                                       _SCErrorSet(kSCStatusFailed);
+                                       return;
+                               }
+                       }
+
+
                        hn_targets = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
                        ReachabilityStoreInfo_enable(TRUE);
                        hn_targets = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
                        ReachabilityStoreInfo_enable(TRUE);
@@ -6019,20 +6403,29 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef     target,
                         * are starting with a clean slate before we
                         * resolve the name
                         */
                         * are starting with a clean slate before we
                         * resolve the name
                         */
-                       if (targetPrivate->resolvedAddress != NULL) {
-                               CFRelease(targetPrivate->resolvedAddress);
-                               targetPrivate->resolvedAddress = NULL;
+                       if (targetPrivate->resolvedAddresses != NULL) {
+                               CFRelease(targetPrivate->resolvedAddresses);
+                               targetPrivate->resolvedAddresses = NULL;
                        }
                        }
-                       targetPrivate->resolvedAddressError = NETDB_SUCCESS;
+                       targetPrivate->resolvedError = NETDB_SUCCESS;
                        targetPrivate->needResolve = TRUE;
                        targetPrivate->needResolve = TRUE;
-                       _reach_set(&targetPrivate->info, &NOT_REACHABLE, targetPrivate->info.cycle);
+                       _reach_set(&targetPrivate->info,
+                                  &NOT_REACHABLE,
+                                  targetPrivate->info.cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
                        targetPrivate->info.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #ifdef HAVE_REACHABILITY_SERVER
                        targetPrivate->info.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #ifdef HAVE_REACHABILITY_SERVER
-                       _reach_set(&targetPrivate->serverInfo, &NOT_REACHABLE, targetPrivate->serverInfo.cycle);
+                       _reach_set(&targetPrivate->serverInfo,
+                                  &NOT_REACHABLE,
+                                  targetPrivate->serverInfo.cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
                        targetPrivate->serverInfo.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #endif // HAVE_REACHABILITY_SERVER
                }
 
                        targetPrivate->serverInfo.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 #endif // HAVE_REACHABILITY_SERVER
                }
 
+
                targetPrivate->scheduled = TRUE;
 
                init = TRUE;
                targetPrivate->scheduled = TRUE;
 
                init = TRUE;
@@ -6095,13 +6488,25 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef     target,
 #ifdef HAVE_REACHABILITY_SERVER
                        reach_info.flags |= (targetPrivate->info.flags & kSCNetworkReachabilityFlagsFirstResolvePending);
 #endif // HAVE_REACHABILITY_SERVER
 #ifdef HAVE_REACHABILITY_SERVER
                        reach_info.flags |= (targetPrivate->info.flags & kSCNetworkReachabilityFlagsFirstResolvePending);
 #endif // HAVE_REACHABILITY_SERVER
-                       _reach_set(&targetPrivate->info, &reach_info, targetPrivate->cycle);
-                       __SCNetworkReachabilityPerform(target);
+                       _reach_set(&targetPrivate->info,
+                                  &reach_info,
+                                  targetPrivate->cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
+                       __SCNetworkReachabilityPerformLocked(target);
                } else {
                        /* if reachability status not available, async lookup started */
                } else {
                        /* if reachability status not available, async lookup started */
-                       _reach_set(&targetPrivate->info, &NOT_REACHABLE, targetPrivate->cycle);
+                       _reach_set(&targetPrivate->info,
+                                  &NOT_REACHABLE,
+                                  targetPrivate->cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
 #ifdef HAVE_REACHABILITY_SERVER
 #ifdef HAVE_REACHABILITY_SERVER
-                       _reach_set(&targetPrivate->serverInfo, &NOT_REACHABLE, targetPrivate->cycle);
+                       _reach_set(&targetPrivate->serverInfo,
+                                  &NOT_REACHABLE,
+                                  targetPrivate->cycle,
+                                  targetPrivate->if_index,
+                                  targetPrivate->if_name);
 #endif // HAVE_REACHABILITY_SERVER
                }
                ReachabilityStoreInfo_free(&store_info);
 #endif // HAVE_REACHABILITY_SERVER
                }
                ReachabilityStoreInfo_free(&store_info);
@@ -6155,6 +6560,7 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef     target,
        // unschedule the target specific sources
        if (targetPrivate->dispatchQueue != NULL) {
                if (targetPrivate->onDemandServer != NULL) {
        // unschedule the target specific sources
        if (targetPrivate->dispatchQueue != NULL) {
                if (targetPrivate->onDemandServer != NULL) {
+                       SCNetworkReachabilitySetCallback(targetPrivate->onDemandServer, NULL, NULL);
                        __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE);
                }
 
                        __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE);
                }
 
@@ -6186,6 +6592,9 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef     target,
 
                        if (n == 0) {
                                // if *all* notifications have been unscheduled
 
                        if (n == 0) {
                                // if *all* notifications have been unscheduled
+                               if (targetPrivate->onDemandServer != NULL) {
+                                       SCNetworkReachabilitySetCallback(targetPrivate->onDemandServer, NULL, NULL);
+                               }
                                CFRelease(targetPrivate->rlList);
                                targetPrivate->rlList = NULL;
                                CFRunLoopSourceInvalidate(targetPrivate->rls);
                                CFRelease(targetPrivate->rlList);
                                targetPrivate->rlList = NULL;
                                CFRunLoopSourceInvalidate(targetPrivate->rls);
@@ -6201,6 +6610,7 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef     target,
                // Cancel our request for server monitoring
                //
                if (targetPrivate->serverActive) {
                // Cancel our request for server monitoring
                //
                if (targetPrivate->serverActive) {
+
                        ok = __SCNetworkReachabilityServer_targetUnschedule(target);
                        if (!ok) {
                                SCLog(TRUE, LOG_DEBUG,
                        ok = __SCNetworkReachabilityServer_targetUnschedule(target);
                        if (!ok) {
                                SCLog(TRUE, LOG_DEBUG,
@@ -6221,22 +6631,17 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef   target,
 #endif // HAVE_REACHABILITY_SERVER
 
        if (n == 0) {
 #endif // HAVE_REACHABILITY_SERVER
 
        if (n == 0) {
-               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
-                       // if we have an active async DNS query
-                       dequeueAsyncDNSQuery(target, TRUE);
+               if (targetPrivate->dnsActive) {
+                       // if we have an active [m]DNS query
+                       dequeueDNSQuery(target);
                }
 
                }
 
-               if (targetPrivate->dnsRetry != NULL) {
-                       // if we have an outstanding DNS retry
-                       dequeueAsyncDNSRetry(target);
-               }
-
-               if (targetPrivate->llqActive) {
-                       // if we have a long-lived-query
-                       dequeueLongLivedQuery(target);
+               if (targetPrivate->dnsMP != MACH_PORT_NULL) {
+                       // if we have an active [async] DNS query
+                       dequeueAsyncDNSQuery(target, TRUE);
                }
 
                }
 
-               dispatch_sync(_hn_queue(), ^{
+               dispatch_sync(_hn_target_queue(), ^{
                        CFSetRemoveValue(hn_targets, target);
 
                        if (onDemand) {
                        CFSetRemoveValue(hn_targets, target);
 
                        if (onDemand) {
@@ -6249,8 +6654,6 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef     target,
 
                        // if we are no longer monitoring any targets
                        SCDynamicStoreSetDispatchQueue(hn_store, NULL);
 
                        // if we are no longer monitoring any targets
                        SCDynamicStoreSetDispatchQueue(hn_store, NULL);
-                       dispatch_release(hn_dispatchQueue);
-                       hn_dispatchQueue = NULL;
                        CFRelease(hn_store);
                        hn_store = NULL;
                        CFRelease(hn_targets);
                        CFRelease(hn_store);
                        hn_store = NULL;
                        CFRelease(hn_targets);
@@ -6259,6 +6662,32 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef    target,
                        ReachabilityStoreInfo_enable(FALSE);
                        ReachabilityStoreInfo_save(NULL);
 
                        ReachabilityStoreInfo_enable(FALSE);
                        ReachabilityStoreInfo_save(NULL);
 
+
+                       if (!D_nwiBypass) {
+                               /*
+                                * until we start monitoring again, ensure that
+                                * any resources associated with tracking the
+                                * network changes (nwi) have been released.
+                                */
+                               nwi_refresh_disable();
+
+                               /*
+                                * until we start monitoring again, ensure that
+                                * any resources associated with tracking the
+                                * OnDemand configuration have been released.
+                                */
+                               onDemand_refresh_disable();
+                       }
+
+#ifdef USE_DNSSERVICEGETADDRINFO
+                       /*
+                        * until we start monitoring again, ensure that
+                        * any resources associated with restarting
+                        * [m]DNS queries have been released.
+                        */
+                       dns_refresh_disable();
+#endif // USE_DNSSERVICEGETADDRINFO
+
                        /*
                         * until we start monitoring again, ensure that
                         * any resources associated with tracking the
                        /*
                         * until we start monitoring again, ensure that
                         * any resources associated with tracking the
index f0caeaa96b9a86f0cd26b8bd78b341d4330769be..69ad3af5685c2020e7436f161757629daade55fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -30,6 +30,7 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
 #include <dispatch/dispatch.h>
 
 #include <dns_sd.h>
 #include <dispatch/dispatch.h>
 
 #include <dns_sd.h>
 #include <sys/socket.h>
 #include <net/if.h>
 
 #include <sys/socket.h>
 #include <net/if.h>
 
-#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))
 #define        HAVE_REACHABILITY_SERVER
 #include <xpc/xpc.h>
 #define        HAVE_REACHABILITY_SERVER
 #include <xpc/xpc.h>
-#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) && !TARGET_IPHONE_SIMULATOR
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
+#define        HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
+#define        HAVE_IPSEC_STATUS
+#define        HAVE_VPN_STATUS
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
+
+
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+#define USE_DNSSERVICEGETADDRINFO
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
 
 
 #pragma mark -
 
 
 #pragma mark -
 #define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
 
 
 #define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
 
 
-typedef        enum { NO = 0, YES, UNKNOWN }   lazyBoolean;
+
+#define kSCNetworkReachabilityFlagsMask                        0x00ffffff      // top 8-bits reserved for implementation
+
+
+typedef        enum {
+       NO      = 0,
+       YES,
+       UNKNOWN
+} lazyBoolean;
 
 
 typedef enum {
 
 
 typedef enum {
@@ -82,11 +106,10 @@ typedef struct {
 
        /* target host name */
        const char                      *name;
 
        /* target host name */
        const char                      *name;
-       const char                      *serv;
-       struct addrinfo                 hints;
        Boolean                         needResolve;
        Boolean                         needResolve;
-       CFArrayRef                      resolvedAddress;        /* CFArray[CFData] */
-       int                             resolvedAddressError;
+       CFArrayRef                      resolvedAddresses;      /* CFArray[CFData] */
+       int                             resolvedError;
+       SCNetworkReachabilityFlags      resolverFlags;
 
        /* [scoped routing] interface constraints */
        unsigned int                    if_index;
 
        /* [scoped routing] interface constraints */
        unsigned int                    if_index;
@@ -119,8 +142,6 @@ typedef struct {
        dispatch_source_t               dnsSource;              // for dispatch queries
        struct timeval                  dnsQueryStart;
        struct timeval                  dnsQueryEnd;
        dispatch_source_t               dnsSource;              // for dispatch queries
        struct timeval                  dnsQueryStart;
        struct timeval                  dnsQueryEnd;
-       dispatch_source_t               dnsRetry;               // != NULL if DNS retry request queued
-       int                             dnsRetryCount;          // number of retry attempts
 
        /* [async] processing info */
        struct timeval                  last_dns;
 
        /* [async] processing info */
        struct timeval                  last_dns;
@@ -138,10 +159,22 @@ typedef struct {
        CFStringRef                     onDemandServiceID;
 
 
        CFStringRef                     onDemandServiceID;
 
 
-       Boolean                         llqActive;
-       Boolean                         llqBypass;
-       DNSServiceRef                   llqTarget;
-       dispatch_source_t               llqTimer;               // != NULL while waiting for first callback
+       union {
+               uint32_t                dnsFlags;
+               struct {
+                       Boolean         dnsActive     :1;       // if DNSServiceGetAddrInfo active
+
+                       Boolean         dnsHaveError  :1;       // error during query
+                       Boolean         dnsHaveV4     :1;       // have IPv4 (A) reply
+                       Boolean         dnsHaveV6     :1;       // have IPv6 (AAAA) reply
+                       Boolean         dnsHaveTimeout:1;       // no replies (A and/or AAAA)
+               };
+       };
+       CFArrayRef                      dnsAddresses;           // CFArray[CFData]
+       Boolean                         dnsBlocked;             // if DNS query blocked
+       int                             dnsError;
+       DNSServiceRef                   dnsMain;
+       DNSServiceRef                   dnsTarget;
 
 #ifdef HAVE_REACHABILITY_SERVER
        /* SCNetworkReachability server "client" info */
 
 #ifdef HAVE_REACHABILITY_SERVER
        /* SCNetworkReachability server "client" info */
@@ -154,13 +187,17 @@ typedef struct {
        CFDataRef                       serverDigest;
        dispatch_group_t                serverGroup;
        Boolean                         serverInfoValid;
        CFDataRef                       serverDigest;
        dispatch_group_t                serverGroup;
        Boolean                         serverInfoValid;
-       unsigned int                    serverQueryActive;      // 0 == no query active, else # waiting on group
+       unsigned int                    serverSyncQueryActive;  // 0 == no [sync] query active, else # waiting on group
        dispatch_queue_t                serverQueue;
        unsigned int                    serverReferences;       // how many [client] targets
        CFMutableDictionaryRef          serverWatchers;         // [client_id/target_id] watchers
        dispatch_queue_t                serverQueue;
        unsigned int                    serverReferences;       // how many [client] targets
        CFMutableDictionaryRef          serverWatchers;         // [client_id/target_id] watchers
+
+       Boolean                         useVPNAppLayer;         // if App-Layer VPN, only use client mode
 #endif // HAVE_REACHABILITY_SERVER
        Boolean                         resolverBypass;         // set this flag to bypass resolving the name
 
 #endif // HAVE_REACHABILITY_SERVER
        Boolean                         resolverBypass;         // set this flag to bypass resolving the name
 
+
+
        /* logging */
        char                            log_prefix[32];
 
        /* logging */
        char                            log_prefix[32];
 
@@ -176,7 +213,12 @@ typedef struct {
 
 
 #define        REACH_SERVER_VERSION            20110323
 
 
 #define        REACH_SERVER_VERSION            20110323
+
+#if    !TARGET_IPHONE_SIMULATOR
 #define        REACH_SERVICE_NAME              "com.apple.SystemConfiguration.SCNetworkReachability"
 #define        REACH_SERVICE_NAME              "com.apple.SystemConfiguration.SCNetworkReachability"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define        REACH_SERVICE_NAME              "com.apple.SystemConfiguration.SCNetworkReachability_sim"
+#endif // !TARGET_IPHONE_SIMULATOR
 
 // ------------------------------------------------------------
 
 
 // ------------------------------------------------------------
 
@@ -200,14 +242,12 @@ enum {
 };
 
 #define        REACH_TARGET_NAME               "name"                  // string
 };
 
 #define        REACH_TARGET_NAME               "name"                  // string
-#define        REACH_TARGET_SERV               "serv"                  // string
-#define        REACH_TARGET_HINTS              "hints"                 // data (struct addrinfo)
 #define        REACH_TARGET_IF_INDEX           "if_index"              // int64
 #define        REACH_TARGET_IF_NAME            "if_name"               // string
 #define        REACH_TARGET_IF_INDEX           "if_index"              // int64
 #define        REACH_TARGET_IF_NAME            "if_name"               // string
-#define        REACH_TARGET_LOCAL_ADDR         "localAddress"          // data (struct sockaddr)
-#define        REACH_TARGET_REMOTE_ADDR        "remoteAddress"         // data (struct sockaddr)
-#define        REACH_TARGET_ONDEMAND_BYPASS    "onDemandBypass"        // bool
-#define REACH_TARGET_RESOLVER_BYPASS   "resolverBypass"        // bool
+#define        REACH_TARGET_LOCAL_ADDR         "local_address"         // data (struct sockaddr)
+#define        REACH_TARGET_REMOTE_ADDR        "remote_address"        // data (struct sockaddr)
+#define        REACH_TARGET_ONDEMAND_BYPASS    "ondemand_bypass"       // bool
+#define REACH_TARGET_RESOLVER_BYPASS   "resolver_bypass"       // bool
 
 
 #define REACH_REQUEST_REPLY            "reply"                 // int64
 
 
 #define REACH_REQUEST_REPLY            "reply"                 // int64
@@ -233,13 +273,13 @@ enum {
        MESSAGE_REACHABILITY_STATUS     = 0x1001,
 };
 
        MESSAGE_REACHABILITY_STATUS     = 0x1001,
 };
 
-#define REACH_STATUS_CYCLE                     "cycle"                 // uint64
-#define REACH_STATUS_FLAGS                     "flags"                 // uint64
-#define REACH_STATUS_IF_INDEX                  "if_index"              // uint64
-#define REACH_STATUS_IF_NAME                   "if_name"               // data (char if_name[IFNAMSIZ])
-#define REACH_STATUS_RESOLVED_ADDRESS          "resolvedAddress"       // array[data]
-#define REACH_STATUS_RESOLVED_ADDRESS_ERROR    "resolvedAddressError"  // int64
-#define REACH_STATUS_SLEEPING                  "sleeping"              // bool
+#define REACH_STATUS_CYCLE             "cycle"                 // uint64
+#define REACH_STATUS_FLAGS             "flags"                 // uint64
+#define REACH_STATUS_IF_INDEX          "if_index"              // uint64
+#define REACH_STATUS_IF_NAME           "if_name"               // data (char if_name[IFNAMSIZ])
+#define REACH_STATUS_RESOLVED_ADDRESSES        "resolved_addresses"    // array[data]
+#define REACH_STATUS_RESOLVED_ERROR    "resolved_error"        // int64
+#define REACH_STATUS_SLEEPING          "sleeping"              // bool
 
 
 // ------------------------------------------------------------
 
 
 // ------------------------------------------------------------
@@ -255,14 +295,17 @@ _SCNetworkReachabilityCopyTargetDescription       (SCNetworkReachabilityRef       target);
 CFStringRef
 _SCNetworkReachabilityCopyTargetFlags          (SCNetworkReachabilityRef       target);
 
 CFStringRef
 _SCNetworkReachabilityCopyTargetFlags          (SCNetworkReachabilityRef       target);
 
+void
+__SCNetworkReachabilityPerform                 (SCNetworkReachabilityRef       target);
+
+void
+__SCNetworkReachabilityPerformConcurrent       (SCNetworkReachabilityRef       target);
+
 #ifdef HAVE_REACHABILITY_SERVER
 
 dispatch_queue_t
 __SCNetworkReachability_concurrent_queue       (void);
 
 #ifdef HAVE_REACHABILITY_SERVER
 
 dispatch_queue_t
 __SCNetworkReachability_concurrent_queue       (void);
 
-void
-__SCNetworkReachabilityPerformNoLock           (SCNetworkReachabilityRef       target);
-
 #pragma mark -
 #pragma mark [XPC] Reachability Server (client APIs)
 
 #pragma mark -
 #pragma mark [XPC] Reachability Server (client APIs)
 
@@ -284,17 +327,79 @@ __SCNetworkReachabilityServer_targetStatus        (SCNetworkReachabilityRef       target);
 Boolean
 __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef       target);
 
 Boolean
 __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef       target);
 
+
 Boolean
 __SC_checkResolverReachabilityInternal         (SCDynamicStoreRef              *storeP,
                                                 SCNetworkReachabilityFlags     *flags,
                                                 Boolean                        *haveDNS,
                                                 const char                     *nodename,
 Boolean
 __SC_checkResolverReachabilityInternal         (SCDynamicStoreRef              *storeP,
                                                 SCNetworkReachabilityFlags     *flags,
                                                 Boolean                        *haveDNS,
                                                 const char                     *nodename,
-                                                const char                     *servname,
                                                 uint32_t                       *resolver_if_index,
                                                 int                            *dns_config_index);
 
 #endif // HAVE_REACHABILITY_SERVER
 
                                                 uint32_t                       *resolver_if_index,
                                                 int                            *dns_config_index);
 
 #endif // HAVE_REACHABILITY_SERVER
 
+static __inline__ void
+__SCNetworkReachabilityPrintFlags(SCNetworkReachabilityFlags flags)
+{
+       if (flags != 0) {
+               if (flags & kSCNetworkReachabilityFlagsReachable) {
+                       SCPrint(TRUE, stdout, CFSTR("Reachable"));
+                       flags &= ~kSCNetworkReachabilityFlagsReachable;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
+                       SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
+                       flags &= ~kSCNetworkReachabilityFlagsTransientConnection;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
+                       SCPrint(TRUE, stdout, CFSTR("Connection Required"));
+                       flags &= ~kSCNetworkReachabilityFlagsConnectionRequired;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
+                       SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Traffic"));
+                       flags &= ~kSCNetworkReachabilityFlagsConnectionOnTraffic;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
+                       SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Demand"));
+                       flags &= ~kSCNetworkReachabilityFlagsConnectionOnDemand;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
+                       SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
+                       flags &= ~kSCNetworkReachabilityFlagsInterventionRequired;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
+                       SCPrint(TRUE, stdout, CFSTR("Local Address"));
+                       flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkReachabilityFlagsIsDirect) {
+                       SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
+                       flags &= ~kSCNetworkReachabilityFlagsIsDirect;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+#if    TARGET_OS_IPHONE
+               if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
+                       SCPrint(TRUE, stdout, CFSTR("WWAN"));
+                       flags &= ~kSCNetworkReachabilityFlagsIsWWAN;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+#endif // TARGET_OS_IPHONE
+               if (flags != 0) {
+                       SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
+               }
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
+       }
+
+       return;
+}
+
+
 __END_DECLS
 
 #endif // _SCNETWORKREACHABILITYINTERNAL_H
 __END_DECLS
 
 #endif // _SCNETWORKREACHABILITYINTERNAL_H
index 1d85e4348fd484fbf2dcdc4e96817872175438a5..5a19657584f3eae3bfa6d9291bc3350ff52f0dce 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -38,6 +38,7 @@
 
 #include <pthread.h>
 
 
 #include <pthread.h>
 
+#define EXTERNAL_ID_DOMAIN_PREFIX      "_"
 
 static CFStringRef     __SCNetworkServiceCopyDescription       (CFTypeRef cf);
 static void            __SCNetworkServiceDeallocate            (CFTypeRef cf);
 
 static CFStringRef     __SCNetworkServiceCopyDescription       (CFTypeRef cf);
 static void            __SCNetworkServiceDeallocate            (CFTypeRef cf);
@@ -100,6 +101,7 @@ __SCNetworkServiceDeallocate(CFTypeRef cf)
        if (servicePrivate->prefs != NULL) CFRelease(servicePrivate->prefs);
        if (servicePrivate->store != NULL) CFRelease(servicePrivate->store);
        if (servicePrivate->name != NULL) CFRelease(servicePrivate->name);
        if (servicePrivate->prefs != NULL) CFRelease(servicePrivate->prefs);
        if (servicePrivate->store != NULL) CFRelease(servicePrivate->store);
        if (servicePrivate->name != NULL) CFRelease(servicePrivate->name);
+       if (servicePrivate->externalIDs != NULL) CFRelease(servicePrivate->externalIDs);
 
        return;
 }
 
        return;
 }
@@ -332,7 +334,7 @@ __SCNetworkServiceNextName(SCNetworkServiceRef service)
                }
        }
 
                }
        }
 
-       name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), suffix);
+       name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), (int)suffix);
        CFArrayAppendValue(newComponents, name);
        CFRelease(name);
 
        CFArrayAppendValue(newComponents, name);
        CFRelease(name);
 
@@ -452,6 +454,8 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
        }
 
        protocol  = SCNetworkServiceCopyProtocol(service, protocolType);
        }
 
        protocol  = SCNetworkServiceCopyProtocol(service, protocolType);
+       assert(protocol != NULL);
+
        newEntity = _protocolTemplate(service, protocolType);
        ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
        CFRelease(newEntity);
        newEntity = _protocolTemplate(service, protocolType);
        ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
        CFRelease(newEntity);
@@ -519,6 +523,7 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs)
                        }
 
                        servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, keys[i], NULL);
                        }
 
                        servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, keys[i], NULL);
+                       assert(servicePrivate != NULL);
                        CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
                        CFRelease(servicePrivate);
                }
                        CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate);
                        CFRelease(servicePrivate);
                }
@@ -620,6 +625,7 @@ _SCNetworkServiceCopyActive(SCDynamicStoreRef store, CFStringRef serviceID)
        }
 
        servicePrivate = __SCNetworkServiceCreatePrivate(NULL, NULL, serviceID, NULL);
        }
 
        servicePrivate = __SCNetworkServiceCreatePrivate(NULL, NULL, serviceID, NULL);
+       assert(servicePrivate != NULL);
        if (store != NULL) {
                servicePrivate->store = CFRetain(store);
        }
        if (store != NULL) {
                servicePrivate->store = CFRetain(store);
        }
@@ -1130,7 +1136,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
                                                CFRetain(interface_name);
                                        }
                                        break;
                                                CFRetain(interface_name);
                                        }
                                        break;
-#if    !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#if    !TARGET_OS_IPHONE
                                case 1 :
                                        // compare the older "Built-in XXX" localized name
                                        interface_name = __SCNetworkInterfaceCopyXLocalizedDisplayName(interface);
                                case 1 :
                                        // compare the older "Built-in XXX" localized name
                                        interface_name = __SCNetworkInterfaceCopyXLocalizedDisplayName(interface);
@@ -1139,7 +1145,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
                                        // compare the older "Built-in XXX" non-localized name
                                        interface_name = __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface);
                                        break;
                                        // compare the older "Built-in XXX" non-localized name
                                        interface_name = __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface);
                                        break;
-#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#endif // !TARGET_OS_IPHONE
                                default :
                                        continue;
                        }
                                default :
                                        continue;
                        }
@@ -1709,3 +1715,130 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service)
        return FALSE;
 }
 
        return FALSE;
 }
 
+
+Boolean
+SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain, CFStringRef identifier)
+{
+       CFStringRef                                     prefs_path;
+       CFDictionaryRef                         service_dictionary;
+       SCNetworkServicePrivateRef      service_private         = (SCNetworkServicePrivateRef)service;
+       Boolean                                         success                         = FALSE;
+       CFStringRef                                     prefixed_domain;
+
+       if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (identifier != NULL && !isA_CFString(identifier)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       prefixed_domain = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX, identifierDomain);
+
+       prefs_path = SCPreferencesPathKeyCreateNetworkServiceEntity(kCFAllocatorDefault,
+                                                                   service_private->serviceID,
+                                                                   NULL);
+
+       service_dictionary = SCPreferencesPathGetValue(service_private->prefs, prefs_path);
+       if (isA_CFDictionary(service_dictionary) || ((service_dictionary == NULL) && (identifier != NULL))) {
+               CFMutableDictionaryRef  new_service_dictionary;
+
+               if (service_dictionary != NULL) {
+                       new_service_dictionary = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, service_dictionary);
+               } else {
+                       new_service_dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                          0,
+                                                                          &kCFTypeDictionaryKeyCallBacks,
+                                                                          &kCFTypeDictionaryValueCallBacks);
+               }
+
+               if (identifier != NULL) {
+                       CFDictionarySetValue(new_service_dictionary, prefixed_domain, identifier);
+               } else {
+                       CFDictionaryRemoveValue(new_service_dictionary, prefixed_domain);
+               }
+               success = SCPreferencesPathSetValue(service_private->prefs, prefs_path, new_service_dictionary);
+               CFRelease(new_service_dictionary);
+       }
+       CFRelease(prefs_path);
+
+       if (identifier != NULL) {
+           if (service_private->externalIDs == NULL) {
+                       service_private->externalIDs = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                                0,
+                                                                                                                                        &kCFTypeDictionaryKeyCallBacks,
+                                                                                                                                        &kCFTypeDictionaryValueCallBacks);
+           }
+           CFDictionarySetValue(service_private->externalIDs, prefixed_domain, identifier);
+       } else {
+           if (service_private->externalIDs != NULL) {
+                       CFDictionaryRemoveValue(service_private->externalIDs, prefixed_domain);
+           }
+       }
+
+       CFRelease(prefixed_domain);
+
+       if (!success) {
+               _SCErrorSet(kSCStatusFailed);
+       }
+
+       return success;
+}
+
+
+CFStringRef
+SCNetworkServiceCopyExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain)
+{
+       SCNetworkServicePrivateRef      service_private         = (SCNetworkServicePrivateRef)service;
+       CFStringRef                                     identifier                      = NULL;
+       CFStringRef                                     prefixed_domain;
+
+       if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       prefixed_domain = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX, identifierDomain);
+
+       if (service_private->externalIDs != NULL) {
+               identifier = CFDictionaryGetValue(service_private->externalIDs, prefixed_domain);
+               if (identifier != NULL) {
+                       CFRetain(identifier);
+               }
+       }
+
+       if (identifier == NULL) {
+               CFStringRef                     prefs_path;
+               CFDictionaryRef         service_dictionary;
+
+               prefs_path = SCPreferencesPathKeyCreateNetworkServiceEntity(kCFAllocatorDefault,
+                                                                           service_private->serviceID,
+                                                                           NULL);
+
+               service_dictionary = SCPreferencesPathGetValue(service_private->prefs, prefs_path);
+               if (isA_CFDictionary(service_dictionary)) {
+                       identifier = CFDictionaryGetValue(service_dictionary, prefixed_domain);
+                       if (identifier != NULL) {
+                               CFRetain(identifier);
+                               if (service_private->externalIDs == NULL) {
+                                       service_private->externalIDs = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                                                0,
+                                                                                                &kCFTypeDictionaryKeyCallBacks,
+                                                                                                &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(service_private->externalIDs, prefixed_domain, identifier);
+                       }
+               }
+               CFRelease(prefs_path);
+       }
+
+       CFRelease(prefixed_domain);
+
+       if (identifier == NULL) {
+               _SCErrorSet(kSCStatusNoKey);
+       }
+
+       return identifier;
+}
index 126300fe820bea67e1ac3a1ee4f036a62b85dda8..41dd8d26b8365d4a3ed3cada65b8260c31ea9c9b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2007, 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -201,6 +201,7 @@ _serviceOrder_add(SCNetworkSetRef set, SCNetworkServiceRef service)
        } else {
                newOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
        } else {
                newOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        }
+       assert(newOrder != NULL);
        n = CFArrayGetCount(newOrder);
 
        serviceID = SCNetworkServiceGetServiceID(service);
        n = CFArrayGetCount(newOrder);
 
        serviceID = SCNetworkServiceGetServiceID(service);
@@ -450,6 +451,7 @@ SCNetworkSetCopy(SCPreferencesRef prefs, CFStringRef setID)
        }
 
        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
        }
 
        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
+       assert(setPrivate != NULL);
 
        // mark set as "old" (already established)
        setPrivate->established = TRUE;
 
        // mark set as "old" (already established)
        setPrivate->established = TRUE;
@@ -517,6 +519,7 @@ SCNetworkSetCopyAll(SCPreferencesRef prefs)
                        }
 
                        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, keys[i]);
                        }
 
                        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, keys[i]);
+                       assert(setPrivate != NULL);
 
                        // mark set as "old" (already established)
                        setPrivate->established = TRUE;
 
                        // mark set as "old" (already established)
                        setPrivate->established = TRUE;
@@ -534,6 +537,80 @@ SCNetworkSetCopyAll(SCPreferencesRef prefs)
 }
 
 
 }
 
 
+CFArrayRef /* of SCNetworkInterfaceRef's */
+SCNetworkSetCopyAvailableInterfaces(SCNetworkSetRef set)
+{
+       CFMutableArrayRef       available;
+       CFMutableSetRef         excluded        = NULL;
+       int                     i;
+       CFArrayRef              interfaces;
+       int                     n_interfaces;
+       int                     n_exclusions    = 0;
+       SCPreferencesRef        prefs;
+       SCNetworkSetPrivateRef  setPrivate;
+
+       setPrivate = (SCNetworkSetPrivateRef)set;
+       prefs = setPrivate->prefs;
+
+       interfaces = _SCNetworkInterfaceCopyAllWithPreferences(prefs);
+       n_interfaces = CFArrayGetCount(interfaces);
+       if (n_interfaces == 0) {
+               return interfaces;
+       }
+
+       if (prefs != NULL) {
+               CFArrayRef      bridges = NULL;
+
+               excluded = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+
+#if    !TARGET_OS_IPHONE
+               CFArrayRef      bonds   = NULL;
+
+               bonds = SCBondInterfaceCopyAll(prefs);
+               if (bonds != NULL) {
+                       __SCBondInterfaceListCollectMembers(bonds, excluded);
+                       CFRelease(bonds);
+               }
+#endif /* !TARGET_OS_IPHONE */
+
+               bridges = SCBridgeInterfaceCopyAll(prefs);
+               if (bridges != NULL) {
+                       __SCBridgeInterfaceListCollectMembers(bridges, excluded);
+                       CFRelease(bridges);
+               }
+
+               n_exclusions = CFSetGetCount(excluded);
+       }
+
+       if (n_exclusions == 0) {
+               if (excluded != NULL) {
+                       CFRelease(excluded);
+               }
+
+               return interfaces;
+       }
+
+       available = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       for (i = 0; i < n_interfaces; i++) {
+               SCNetworkInterfaceRef   interface;
+
+               interface = CFArrayGetValueAtIndex(interfaces, i);
+               if (CFSetContainsValue(excluded, interface)) {
+                       // if excluded
+                       continue;
+               }
+
+               CFArrayAppendValue(available, interface);
+       }
+
+       CFRelease(interfaces);
+       CFRelease(excluded);
+
+       return available;
+}
+
+
 SCNetworkSetRef
 SCNetworkSetCopyCurrent(SCPreferencesRef prefs)
 {
 SCNetworkSetRef
 SCNetworkSetCopyCurrent(SCPreferencesRef prefs)
 {
@@ -555,6 +632,7 @@ SCNetworkSetCopyCurrent(SCPreferencesRef prefs)
                path = SCPreferencesPathKeyCreateSet(NULL, setID);
                if (CFEqual(path, currentID)) {
                        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
                path = SCPreferencesPathKeyCreateSet(NULL, setID);
                if (CFEqual(path, currentID)) {
                        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
+                       assert(setPrivate != NULL);
 
                        // mark set as "old" (already established)
                        setPrivate->established = TRUE;
 
                        // mark set as "old" (already established)
                        setPrivate->established = TRUE;
@@ -674,6 +752,7 @@ SCNetworkSetCreate(SCPreferencesRef prefs)
        components = CFStringCreateArrayBySeparatingStrings(NULL, path, CFSTR("/"));
        setID = CFArrayGetValueAtIndex(components, 2);
        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
        components = CFStringCreateArrayBySeparatingStrings(NULL, path, CFSTR("/"));
        setID = CFArrayGetValueAtIndex(components, 2);
        setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID);
+       assert(setPrivate != NULL);
        CFRelease(components);
 
        // mark set as "new" (not yet established)
        CFRelease(components);
 
        // mark set as "new" (not yet established)
@@ -1130,6 +1209,7 @@ add_supported_interfaces(CFMutableArrayRef interface_list, SCNetworkInterfaceRef
        return;
 }
 
        return;
 }
 
+
 static CFSetRef        /* of SCNetworkInterfaceRef's */
 copyExcludedInterfaces(SCPreferencesRef prefs)
 {
 static CFSetRef        /* of SCNetworkInterfaceRef's */
 copyExcludedInterfaces(SCPreferencesRef prefs)
 {
@@ -1158,6 +1238,137 @@ copyExcludedInterfaces(SCPreferencesRef prefs)
 }
 
 
 }
 
 
+#if    !TARGET_OS_IPHONE
+static SCBridgeInterfaceRef
+copyAutoBridgeInterface(SCPreferencesRef prefs, CFStringRef bridgeName)
+{
+       SCBridgeInterfaceRef    bridge          = NULL;
+       CFArrayRef              interfaces;
+
+       // exclude Bridge [member] interfaces
+       interfaces = SCBridgeInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               CFIndex         i;
+               CFIndex         n;
+
+               n = CFArrayGetCount(interfaces);
+               for (i = 0; i < n; i++) {
+                       SCBridgeInterfaceRef    interface;
+                       CFStringRef             name    = NULL;
+                       CFDictionaryRef         options;
+
+                       interface = CFArrayGetValueAtIndex(interfaces, i);
+                       options = SCBridgeInterfaceGetOptions(interface);
+                       if ((options != NULL) &&
+                           CFDictionaryGetValueIfPresent(options,
+                                                         CFSTR("__AUTO__"),
+                                                         (const void **)&name) &&
+                           _SC_CFEqual(name, bridgeName)) {
+                               bridge = interface;
+                               CFRetain(bridge);
+                               break;
+                       }
+               }
+
+               CFRelease(interfaces);
+       }
+
+       if (bridge == NULL) {
+               bridge = SCBridgeInterfaceCreate(prefs);
+               if (bridge != NULL) {
+                       CFMutableDictionaryRef  newOptions;
+                       Boolean                 ok;
+
+                       newOptions = CFDictionaryCreateMutable(NULL, 0,
+                                                              &kCFTypeDictionaryKeyCallBacks,
+                                                              &kCFTypeDictionaryValueCallBacks);
+                       CFDictionarySetValue(newOptions, CFSTR("__AUTO__"), bridgeName);
+                       ok = SCBridgeInterfaceSetOptions(bridge, newOptions);
+                       CFRelease(newOptions);
+                       if (!ok) {
+                               CFRelease(bridge);
+                               bridge = NULL;
+                       }
+               }
+       }
+
+       return bridge;
+}
+#endif // !TARGET_OS_IPHONE
+
+
+static CFArrayRef
+copyServices(SCNetworkSetRef set)
+{
+       CFArrayRef              services;
+       SCNetworkSetPrivateRef  setPrivate      = (SCNetworkSetPrivateRef)set;
+
+       // first, assume that we only want to add new services
+       // for those interfaces that are not represented in the
+       // current set.
+       services = SCNetworkSetCopyServices(set);
+       if ((services != NULL) && setPrivate->established) {
+               // but, if we are given an existing (or "established") set
+               // than we only want to add new services for those interfaces
+               // that are not represented in *any* set.
+               CFRelease(services);
+               services = SCNetworkServiceCopyAll(setPrivate->prefs);
+       }
+
+       return services;
+}
+
+
+#if    !TARGET_OS_IPHONE
+static CFArrayRef
+updateServices(CFArrayRef services, SCNetworkInterfaceRef interface)
+{
+       CFStringRef             bsdName;
+       CFIndex                 i;
+       CFIndex                 n;
+       CFMutableArrayRef       newServices;
+
+       if (services == NULL) {
+               return NULL;
+       }
+
+       bsdName = SCNetworkInterfaceGetBSDName(interface);
+
+       newServices = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       n = CFArrayGetCount(services);
+       for (i = 0; i < n; i++) {
+               SCNetworkInterfaceRef           interface;
+               CFStringRef                     interfaceName;
+               SCNetworkServiceRef             newService;
+               SCNetworkServiceRef             service;
+               CFStringRef                     serviceID;
+               SCNetworkServicePrivateRef      servicePrivate;
+
+               service = CFArrayGetValueAtIndex(services, i);
+               interface = SCNetworkServiceGetInterface(service);
+               interfaceName = SCNetworkInterfaceGetBSDName(interface);
+               if (!_SC_CFEqual(interfaceName, bsdName)) {
+                       // if not a match, retain
+                       CFArrayAppendValue(newServices, service);
+                       continue;
+               }
+
+               // if a match, update
+               serviceID = SCNetworkServiceGetServiceID(service);
+               servicePrivate = (SCNetworkServicePrivateRef)service;
+               newService = SCNetworkServiceCopy(servicePrivate->prefs, serviceID);
+               if (newService != NULL) {
+                       CFArrayAppendValue(newServices, newService);
+                       CFRelease(newService);
+               }
+       }
+
+       return newServices;
+}
+#endif // !TARGET_OS_IPHONE
+
+
 static Boolean
 __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CFArrayRef interfaces)
 {
 static Boolean
 __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CFArrayRef interfaces)
 {
@@ -1168,6 +1379,7 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF
        CFArrayRef              services;
        SCNetworkSetPrivateRef  setPrivate      = (SCNetworkSetPrivateRef)set;
        Boolean                 updated         = FALSE;
        CFArrayRef              services;
        SCNetworkSetPrivateRef  setPrivate      = (SCNetworkSetPrivateRef)set;
        Boolean                 updated         = FALSE;
+       Boolean                 updatedIFs      = FALSE;
 
 #if    TARGET_OS_IPHONE
        CFArrayRef              orphans         = NULL;
 
 #if    TARGET_OS_IPHONE
        CFArrayRef              orphans         = NULL;
@@ -1193,20 +1405,103 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF
        }
 #endif // TARGET_OS_IPHONE
 
        }
 #endif // TARGET_OS_IPHONE
 
-       // first, assume that we only want to add new services
-       // for those interfaces that are not represented in the
-       // current set.
-       services = SCNetworkSetCopyServices(set);
-       if ((services != NULL) && setPrivate->established) {
-               // but, if we are given an existing (or "established") set
-               // than we only want to add new services for those interfaces
-               // that are not represented in *any* set.
-               CFRelease(services);
-               services = SCNetworkServiceCopyAll(setPrivate->prefs);
-       }
+       // copy network services
+       services = copyServices(set);
 
 
+       // copy network interfaces to be excluded
        excluded = copyExcludedInterfaces(setPrivate->prefs);
 
        excluded = copyExcludedInterfaces(setPrivate->prefs);
 
+#if    !TARGET_OS_IPHONE
+       // look for interfaces that should auto-magically be added
+       // to an Ethernet bridge
+       n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
+       for (i = 0; i < n; i++) {
+               SCBridgeInterfaceRef    bridge          = NULL;
+               SCNetworkInterfaceRef   interface;
+
+               interface = CFArrayGetValueAtIndex(interfaces, i);
+               if ((excluded != NULL)
+                   && CFSetContainsValue(excluded, interface)) {
+                       // if this interface is a member of a Bond or Bridge
+                       continue;
+               }
+
+               if (__SCNetworkServiceExistsForInterface(services, interface)) {
+                       // if this is not a new interface
+                       continue;
+               }
+
+               if (_SCNetworkInterfaceIsBuiltin(interface) &&
+                   _SCNetworkInterfaceIsThunderbolt(interface) &&
+                   !isA_SCBridgeInterface(interface)) {
+                       // add built-in Thunderbolt interfaces to bridge
+                       bridge = copyAutoBridgeInterface(setPrivate->prefs, CFSTR("thunderbolt-bridge"));
+               }
+
+               if (bridge != NULL) {
+                       CFIndex                 bridgeIndex;
+                       CFArrayRef              members;
+                       CFMutableArrayRef       newMembers;
+                       CFMutableSetRef         newExcluded;
+                       CFMutableArrayRef       newInterfaces;
+                       CFArrayRef              newServices;
+
+                       // track the bridge interface (if it's in our list)
+                       bridgeIndex = CFArrayGetFirstIndexOfValue(interfaces,
+                                                                 CFRangeMake(0, CFArrayGetCount(interfaces)),
+                                                                 bridge);
+
+                       // add new member interface
+                       members = SCBridgeInterfaceGetMemberInterfaces(bridge);
+                       if ((members != NULL) && (CFArrayGetCount(members) > 0)) {
+                               newMembers = CFArrayCreateMutableCopy(NULL, 0, members);
+                               updated = TRUE;         // if we're updating an existing bridge
+                       } else {
+                               newMembers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       }
+                       CFArrayAppendValue(newMembers, interface);
+                       ok = SCBridgeInterfaceSetMemberInterfaces(bridge, newMembers);
+                       CFRelease(newMembers);
+                       if (!ok) {
+                               SCLog(TRUE, LOG_DEBUG,
+                                     CFSTR("could not update bridge with \"%@\": %s\n"),
+                                     SCNetworkInterfaceGetLocalizedDisplayName(interface),
+                                     SCErrorString(SCError()));
+                               CFRelease(bridge);
+                               continue;
+                       }
+
+                       // exclude the new member interface
+                       newExcluded = CFSetCreateMutableCopy(NULL, 0, excluded);
+                       CFRelease(excluded);
+                       CFSetAddValue(newExcluded, interface);
+                       excluded = newExcluded;
+
+                       // update the list of interfaces to include the [new or updated] bridge
+                       newInterfaces = CFArrayCreateMutableCopy(NULL, 0, interfaces);
+                       if (bridgeIndex != kCFNotFound) {
+                               CFArraySetValueAtIndex(newInterfaces, bridgeIndex, bridge);
+                       } else {
+                               CFArrayAppendValue(newInterfaces, bridge);
+                       }
+                       if (updatedIFs) {
+                               CFRelease(interfaces);
+                       }
+                       interfaces = newInterfaces;
+                       updatedIFs = TRUE;
+
+                       // refresh [existing] services
+                       newServices = updateServices(services, bridge);
+                       if (newServices != NULL) {
+                               CFRelease(services);
+                               services = newServices;
+                       }
+
+                       CFRelease(bridge);
+               }
+       }
+#endif // !TARGET_OS_IPHONE
+
        n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
        for (i = 0; i < n; i++) {
                SCNetworkInterfaceRef   interface;
        n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
        for (i = 0; i < n; i++) {
                SCNetworkInterfaceRef   interface;
@@ -1318,6 +1613,7 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF
                }
                CFRelease(interface_list);
        }
                }
                CFRelease(interface_list);
        }
+       if (updatedIFs)         CFRelease(interfaces);
        if (services != NULL)   CFRelease(services);
        if (excluded != NULL)   CFRelease(excluded);
 
        if (services != NULL)   CFRelease(services);
        if (excluded != NULL)   CFRelease(excluded);
 
@@ -1392,6 +1688,7 @@ SCNetworkSetEstablishDefaultInterfaceConfiguration(SCNetworkSetRef set, SCNetwor
        }
 
        interfaces = CFArrayCreate(NULL, (const void **)&interface, 1, &kCFTypeArrayCallBacks);
        }
 
        interfaces = CFArrayCreate(NULL, (const void **)&interface, 1, &kCFTypeArrayCallBacks);
+       assert(interfaces != NULL);
        updated = __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set, interfaces);
        CFRelease(interfaces);
 
        updated = __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set, interfaces);
        CFRelease(interfaces);
 
index 2be8e9b079744504aa75ad033dcbd8454103ed71..0a86bc44807170e7ae95045cd101811640177eaa 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2006, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include "SCNetworkSignature.h"
 #include "SCNetworkSignaturePrivate.h"
 #include <arpa/inet.h>
 #include "SCNetworkSignature.h"
 #include "SCNetworkSignaturePrivate.h"
 #include <arpa/inet.h>
-
-const char * kSCNetworkSignatureActiveChangedNotifyName = NETWORK_ID_KEY ".active";
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <network/conninfo.h>
 
 #pragma mark SCNetworkSignature Supporting APIs
 
 static CFStringRef
 create_global_state_v4_key(void)
 {
 
 #pragma mark SCNetworkSignature Supporting APIs
 
 static CFStringRef
 create_global_state_v4_key(void)
 {
-       return SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, 
+       return SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
                                                          kSCDynamicStoreDomainState,
                                                          kSCEntNetIPv4);
                                                          kSCDynamicStoreDomainState,
                                                          kSCEntNetIPv4);
-       
+
 }
 
 static CFStringRef
 }
 
 static CFStringRef
@@ -88,26 +90,26 @@ create_ipv6_services_pattern(void)
 
 static CFDictionaryRef
 copy_services_for_address_family(CFAllocatorRef alloc,
 
 static CFDictionaryRef
 copy_services_for_address_family(CFAllocatorRef alloc,
-                                 int af)
+                                int af)
 {
 {
-        CFDictionaryRef info;
-        CFArrayRef      patterns;
-        CFStringRef     pattern;
-        CFStringRef     prop;
-       
-        prop = (af == AF_INET) ? kSCEntNetIPv4 : kSCEntNetIPv6;
-        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
-                                                              kSCDynamicStoreDomainState,
-                                                              kSCCompAnyRegex,
-                                                              prop);
-        patterns = CFArrayCreate(NULL,
-                                 (const void * *)&pattern, 1,
-                                 &kCFTypeArrayCallBacks);
-        CFRelease(pattern);
-        info = SCDynamicStoreCopyMultiple(NULL, NULL, patterns);
-        CFRelease(patterns);
-       
-        return (info);
+       CFDictionaryRef info;
+       CFArrayRef      patterns;
+       CFStringRef     pattern;
+       CFStringRef     prop;
+
+       prop = (af == AF_INET) ? kSCEntNetIPv4 : kSCEntNetIPv6;
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainState,
+                                                             kSCCompAnyRegex,
+                                                             prop);
+       patterns = CFArrayCreate(NULL,
+                                (const void * *)&pattern, 1,
+                                &kCFTypeArrayCallBacks);
+       CFRelease(pattern);
+       info = SCDynamicStoreCopyMultiple(NULL, NULL, patterns);
+       CFRelease(patterns);
+
+       return (info);
 }
 
 
 }
 
 
@@ -115,7 +117,7 @@ static CF_RETURNS_RETAINED CFStringRef
 my_IPAddressToCFString(int af, const void * src_p)
 {
        char            ntopbuf[INET6_ADDRSTRLEN];
 my_IPAddressToCFString(int af, const void * src_p)
 {
        char            ntopbuf[INET6_ADDRSTRLEN];
-       
+
        if (inet_ntop(af, src_p, ntopbuf, sizeof(ntopbuf)) != NULL) {
                return (CFStringCreateWithCString(NULL, ntopbuf,
                                                  kCFStringEncodingASCII));
        if (inet_ntop(af, src_p, ntopbuf, sizeof(ntopbuf)) != NULL) {
                return (CFStringCreateWithCString(NULL, ntopbuf,
                                                  kCFStringEncodingASCII));
@@ -138,7 +140,7 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc,
        CFDictionaryRef         global_v4_state_dict = NULL;
        CFArrayRef              keys = NULL;
        CFArrayRef              patterns = NULL;
        CFDictionaryRef         global_v4_state_dict = NULL;
        CFArrayRef              keys = NULL;
        CFArrayRef              patterns = NULL;
-       in_addr_t               s_addr; 
+       in_addr_t               s_addr;
        CFStringRef             service = NULL;
        CFDictionaryRef         service_dict = NULL;
        CFStringRef             service_id = NULL;
        CFStringRef             service = NULL;
        CFDictionaryRef         service_dict = NULL;
        CFStringRef             service_id = NULL;
@@ -148,7 +150,7 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc,
        /* only accept 0.0.0.0 (i.e. default) for now */
        if (addr == NULL
            || addr->sa_family != AF_INET
        /* only accept 0.0.0.0 (i.e. default) for now */
        if (addr == NULL
            || addr->sa_family != AF_INET
-           || addr->sa_len != sizeof(struct sockaddr_in)){
+           || addr->sa_len != sizeof(struct sockaddr_in)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                goto done;
        }
                _SCErrorSet(kSCStatusInvalidArgument);
                goto done;
        }
@@ -160,18 +162,18 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc,
                _SCErrorSet(kSCStatusInvalidArgument);
                goto done;
        }
                _SCErrorSet(kSCStatusInvalidArgument);
                goto done;
        }
-       
+
        global_state_v4_key = create_global_state_v4_key();
        global_state_v4_key = create_global_state_v4_key();
-       keys = CFArrayCreate(NULL, (const void * *)&global_state_v4_key, 
+       keys = CFArrayCreate(NULL, (const void * *)&global_state_v4_key,
                             1, &kCFTypeArrayCallBacks);
                             1, &kCFTypeArrayCallBacks);
-       
+
        v4_service_pattern = create_ipv4_services_pattern();
        patterns = CFArrayCreate(NULL,  (const void * *)&v4_service_pattern, 1,
                                 &kCFTypeArrayCallBacks);
 
        info = SCDynamicStoreCopyMultiple(NULL, keys, patterns);
        v4_service_pattern = create_ipv4_services_pattern();
        patterns = CFArrayCreate(NULL,  (const void * *)&v4_service_pattern, 1,
                                 &kCFTypeArrayCallBacks);
 
        info = SCDynamicStoreCopyMultiple(NULL, keys, patterns);
-       
-       if (info == NULL 
+
+       if (info == NULL
            || CFDictionaryGetCount(info) == 0) {
                goto done;
        }
            || CFDictionaryGetCount(info) == 0) {
                goto done;
        }
@@ -181,22 +183,22 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc,
        if (isA_CFDictionary(global_v4_state_dict) == NULL) {
                goto done;
        }
        if (isA_CFDictionary(global_v4_state_dict) == NULL) {
                goto done;
        }
-       
+
        service_id = CFDictionaryGetValue(global_v4_state_dict,
                                           kSCDynamicStorePropNetPrimaryService);
 
        if (isA_CFString(service_id) == NULL) {
                goto done;
        }
        service_id = CFDictionaryGetValue(global_v4_state_dict,
                                           kSCDynamicStorePropNetPrimaryService);
 
        if (isA_CFString(service_id) == NULL) {
                goto done;
        }
-       
+
        service = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainState,
                                                              service_id, kSCEntNetIPv4);
        service = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                              kSCDynamicStoreDomainState,
                                                              service_id, kSCEntNetIPv4);
-       
+
        service_dict = CFDictionaryGetValue(info, service);
 
        service_dict = CFDictionaryGetValue(info, service);
 
-       
-       if (isA_CFDictionary(service_dict) == NULL 
+
+       if (isA_CFDictionary(service_dict) == NULL
            || CFDictionaryGetCount(service_dict) == 0) {
                goto done;
        }
            || CFDictionaryGetCount(service_dict) == 0) {
                goto done;
        }
@@ -255,16 +257,16 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
        global_setup_v4_key = create_global_setup_v4_key();
        keys = CFArrayCreate(NULL, (const void * *)&global_setup_v4_key, 1,
                             &kCFTypeArrayCallBacks);
        global_setup_v4_key = create_global_setup_v4_key();
        keys = CFArrayCreate(NULL, (const void * *)&global_setup_v4_key, 1,
                             &kCFTypeArrayCallBacks);
-       
+
        v4_service_pattern = create_ipv4_services_pattern();
        CFArrayAppendValue(patterns, v4_service_pattern);
        v4_service_pattern = create_ipv4_services_pattern();
        CFArrayAppendValue(patterns, v4_service_pattern);
-       
+
        v6_service_pattern = create_ipv6_services_pattern();
        CFArrayAppendValue(patterns, v6_service_pattern);
        v6_service_pattern = create_ipv6_services_pattern();
        CFArrayAppendValue(patterns, v6_service_pattern);
-       
+
        info = SCDynamicStoreCopyMultiple(NULL, keys, patterns);
        info = SCDynamicStoreCopyMultiple(NULL, keys, patterns);
-       
-       if (info == NULL 
+
+       if (info == NULL
            || CFDictionaryGetCount(info) == 0) {
                goto done;
        }
            || CFDictionaryGetCount(info) == 0) {
                goto done;
        }
@@ -272,32 +274,32 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
        services_dict = CFDictionaryCreateMutableCopy(NULL, 0, info);
        /*
         * The service_dict should only contain services and once each
        services_dict = CFDictionaryCreateMutableCopy(NULL, 0, info);
        /*
         * The service_dict should only contain services and once each
-        * service has been visited, it will be removed from the dictionary.    
+        * service has been visited, it will be removed from the dictionary.
         */
        CFDictionaryRemoveValue(services_dict, global_setup_v4_key);
 
        global_v4_dict = CFDictionaryGetValue(info, global_setup_v4_key);
 
        if (isA_CFDictionary(global_v4_dict) == NULL) {
         */
        CFDictionaryRemoveValue(services_dict, global_setup_v4_key);
 
        global_v4_dict = CFDictionaryGetValue(info, global_setup_v4_key);
 
        if (isA_CFDictionary(global_v4_dict) == NULL) {
-               service_order = CFDictionaryGetValue(global_v4_dict, 
+               service_order = CFDictionaryGetValue(global_v4_dict,
                                                     kSCPropNetServiceOrder);
                if (isA_CFArray(service_order) != NULL) {
                        count = CFArrayGetCount(service_order);
                }
        }
                                                     kSCPropNetServiceOrder);
                if (isA_CFArray(service_order) != NULL) {
                        count = CFArrayGetCount(service_order);
                }
        }
-       
+
        active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       
+
        range = CFRangeMake(0, 0);
 
        for (i = 0; i < count ; i++) {
                int                     j;
                CFStringRef             network_sig;
                CFStringRef             service;
        range = CFRangeMake(0, 0);
 
        for (i = 0; i < count ; i++) {
                int                     j;
                CFStringRef             network_sig;
                CFStringRef             service;
-               CFStringRef             service_id; 
+               CFStringRef             service_id;
                CFDictionaryRef         service_info;
                CFStringRef             afs[2] = {kSCEntNetIPv4, kSCEntNetIPv6};
                CFDictionaryRef         service_info;
                CFStringRef             afs[2] = {kSCEntNetIPv4, kSCEntNetIPv6};
-               
+
                service_id = CFArrayGetValueAtIndex(service_order, i);
 
                if (isA_CFString(service_id) == NULL) {
                service_id = CFArrayGetValueAtIndex(service_order, i);
 
                if (isA_CFString(service_id) == NULL) {
@@ -308,7 +310,7 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
                        service = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                kSCDynamicStoreDomainState,
                                                service_id, afs[j]);
                        service = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
                                                kSCDynamicStoreDomainState,
                                                service_id, afs[j]);
-               
+
                        service_info = CFDictionaryGetValue(services_dict, service);
 
                        /* Does this service have a signature? */
                        service_info = CFDictionaryGetValue(services_dict, service);
 
                        /* Does this service have a signature? */
@@ -337,7 +339,7 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
                CFDictionaryGetKeysAndValues(services_dict, NULL,
                                             (const void * *)values);
        }
                CFDictionaryGetKeysAndValues(services_dict, NULL,
                                             (const void * *)values);
        }
-       
+
        for (i = 0; i < count; i++) {
                CFStringRef             network_sig;
                CFDictionaryRef         service_dict = (CFDictionaryRef)values[i];
        for (i = 0; i < count; i++) {
                CFStringRef             network_sig;
                CFDictionaryRef         service_dict = (CFDictionaryRef)values[i];
@@ -349,13 +351,13 @@ SCNetworkSignatureCopyActiveIdentifiers(CFAllocatorRef alloc)
                network_sig = CFDictionaryGetValue(service_dict,
                                                   kStoreKeyNetworkSignature);
                /* Does this service have a signature? */
                network_sig = CFDictionaryGetValue(service_dict,
                                                   kStoreKeyNetworkSignature);
                /* Does this service have a signature? */
-               if (isA_CFString(network_sig) != NULL 
+               if (isA_CFString(network_sig) != NULL
                    && CFArrayContainsValue(active, range, network_sig) == FALSE) {
                        CFArrayAppendValue(active, network_sig);
                        range.length++;
                        network_sig = NULL;
                }
                    && CFArrayContainsValue(active, range, network_sig) == FALSE) {
                        CFArrayAppendValue(active, network_sig);
                        range.length++;
                        network_sig = NULL;
                }
-       }               
+       }
  done:
        if (info != NULL) {
                CFRelease(info);
  done:
        if (info != NULL) {
                CFRelease(info);
@@ -400,41 +402,44 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc,
        int                     af;
        int                     count;
        int                     i;
        int                     af;
        int                     count;
        int                     i;
-       const void * *          keys = NULL;
+       char                    if_name[IFNAMSIZ];
+       CFStringRef             if_name_cf      = NULL;
+       conninfo_t *            info             = NULL;
+       const void * *          keys             = NULL;
 #define KEYS_STATIC_COUNT      10
        const void *            keys_static[KEYS_STATIC_COUNT];
        const void *            local_ip_p;
 #define KEYS_STATIC_COUNT      10
        const void *            keys_static[KEYS_STATIC_COUNT];
        const void *            local_ip_p;
-       CFStringRef             local_ip_str = NULL;
-       CFStringRef             ret_signature = NULL;
-       CFDictionaryRef         service_info = NULL;
-       union {
-               struct sockaddr_in      inet;
-               struct sockaddr_in6     inet6;
-               struct sockaddr         sa;
-       }                       ss;
-       socklen_t               ss_len = sizeof(ss);
-       int                     status = kSCStatusFailed;
-
-       if (getsockname(sock_fd, &ss.sa, &ss_len) != 0) {
+       CFStringRef             local_ip_str    = NULL;
+       CFStringRef             ret_signature   = NULL;
+       CFDictionaryRef         service_info    = NULL;
+       int                     status          = kSCStatusFailed;
+
+       if (copyconninfo(sock_fd, CONNID_ANY, &info) != 0) {
                status = kSCStatusInvalidArgument;
                goto done;
        }
                status = kSCStatusInvalidArgument;
                goto done;
        }
-       af = ss.inet.sin_family;
+       if ((info->ci_flags & CIF_CONNECTED) == 0
+           || info->ci_src == NULL) {
+           goto done;
+       }
+       af = info->ci_src->sa_family;
        switch (af) {
        case AF_INET:
                addresses_key = kSCPropNetIPv4Addresses;
        switch (af) {
        case AF_INET:
                addresses_key = kSCPropNetIPv4Addresses;
-               local_ip_p = &ss.inet.sin_addr;
+               local_ip_p = &((struct sockaddr_in *)
+                              (void *)info->ci_src)->sin_addr;
                break;
        case AF_INET6:
                addresses_key = kSCPropNetIPv6Addresses;
                break;
        case AF_INET6:
                addresses_key = kSCPropNetIPv6Addresses;
-               local_ip_p = &ss.inet6.sin6_addr;
+               local_ip_p = &((struct sockaddr_in6 *)
+                              (void *)info->ci_src)->sin6_addr;
                break;
        default:
                status = kSCStatusInvalidArgument;
                goto done;
        }
 
                break;
        default:
                status = kSCStatusInvalidArgument;
                goto done;
        }
 
-       /* find a service matching the local IP and get its network signature */
+       /* search for service with matching IP address and interface name */
        service_info = copy_services_for_address_family(alloc, af);
        if (service_info == NULL) {
                goto done;
        service_info = copy_services_for_address_family(alloc, af);
        if (service_info == NULL) {
                goto done;
@@ -443,6 +448,12 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc,
        if (local_ip_str == NULL) {
                goto done;
        }
        if (local_ip_str == NULL) {
                goto done;
        }
+       if (info->ci_ifindex != 0
+           && if_indextoname(info->ci_ifindex, if_name) != NULL) {
+               if_name_cf
+                       = CFStringCreateWithCString(NULL, if_name,
+                                                   kCFStringEncodingASCII);
+       }
        count = CFDictionaryGetCount(service_info);
        if (count > KEYS_STATIC_COUNT) {
                keys = (const void * *)malloc(sizeof(*keys) * count);
        count = CFDictionaryGetCount(service_info);
        if (count > KEYS_STATIC_COUNT) {
                keys = (const void * *)malloc(sizeof(*keys) * count);
@@ -467,6 +478,17 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc,
                        /* no signature */
                        continue;
                }
                        /* no signature */
                        continue;
                }
+               if (if_name_cf != NULL) {
+                       CFStringRef             this_if;
+
+                       this_if = CFDictionaryGetValue(value,
+                                                      kSCPropInterfaceName);
+                       if (isA_CFString(this_if) != NULL
+                           && !CFEqual(this_if, if_name_cf)) {
+                               /* interface name doesn't match */
+                               continue;
+                       }
+               }
                addrs = CFDictionaryGetValue(value, addresses_key);
                if (isA_CFArray(addrs) == NULL) {
                        continue;
                addrs = CFDictionaryGetValue(value, addresses_key);
                if (isA_CFArray(addrs) == NULL) {
                        continue;
@@ -480,6 +502,12 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc,
        }
 
  done:
        }
 
  done:
+       if (info != NULL) {
+               freeconninfo(info);
+       }
+       if (if_name_cf != NULL) {
+               CFRelease(if_name_cf);
+       }
        if (local_ip_str != NULL) {
                CFRelease(local_ip_str);
        }
        if (local_ip_str != NULL) {
                CFRelease(local_ip_str);
        }
index 10926a62979904f7b8e717c81a3a4a6e44c5adc1..675ae3f6b10b0ac679c1f755e8715812069e17f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -42,13 +42,6 @@ __BEGIN_DECLS
                or set of networks.
  */
 
                or set of networks.
  */
 
-/*!
-       @const kSCNetworkSignatureActiveChangedNotifyName
-       @discussion The name to use with the notify(3) API's to monitor
-               when the list of active signatures changes.
- */
-extern const char * kSCNetworkSignatureActiveChangedNotifyName;
-
 /*!
        @function SCNetworkSignatureCopyActiveIdentifiers
        @discussion Find all currently active networks and return a list of
 /*!
        @function SCNetworkSignatureCopyActiveIdentifiers
        @discussion Find all currently active networks and return a list of
index 55219f069915d75af34d059117baa2d8e08da90d..1486b5cba9fd2cc1ab71a1b0c14afd5e468a5f0c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2006, 2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2006, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #ifndef _SCNETWORKSIGNATUREPRIVATE_H
 #define _SCNETWORKSIGNATUREPRIVATE_H
 
 #ifndef _SCNETWORKSIGNATUREPRIVATE_H
 #define _SCNETWORKSIGNATUREPRIVATE_H
 
-#define NETWORK_ID_KEY         "com.apple.network.identification"
-#define kSCNetworkIdentificationPrefsKey CFSTR(NETWORK_ID_KEY ".plist")
-#define kSCNetworkIdentificationStoreKey CFSTR(NETWORK_ID_KEY)
-
-#define kStoreKeyServiceIdentifiers    CFSTR("ServiceIdentifiers")
-#define kStoreKeyActiveIdentifiers     CFSTR("ActiveIdentifiers")
-#define kStoreKeyPrimaryIPv4Identifier         CFSTR("PrimaryIPv4Identifier")
-
 #define kStoreKeyNetworkSignature      CFSTR("NetworkSignature")
 
 #endif /* _SCNETWORKSIGNATUREPRIVATE_H */
 #define kStoreKeyNetworkSignature      CFSTR("NetworkSignature")
 
 #endif /* _SCNETWORKSIGNATUREPRIVATE_H */
index 6f193c1712e49fb9fb0566a285bae2eeeaaca107..6418cfcd0fbdb9c68b4d32894124b03d503bc9c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2008, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -60,6 +60,13 @@ __SCPreferencesCommitChanges_helper(SCPreferencesRef prefs)
                ok = _SCSerialize(prefsPrivate->prefs, &data, NULL, NULL);
                if (!ok) {
                        status = kSCStatusFailed;
                ok = _SCSerialize(prefsPrivate->prefs, &data, NULL, NULL);
                if (!ok) {
                        status = kSCStatusFailed;
+                       if (_sc_verbose) {
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("SCPreferencesCommitChanges(-->helper) CFPropertyListCreateData() failed"));
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("  prefs = %s"),
+                                     prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path);
+                       }
                        goto error;
                }
        }
                        goto error;
                }
        }
index 7558a9ed5f36dbbdbe0d6917767aab0d7b2f121c..125ba24b99530a4e5cda29cb61f77a1422d3a76e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright(c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright(c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -48,6 +48,7 @@
 
 #include <fcntl.h>
 #include <pthread.h>
 
 #include <fcntl.h>
 #include <pthread.h>
+#include <sandbox.h>
 #include <unistd.h>
 #include <sys/errno.h>
 
 #include <unistd.h>
 #include <sys/errno.h>
 
@@ -84,7 +85,7 @@ __SCPreferencesCopyDescription(CFTypeRef cf) {
                CFStringAppendFormat(result, NULL, CFSTR(", locked"));
        }
        if (prefsPrivate->helper_port != MACH_PORT_NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", locked"));
        }
        if (prefsPrivate->helper_port != MACH_PORT_NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR(", helper port = %p"), prefsPrivate->helper_port);
+               CFStringAppendFormat(result, NULL, CFSTR(", helper port = 0x%x"), prefsPrivate->helper_port);
        }
        CFStringAppendFormat(result, NULL, CFSTR("}"));
 
        }
        CFStringAppendFormat(result, NULL, CFSTR("}"));
 
@@ -209,6 +210,7 @@ __SCPreferencesCreatePrivate(CFAllocatorRef allocator)
        prefsPrivate->changed                           = FALSE;
        prefsPrivate->isRoot                            = (geteuid() == 0);
        prefsPrivate->authorizationData                 = NULL;
        prefsPrivate->changed                           = FALSE;
        prefsPrivate->isRoot                            = (geteuid() == 0);
        prefsPrivate->authorizationData                 = NULL;
+       prefsPrivate->authorizationRequired             = FALSE;
        prefsPrivate->helper_port                       = MACH_PORT_NULL;
 
        return prefsPrivate;
        prefsPrivate->helper_port                       = MACH_PORT_NULL;
 
        return prefsPrivate;
@@ -355,7 +357,7 @@ __SCPreferencesAccess_helper(SCPreferencesRef prefs)
        }
 
        if ((serverPrefs == NULL) || (serverSignature == NULL)) {
        }
 
        if ((serverPrefs == NULL) || (serverSignature == NULL)) {
-               CFRelease(serverDict);
+               if (serverDict != NULL) CFRelease(serverDict);
                goto fail;
        }
 
                goto fail;
        }
 
@@ -390,7 +392,6 @@ __SCPreferencesCreate(CFAllocatorRef        allocator,
                      CFDataRef         authorizationData,
                      CFDictionaryRef   options)
 {
                      CFDataRef         authorizationData,
                      CFDictionaryRef   options)
 {
-       int                             fd              = -1;
        SCPreferencesPrivateRef         prefsPrivate;
        int                             sc_status       = kSCStatusOK;
 
        SCPreferencesPrivateRef         prefsPrivate;
        int                             sc_status       = kSCStatusOK;
 
@@ -426,87 +427,90 @@ __SCPreferencesCreate(CFAllocatorRef      allocator,
                goto error;
        }
 
                goto error;
        }
 
-       /*
-        * open file
-        */
-       fd = open(prefsPrivate->path, O_RDONLY, 0644);
-       if (fd != -1) {
-               (void) close(fd);
-       } else {
-               switch (errno) {
-                       case ENOENT :
-                               /* no prefs file */
-                               if ((prefsID == NULL) || !CFStringHasPrefix(prefsID, CFSTR("/"))) {
-                                       /* if default preference ID or relative path */
-                                       if (prefsPrivate->newPath == NULL) {
-                                               /*
-                                                * we've looked in the "new" prefs directory
-                                                * without success.  Save the "new" path and
-                                                * look in the "old" prefs directory.
-                                                */
-                                               prefsPrivate->newPath = prefsPrivate->path;
-                                               goto retry;
-                                       } else {
-                                               /*
-                                                * we've looked in both the "new" and "old"
-                                                * prefs directories without success.  Use
-                                                * the "new" path.
-                                                */
-                                               CFAllocatorDeallocate(NULL, prefsPrivate->path);
-                                               prefsPrivate->path = prefsPrivate->newPath;
-                                               prefsPrivate->newPath = NULL;
-                                       }
+       if (access(prefsPrivate->path, R_OK) == 0) {
+               goto done;
+       }
+
+       switch (errno) {
+               case ENOENT :
+                       /* no prefs file */
+                       if ((prefsID == NULL) || !CFStringHasPrefix(prefsID, CFSTR("/"))) {
+                               /* if default preference ID or relative path */
+                               if (prefsPrivate->newPath == NULL) {
+                                       /*
+                                        * we've looked in the "new" prefs directory
+                                        * without success.  Save the "new" path and
+                                        * look in the "old" prefs directory.
+                                        */
+                                       prefsPrivate->newPath = prefsPrivate->path;
+                                       goto retry;
+                               } else {
+                                       /*
+                                        * we've looked in both the "new" and "old"
+                                        * prefs directories without success.  Use
+                                        * the "new" path.
+                                        */
+                                       CFAllocatorDeallocate(NULL, prefsPrivate->path);
+                                       prefsPrivate->path = prefsPrivate->newPath;
+                                       prefsPrivate->newPath = NULL;
                                }
                                }
+                       }
 
 
-                               /* no preference data, start fresh */
-                               sc_status = kSCStatusNoConfigFile;
+                       /* no preference data, start fresh */
+                       sc_status = kSCStatusNoConfigFile;
+                       goto done;
+               case EPERM  :
+               case EACCES :
+                       if (prefsPrivate->authorizationData != NULL) {
+                               /* no problem, we'll be using the helper */
                                goto done;
                                goto done;
-                       case EACCES :
-                               if (prefsPrivate->authorizationData != NULL) {
-                                       /* no problem, we'll be using the helper */
-                                       goto done;
-                               }
+                       }
 
 
-                               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesCreate open() failed: %s"), strerror(errno));
-                               sc_status = kSCStatusAccessError;
-                               break;
-                       default :
-                               SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesCreate open() failed: %s"), strerror(errno));
-                               sc_status = kSCStatusFailed;
-                               break;
-               }
-               goto error;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesCreate open() failed: %s"), strerror(errno));
+                       sc_status = kSCStatusAccessError;
+                       break;
+               default :
+                       SCLog(TRUE, LOG_ERR, CFSTR("__SCPreferencesCreate open() failed: %s"), strerror(errno));
+                       sc_status = kSCStatusFailed;
+                       break;
        }
 
        }
 
-    done :
+    error:
 
 
-       /* all OK */
+       CFRelease(prefsPrivate);
        _SCErrorSet(sc_status);
        _SCErrorSet(sc_status);
-       return prefsPrivate;
+       return NULL;
 
 
-    error :
+    done :
 
 
-       if (fd != -1) (void) close(fd);
-       CFRelease(prefsPrivate);
+       /* all OK */
        _SCErrorSet(sc_status);
        _SCErrorSet(sc_status);
-       return NULL;
+       return prefsPrivate;
 }
 
 
 __private_extern__ void
 __SCPreferencesAccess(SCPreferencesRef prefs)
 {
 }
 
 
 __private_extern__ void
 __SCPreferencesAccess(SCPreferencesRef prefs)
 {
-       CFAllocatorRef                  allocator       = CFGetAllocator(prefs);
-       int                             fd              = -1;
-       SCPreferencesPrivateRef         prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-       struct  stat                    statBuf;
+       CFAllocatorRef          allocator       = CFGetAllocator(prefs);
+       int                     fd              = -1;
+       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+       struct stat             statBuf;
 
        if (prefsPrivate->accessed) {
                // if preference data has already been accessed
                return;
        }
 
 
        if (prefsPrivate->accessed) {
                // if preference data has already been accessed
                return;
        }
 
-       fd = open(prefsPrivate->path, O_RDONLY, 0644);
+       if (!prefsPrivate->authorizationRequired) {
+               if (access(prefsPrivate->path, R_OK) == 0) {
+                       fd = open(prefsPrivate->path, O_RDONLY, 0644);
+               } else {
+                       fd = -1;
+               }
+       } else {
+               errno = EACCES;
+       }
        if (fd != -1) {
                // create signature
                if (fstat(fd, &statBuf) == -1) {
        if (fd != -1) {
                // create signature
                if (fstat(fd, &statBuf) == -1) {
@@ -518,6 +522,7 @@ __SCPreferencesAccess(SCPreferencesRef      prefs)
                        case ENOENT :
                                /* no preference data, start fresh */
                                break;
                        case ENOENT :
                                /* no preference data, start fresh */
                                break;
+                       case EPERM  :
                        case EACCES :
                                if (prefsPrivate->authorizationData != NULL) {
                                        if (__SCPreferencesAccess_helper(prefs)) {
                        case EACCES :
                                if (prefsPrivate->authorizationData != NULL) {
                                        if (__SCPreferencesAccess_helper(prefs)) {
@@ -672,7 +677,7 @@ SCPreferencesCreateWithOptions(CFAllocatorRef       allocator,
                                                               &kCFTypeDictionaryValueCallBacks);
 #if    !TARGET_OS_IPHONE
                if (authorization != kSCPreferencesUseEntitlementAuthorization) {
                                                               &kCFTypeDictionaryValueCallBacks);
 #if    !TARGET_OS_IPHONE
                if (authorization != kSCPreferencesUseEntitlementAuthorization) {
-                       CFDataRef                       authorizationRefData;
+                       CFDataRef                       data;
                        AuthorizationExternalForm       extForm;
                        OSStatus                        os_status;
 
                        AuthorizationExternalForm       extForm;
                        OSStatus                        os_status;
 
@@ -684,11 +689,11 @@ SCPreferencesCreateWithOptions(CFAllocatorRef     allocator,
                                return NULL;
                        }
 
                                return NULL;
                        }
 
-                       authorizationRefData = CFDataCreate(NULL, (const UInt8 *)extForm.bytes, sizeof(extForm.bytes));
+                       data = CFDataCreate(NULL, (const UInt8 *)extForm.bytes, sizeof(extForm.bytes));
                        CFDictionaryAddValue(authorizationDict,
                                             kSCHelperAuthAuthorization,
                        CFDictionaryAddValue(authorizationDict,
                                             kSCHelperAuthAuthorization,
-                                            authorizationRefData);
-                       CFRelease(authorizationRefData);
+                                            data);
+                       CFRelease(data);
                }
 #endif
 
                }
 #endif
 
@@ -860,7 +865,7 @@ SCPreferencesSetCallback(SCPreferencesRef       prefs,
                (*prefsPrivate->rlsContext.release)(prefsPrivate->rlsContext.info);
        }
 
                (*prefsPrivate->rlsContext.release)(prefsPrivate->rlsContext.info);
        }
 
-       prefsPrivate->rlsFunction                       = callout;
+       prefsPrivate->rlsFunction                       = callout;
        prefsPrivate->rlsContext.info                   = NULL;
        prefsPrivate->rlsContext.retain                 = NULL;
        prefsPrivate->rlsContext.release                = NULL;
        prefsPrivate->rlsContext.info                   = NULL;
        prefsPrivate->rlsContext.retain                 = NULL;
        prefsPrivate->rlsContext.release                = NULL;
index bd947421ddce669a634cc0773f17895b8a5769d3..a9489ffacc5c60f6036f3bac974407c53332ea7c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -379,6 +379,8 @@ SCPreferencesPathCreateUniqueChild(SCPreferencesRef prefs,
                                     NULL, NULL, 0,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
                                     NULL, NULL, 0,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
+       assert(newDict != NULL);
+
        if (!setPath(prefs, newPath, newDict)) {
                CFRelease(newPath);
                newPath = NULL;
        if (!setPath(prefs, newPath, newDict)) {
                CFRelease(newPath);
                newPath = NULL;
index aca0a16c5ea9cdefc75df21ad5a65b7a3593c618..f4ab7da4f275372bf6b35da38b4afd8fc2128356 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -100,6 +100,7 @@ typedef struct {
 
        /* authorization, helper */
        CFDataRef               authorizationData;
 
        /* authorization, helper */
        CFDataRef               authorizationData;
+       Boolean                 authorizationRequired;
        mach_port_t             helper_port;
 
 } SCPreferencesPrivate, *SCPreferencesPrivateRef;
        mach_port_t             helper_port;
 
 } SCPreferencesPrivate, *SCPreferencesPrivateRef;
index 2690e17174ec6fc17a08d2915a3b3338b5e0039c..303ffdd19050eb779c09c34f1b6d3ef549d5848b 100644 (file)
        @header SCPreferencesPrivate
  */
 
        @header SCPreferencesPrivate
  */
 
+/*!
+       @defined kSCPreferencesOptionChangeNetworkSet
+       @abstract The SCPreferences "option" used to indicate that only the
+               current network set (location) is being changed.
+ */
+#define kSCPreferencesOptionChangeNetworkSet   CFSTR("change-network-set")     // CFBooleanRef
+
+/*!
+       @defined kSCPreferencesOptionRemoveWhenEmpty
+       @abstract The SCPreferences "option" used to indicate that the .plist
+               file should be removed when/if all keys have been removed.
+ */
 #define kSCPreferencesOptionRemoveWhenEmpty    CFSTR("remove-when-empty")      // CFBooleanRef
 
 #define kSCPreferencesOptionRemoveWhenEmpty    CFSTR("remove-when-empty")      // CFBooleanRef
 
-#define kSCPreferencesWriteAuthorizationRight  "system.services.systemconfiguration.network"
+/*!
+       @defined kSCPreferencesAuthorizationRight_network_set
+       @abstract The authorization right used to control whether the current
+               network set (location) can be changed.
+ */
+#define kSCPreferencesAuthorizationRight_network_set   "system.preferences.location"
+
+/*!
+       @defined kSCPreferencesAuthorizationRight_write
+       @abstract The authorization right used to control whether the network
+               configuration can be changed.
+ */
+#define kSCPreferencesAuthorizationRight_write         "system.services.systemconfiguration.network"
 
 /*!
        @enum SCPreferencesKeyType
 
 /*!
        @enum SCPreferencesKeyType
index 509c59e236a93fa0f7e39e337b65ebf2baecc47b..68460338761a346f82ba8c70ebba8843822ba84a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 
 
  */
 
 
+/* "server" defines */
+#if    !TARGET_IPHONE_SIMULATOR
+#define _SC_SERVER_PROG                        "configd"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define _SC_SERVER_PROG                        "configd_sim"
+#endif // !TARGET_IPHONE_SIMULATOR
+
+
 /* atomic operations */
 #define _SC_ATOMIC_CMPXCHG(p, o, n)    __sync_bool_compare_and_swap((p), (o), (n))
 #define _SC_ATOMIC_INC(p)              __sync_fetch_and_add((p), 1)            // return (n++);
 /* atomic operations */
 #define _SC_ATOMIC_CMPXCHG(p, o, n)    __sync_bool_compare_and_swap((p), (o), (n))
 #define _SC_ATOMIC_INC(p)              __sync_fetch_and_add((p), 1)            // return (n++);
@@ -75,6 +83,20 @@ extern int   _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 */
 
                                   1 if SC messages should be logged w/asl(3),
                                   2 if SC messages should be written to stdout/stderr AND logged */
 
+/* notify(3) keys */
+
+#if    !TARGET_IPHONE_SIMULATOR
+#define _SC_NOTIFY_PREFIX      "com.apple.system.config"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define _SC_NOTIFY_PREFIX      "com.apple.iOS_Simulator.config"
+#endif // !TARGET_IPHONE_SIMULATOR
+
+#define _SC_NOTIFY_NETWORK_CHANGE      _SC_NOTIFY_PREFIX ".network_change"
+#define _SC_NOTIFY_NETWORK_CHANGE_DNS  _SC_NOTIFY_NETWORK_CHANGE ".dns"
+#define _SC_NOTIFY_NETWORK_CHANGE_NWI  _SC_NOTIFY_NETWORK_CHANGE ".nwi"
+#define _SC_NOTIFY_NETWORK_CHANGE_PROXY        _SC_NOTIFY_PREFIX ".proxy_change"
+
+
 /*!
        @group SCNetworkReachabilityCreateWithOptions #defines
        @discussion The following defines the keys and values that can
 /*!
        @group SCNetworkReachabilityCreateWithOptions #defines
        @discussion The following defines the keys and values that can
@@ -104,23 +126,6 @@ extern int _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
  */
 #define kSCNetworkReachabilityOptionRemoteAddress              CFSTR("remote-address")
 
  */
 #define kSCNetworkReachabilityOptionRemoteAddress              CFSTR("remote-address")
 
-/*!
-       @constant kSCNetworkReachabilityOptionServName
-       @discussion A CFString that will be passed to getaddrinfo(3).  An acceptable
-               value is either a decimal port number or a service name listed in
-               services(5).
- */
-#define kSCNetworkReachabilityOptionServName                   CFSTR("servname")
-
-/*!
-       @constant kSCNetworkReachabilityOptionHints
-       @discussion A CFData wrapping a "struct addrinfo" that will be passed to
-               getaddrinfo(3).  The caller can supply any of the ai_family,
-               ai_socktype, ai_protocol, and ai_flags structure elements.  All
-               other elements must be 0 or the null pointer.
- */
-#define kSCNetworkReachabilityOptionHints                      CFSTR("hints")
-
 /*!
        @constant kSCNetworkReachabilityOptionInterface
        @discussion A CFString specifying that the reachability query should be
 /*!
        @constant kSCNetworkReachabilityOptionInterface
        @discussion A CFString specifying that the reachability query should be
@@ -128,6 +133,7 @@ extern int  _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
  */
 #define kSCNetworkReachabilityOptionInterface                  CFSTR("interface")
 
  */
 #define kSCNetworkReachabilityOptionInterface                  CFSTR("interface")
 
+
 /*!
        @constant kSCNetworkReachabilityOptionConnectionOnDemandBypass
        @discussion A CFBoolean that indicates if we should bypass the VPNOnDemand
 /*!
        @constant kSCNetworkReachabilityOptionConnectionOnDemandBypass
        @discussion A CFBoolean that indicates if we should bypass the VPNOnDemand
@@ -143,14 +149,6 @@ extern int _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
 #define kSCNetworkReachabilityOptionResolverBypass             CFSTR("ResolverBypass")
 
 
 #define kSCNetworkReachabilityOptionResolverBypass             CFSTR("ResolverBypass")
 
 
-/*!
-       @constant kSCNetworkReachabilityOptionLongLivedQueryBypass
-       @discussion A CFBoolean that indicates if we should bypass usage of any
-               long-lived-queries (w/DNSServiceCreateConnection) when resolving
-               hostnames for this target.
- */
-#define kSCNetworkReachabilityOptionLongLivedQueryBypass       CFSTR("LongLivedQueryBypass")
-
 /*!
        @constant kSCNetworkReachabilityOptionServerBypass
        @discussion A CFBoolean that indicates if we should bypass usage of the
 /*!
        @constant kSCNetworkReachabilityOptionServerBypass
        @discussion A CFBoolean that indicates if we should bypass usage of the
@@ -158,6 +156,9 @@ extern int  _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
  */
 #define kSCNetworkReachabilityOptionServerBypass               CFSTR("ServerBypass")
 
  */
 #define kSCNetworkReachabilityOptionServerBypass               CFSTR("ServerBypass")
 
+
+
+
 /*!
        @group
  */
 /*!
        @group
  */
@@ -404,7 +405,57 @@ void               SCLog                           (Boolean                condition,
                                                 CFStringRef            formatString,
                                                 ...);
 
                                                 CFStringRef            formatString,
                                                 ...);
 
+enum {
+       kSCLoggerFlagsNone              = 0x0,
+       kSCLoggerFlagsDefault   = 0x1,
+       kSCLoggerFlagsFile              = 0x2
+};
+typedef uint32_t       SCLoggerFlags;
+
+typedef struct SCLogger * SCLoggerRef;
+
+
+/*!
+       @function SCLoggerLog
+       @discussion Logs messages using SCLoggerRef
+       @param  logger A SCLoggerRef which keeps information about how logging
+               needs to be done. Passing NULL uses the default logger instance.
+       @param level An 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".
+       @param formatString The format string followed by format arguments
+       @result The specified message will be written to the system message
+               logger (See syslogd(8)). If logger is in verbose mode, the message
+               will be also written to a file specified in the ASL Module
+ */
+void           SCLoggerLog                     (SCLoggerRef    logger,
+                                                int            level,
+                                                CFStringRef    formatString,
+                                                ...)                   __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0);
+
+/*!
+       @function SCLoggerVLog
+       @discussion Logs messages using SCLoggerRef
+       @param logger A SCLoggerRef which keeps information about how logging
+               needs to be done. Passing NULL uses the default logger instance.
+       @param level An 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".
+       @param formatString The format string
+       @param args The va_list representing the arguments
+       @result The specified message will be written to the system message
+               logger (See syslogd(8)). If logger is in verbose mode, the message
+               will be also written to a file specified in the ASL Module
+ */
+void           SCLoggerVLog                    (SCLoggerRef    logger,
+                                                int            level,
+                                                CFStringRef    formatString,
+                                                va_list        args)   __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
 
 
+#ifdef USE_NEW_SCLOG
+#define SCLOG(sclogger, level, __string, ...)  SCLoggerLog(sclogger, level, CFSTR(__string), ## __VA_ARGS__)   // temporary, remove once all "old" clients have migrated
+#else
 /*!
        @function SCLOG
        @discussion Issue a log message.
 /*!
        @function SCLOG
        @discussion Issue a log message.
@@ -426,6 +477,8 @@ void                SCLOG                           (aslclient              asl,
                                                 ...);
 
 
                                                 ...);
 
 
+#endif
+
 /*!
        @function SCPrint
        @discussion Conditionally issue a debug message.
 /*!
        @function SCPrint
        @discussion Conditionally issue a debug message.
@@ -440,6 +493,8 @@ void                SCPrint                         (Boolean                condition,
                                                 CFStringRef            formatString,
                                                 ...);
 
                                                 CFStringRef            formatString,
                                                 ...);
 
+
+
 /*!
        @function SCTrace
        @discussion Conditionally issue a debug message with a time stamp.
 /*!
        @function SCTrace
        @discussion Conditionally issue a debug message with a time stamp.
@@ -454,6 +509,35 @@ void               SCTrace                         (Boolean                condition,
                                                 CFStringRef            formatString,
                                                 ...);
 
                                                 CFStringRef            formatString,
                                                 ...);
 
+/*!
+       @function SCLoggerCreate
+       @discussion Create a reference to logger which stores information like verbose mode or not, loggerID, etc.
+                       loggerID and moduleName both need to be non NULL, or else the function returns NULL.
+                       If the moduleName points to a module which doesn't exist, then SCLoggerCreate will fail and
+                       return NULL;
+       @param loggerID CFStringRef which will be appended to the log message when in verbose mode. It will also be
+                       used to identify the module where the rules are being defined.
+ */
+SCLoggerRef
+SCLoggerCreate                                 (CFStringRef loggerID);
+
+/*!
+       @function SCLoggerGetFlags
+       @discussion Returns the log flags for the logging reference
+       @param  logger Reference which points to the logger information
+ */
+SCLoggerFlags
+SCLoggerGetFlags                               (SCLoggerRef logger);
+
+/*!
+       @function SCLoggerSetFlags
+       @discussion Sets the log flags for the logger reference
+       @param  logger A reference to the logger
+       @param  flags SCLoggerFlags value determining where the logs from the logger will be directed
+ */
+void           SCLoggerSetFlags                (SCLoggerRef logger,
+                                                SCLoggerFlags flags);
+
 #pragma mark -
 #pragma mark Proxies
 
 #pragma mark -
 #pragma mark Proxies
 
@@ -479,6 +563,29 @@ SCNetworkProxiesCopyMatching                       (CFDictionaryRef        globalConfiguration,
                                                 CFStringRef            server,
                                                 CFStringRef            interface)      __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/);
 
                                                 CFStringRef            server,
                                                 CFStringRef            interface)      __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/);
 
+extern const CFStringRef       kSCProxiesNoGlobal;
+
+/*!
+ @function SCDynamicStoreCopyProxiesWithOptions
+ @discussion
+
+       @param  store An SCDynamicStoreRef representing the dynamic store
+               session that should be used for communication with the server.
+               If NULL, a temporary session will be used.
+       @param  options  A dictionary of proxy options which can include 1 (or more) of the following :
+               key                             value           description
+               ---------------------------------------------------------------------------------------
+               kSCProxiesNoGlobal              CFBoolean       Bypass any "global" proxy configuration
+               ...
+       @result Returns a dictionary containing key-value pairs that represent
+               the current internet proxy settings;
+               NULL if no proxy settings have been defined or if an error
+               was encountered.
+               You must release the returned value.
+*/
+CFDictionaryRef
+SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef options) __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/);
+
 #pragma mark -
 #pragma mark Reachability
 
 #pragma mark -
 #pragma mark Reachability
 
@@ -546,9 +653,9 @@ _SC_checkResolverReachabilityByAddress              (SCDynamicStoreRef              *storeP,
 int
 SCNetworkReachabilityGetInterfaceIndex         (SCNetworkReachabilityRef       target);
 
 int
 SCNetworkReachabilityGetInterfaceIndex         (SCNetworkReachabilityRef       target);
 
+
 #pragma mark -
 #pragma mark Domain
 #pragma mark -
 #pragma mark Domain
-
 /*!
        @function    _SC_domainEndsWithDomain
        @discussion  Checks if one domain is a subset of another
 /*!
        @function    _SC_domainEndsWithDomain
        @discussion  Checks if one domain is a subset of another
@@ -728,6 +835,13 @@ _SC_crash                                  (const char             *crash_info,
                                                 CFStringRef            notifyHeader,
                                                 CFStringRef            notifyMessage);
 
                                                 CFStringRef            notifyHeader,
                                                 CFStringRef            notifyMessage);
 
+Boolean
+_SC_getconninfo                                        (int                            socket,
+                                                struct sockaddr_storage        *src_addr,
+                                                struct sockaddr_storage        *dest_addr,
+                                                int                            *if_index,
+                                                uint32_t                       *flags);
+
 __END_DECLS
 
 #endif /* _SCPRIVATE_H */
 __END_DECLS
 
 #endif /* _SCPRIVATE_H */
index b041e3cc94da3005de289bd25e85c72890130fe4..9fe060d92d35bbe7e01ac750ba66721d6227ef41 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -32,6 +32,7 @@
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>
 #include <SystemConfiguration/SystemConfiguration.h>
 #include <SystemConfiguration/SCValidation.h>
 #include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/VPNAppLayerPrivate.h>
 
 #include <netdb.h>
 
 
 #include <netdb.h>
 
@@ -62,8 +63,7 @@ validate_proxy_content(CFMutableDictionaryRef proxies,
        if (num != NULL) {
                if (!isA_CFNumber(num) ||
                    !CFNumberGetValue(num, kCFNumberIntType, &enabled)) {
        if (num != NULL) {
                if (!isA_CFNumber(num) ||
                    !CFNumberGetValue(num, kCFNumberIntType, &enabled)) {
-                       // if we don't like the enabled key/value
-                       goto disable;
+                       goto disable;           // if we don't like the enabled key/value
                }
        }
 
                }
        }
 
@@ -71,26 +71,38 @@ validate_proxy_content(CFMutableDictionaryRef       proxies,
                CFStringRef     host;
 
                host = CFDictionaryGetValue(proxies, proxy_host);
                CFStringRef     host;
 
                host = CFDictionaryGetValue(proxies, proxy_host);
-               if (((enabled == 0) && (host != NULL)) ||
-                   ((enabled != 0) && !isA_CFString(host))) {
-                       // pass only valid proxy hosts and only when enabled
-                       goto disable;
+               if ((enabled == 0) && (host != NULL)) {
+                       goto disable;           // if not enabled, remove provided key/value
+               }
+
+               if ((enabled != 0) && !isA_CFString(host)) {
+                       goto disable;           // if enabled, not provided (or not valid)
                }
        }
 
        if (proxy_port != NULL) {
                CFNumberRef     port;
                }
        }
 
        if (proxy_port != NULL) {
                CFNumberRef     port;
+               int             s_port  = 0;
 
                port = CFDictionaryGetValue(proxies, proxy_port);
 
                port = CFDictionaryGetValue(proxies, proxy_port);
-               if (((enabled == 0) && (port != NULL)) ||
-                   ((enabled != 0) && (port != NULL) && !isA_CFNumber(port))) {
-                       // pass only provided/valid proxy ports and only when enabled
-                       goto disable;
+               if ((enabled == 0) && (port != NULL)) {
+                       goto disable;           // if not enabled, remove provided key/value
+               }
+
+               if ((enabled != 0) && (port != NULL)) {
+                       if (!isA_CFNumber(port) ||
+                           !CFNumberGetValue(port, kCFNumberIntType, &s_port) ||
+                           (s_port > UINT16_MAX)) {
+                               goto disable;   // if enabled, not provided (or not valid)
+                       }
+
+                       if (s_port == 0) {
+                               port = NULL;    // if no port # provided, use default
+                       }
                }
 
                if ((enabled != 0) && (port == NULL)) {
                        struct servent  *service;
                }
 
                if ((enabled != 0) && (port == NULL)) {
                        struct servent  *service;
-                       int             s_port;
 
                        service = getservbyname(proxy_service, "tcp");
                        if (service != NULL) {
 
                        service = getservbyname(proxy_service, "tcp");
                        if (service != NULL) {
@@ -127,6 +139,10 @@ static void
 normalize_scoped_proxy(const void *key, const void *value, void *context);
 
 
 normalize_scoped_proxy(const void *key, const void *value, void *context);
 
 
+static void
+normalize_services_proxy(const void *key, const void *value, void *context);
+
+
 static void
 normalize_supplemental_proxy(const void *value, void *context);
 
 static void
 normalize_supplemental_proxy(const void *value, void *context);
 
@@ -138,6 +154,7 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy)
        CFMutableDictionaryRef  newProxy;
        CFNumberRef             num;
        CFDictionaryRef         scoped;
        CFMutableDictionaryRef  newProxy;
        CFNumberRef             num;
        CFDictionaryRef         scoped;
+       CFDictionaryRef         services;
        CFArrayRef              supplemental;
 
        if (!isA_CFDictionary(proxy)) {
        CFArrayRef              supplemental;
 
        if (!isA_CFDictionary(proxy)) {
@@ -213,6 +230,13 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy)
                               NULL,
                               0);
 
                               NULL,
                               0);
 
+       validate_proxy_content(newProxy,
+                              kSCPropNetProxiesFallBackAllowed,
+                              NULL,
+                              NULL,
+                              NULL,
+                              0);
+
        // validate FTP passive setting
        num = CFDictionaryGetValue(newProxy, kSCPropNetProxiesFTPPassive);
        if (num != NULL) {
        // validate FTP passive setting
        num = CFDictionaryGetValue(newProxy, kSCPropNetProxiesFTPPassive);
        if (num != NULL) {
@@ -286,6 +310,22 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy)
                CFRelease(newScoped);
        }
 
                CFRelease(newScoped);
        }
 
+       // cleanup services proxies
+       services = CFDictionaryGetValue(newProxy, kSCPropNetProxiesServices);
+       if (isA_CFDictionary(services)) {
+               CFMutableDictionaryRef  newServices;
+
+               newServices = CFDictionaryCreateMutable(NULL,
+                                                     0,
+                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                     &kCFTypeDictionaryValueCallBacks);
+               CFDictionaryApplyFunction(services,
+                                         normalize_services_proxy,
+                                         newServices);
+               CFDictionarySetValue(newProxy, kSCPropNetProxiesServices, newServices);
+               CFRelease(newServices);
+       }
+
        // cleanup split/supplemental proxies
        supplemental = CFDictionaryGetValue(newProxy, kSCPropNetProxiesSupplemental);
        if (isA_CFArray(supplemental)) {
        // cleanup split/supplemental proxies
        supplemental = CFDictionaryGetValue(newProxy, kSCPropNetProxiesSupplemental);
        if (isA_CFArray(supplemental)) {
@@ -323,6 +363,19 @@ normalize_scoped_proxy(const void *key, const void *value, void *context)
        return;
 }
 
        return;
 }
 
+static void
+normalize_services_proxy(const void *key, const void *value, void *context)
+{
+       CFStringRef             serviceID       = (CFStringRef)key;
+       CFDictionaryRef         proxy           = (CFDictionaryRef)value;
+       CFMutableDictionaryRef  newServices     = (CFMutableDictionaryRef)context;
+
+       proxy = __SCNetworkProxiesCopyNormalized(proxy);
+       CFDictionarySetValue(newServices, serviceID, proxy);
+       CFRelease(proxy);
+
+       return;
+}
 
 static void
 normalize_supplemental_proxy(const void *value, void *context)
 
 static void
 normalize_supplemental_proxy(const void *value, void *context)
@@ -337,13 +390,35 @@ normalize_supplemental_proxy(const void *value, void *context)
        return;
 }
 
        return;
 }
 
-
 CFDictionaryRef
 SCDynamicStoreCopyProxies(SCDynamicStoreRef store)
 {
 CFDictionaryRef
 SCDynamicStoreCopyProxies(SCDynamicStoreRef store)
 {
+       return SCDynamicStoreCopyProxiesWithOptions(store, NULL);
+}
+
+const CFStringRef      kSCProxiesNoGlobal      = CFSTR("NO_GLOBAL");
+
+CFDictionaryRef
+SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef options)
+{
+       Boolean                 bypass  = FALSE;
        CFStringRef             key;
        CFDictionaryRef         proxies;
 
        CFStringRef             key;
        CFDictionaryRef         proxies;
 
+       if (options != NULL) {
+               CFBooleanRef    bypassGlobalOption;
+
+               if (isA_CFDictionary(options) == NULL) {
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return NULL;
+               }
+
+               bypassGlobalOption = CFDictionaryGetValue(options, kSCProxiesNoGlobal);
+               if (isA_CFBoolean(bypassGlobalOption) && CFBooleanGetValue(bypassGlobalOption)) {
+                       bypass = TRUE;
+               }
+       }
+
 
        /* copy proxy information from dynamic store */
 
 
        /* copy proxy information from dynamic store */
 
@@ -376,11 +451,14 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef      globalConfiguration,
                             CFStringRef        server,
                             CFStringRef        interface)
 {
                             CFStringRef        server,
                             CFStringRef        interface)
 {
-       CFMutableDictionaryRef  newProxy;
-       CFArrayRef              proxies         = NULL;
-       CFDictionaryRef         proxy;
-       int                     sc_status       = kSCStatusOK;
-       CFStringRef             trimmed         = NULL;
+       CFMutableDictionaryRef          newProxy;
+       static const audit_token_t      null_audit      = KERNEL_AUDIT_TOKEN_VALUE;
+       UUID_DEFINE(null_uuid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+       CFArrayRef                      proxies         = NULL;
+       CFDictionaryRef                 proxy;
+       int                             sc_status       = kSCStatusOK;
+       CFStringRef                     serviceID;
+       CFStringRef                     trimmed         = NULL;
 
        if (!isA_CFDictionary(globalConfiguration)) {
                // if no proxy configuration
 
        if (!isA_CFDictionary(globalConfiguration)) {
                // if no proxy configuration
@@ -428,6 +506,49 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef       globalConfiguration,
                return proxies;
        }
 
                return proxies;
        }
 
+       // Check for app-layer VPN proxy results (with or without server)
+       serviceID = VPNAppLayerCopyMatchingService(null_audit, 0, null_uuid, NULL, server, NULL, NULL);
+       if (serviceID != NULL) {
+               CFDictionaryRef serviceProxies  = NULL;
+
+               serviceProxies = CFDictionaryGetValue(globalConfiguration, kSCPropNetProxiesServices);
+               if (serviceProxies == NULL) {
+                       _SCErrorSet(kSCStatusOK);
+                       CFRelease(serviceID);
+                       goto app_layer_no_proxies;
+               }
+               if (!isA_CFDictionary(serviceProxies)) {
+                       _SCErrorSet(kSCStatusFailed);
+                       CFRelease(serviceID);
+                       goto app_layer_no_proxies;
+               }
+
+               proxy = CFDictionaryGetValue(serviceProxies, serviceID);
+               CFRelease(serviceID);
+               if (proxy == NULL) {
+                       _SCErrorSet(kSCStatusOK);
+                       goto app_layer_no_proxies;
+               }
+               if (!isA_CFDictionary(proxy)) {
+                       _SCErrorSet(kSCStatusFailed);
+                       goto app_layer_no_proxies;
+               }
+
+               proxies = CFArrayCreate(NULL, (const void **)&proxy, 1, &kCFTypeArrayCallBacks);
+               return proxies;
+
+           app_layer_no_proxies:
+
+               /*
+                * Rather than returning NULL, return an empty proxy configuration.
+                * This ensures that the global proxy configuration will not be used.
+                */
+               proxy = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL);
+               proxies = CFArrayCreate(NULL, (const void **)&proxy, 1, &kCFTypeArrayCallBacks);
+               CFRelease(proxy);
+               return proxies;
+       }
+
        if (server != NULL) {
                CFIndex                 i;
                CFMutableArrayRef       matching        = NULL;
        if (server != NULL) {
                CFIndex                 i;
                CFMutableArrayRef       matching        = NULL;
@@ -523,6 +644,7 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef        globalConfiguration,
 
        newProxy = CFDictionaryCreateMutableCopy(NULL, 0, globalConfiguration);
        CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesScoped);
 
        newProxy = CFDictionaryCreateMutableCopy(NULL, 0, globalConfiguration);
        CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesScoped);
+       CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesServices);
        CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplemental);
        proxies = CFArrayCreate(NULL, (const void **)&newProxy, 1, &kCFTypeArrayCallBacks);
        CFRelease(newProxy);
        CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplemental);
        proxies = CFArrayCreate(NULL, (const void **)&newProxy, 1, &kCFTypeArrayCallBacks);
        CFRelease(newProxy);
index 583307d9f9028110ec5a3ff96ad859ffd3b65e15..4df5ad60997cd5cfbd23dba75e57ee45b85f7e11 100644 (file)
@@ -61,7 +61,9 @@ const CFStringRef kSCEntNetSMB                                     = CFSTR("SMB"
 const CFStringRef kSCEntNet6to4                                    = CFSTR("6to4");
 
 
 const CFStringRef kSCEntNet6to4                                    = CFSTR("6to4");
 
 
+const CFStringRef kSCEntNetAppLayer                                = CFSTR("AppLayer");
 const CFStringRef kSCEntNetEAPOL                                   = CFSTR("EAPOL");
 const CFStringRef kSCEntNetEAPOL                                   = CFSTR("EAPOL");
+const CFStringRef kSCEntNetLinkIssues                              = CFSTR("LinkIssues");
 const CFStringRef kSCEntNetLinkQuality                             = CFSTR("LinkQuality");
 const CFStringRef kSCEntNetLoopback                                = CFSTR("Loopback");
 const CFStringRef kSCEntNetOnDemand                                = CFSTR("OnDemand");
 const CFStringRef kSCEntNetLinkQuality                             = CFSTR("LinkQuality");
 const CFStringRef kSCEntNetLoopback                                = CFSTR("Loopback");
 const CFStringRef kSCEntNetOnDemand                                = CFSTR("OnDemand");
@@ -114,6 +116,8 @@ const CFStringRef kSCPropNetDNSServerTimeout                       = CFSTR("Serv
 const CFStringRef kSCPropNetDNSSortList                            = CFSTR("SortList");
 const CFStringRef kSCPropNetDNSSupplementalMatchDomains            = CFSTR("SupplementalMatchDomains");
 const CFStringRef kSCPropNetDNSSupplementalMatchOrders             = CFSTR("SupplementalMatchOrders");
 const CFStringRef kSCPropNetDNSSortList                            = CFSTR("SortList");
 const CFStringRef kSCPropNetDNSSupplementalMatchDomains            = CFSTR("SupplementalMatchDomains");
 const CFStringRef kSCPropNetDNSSupplementalMatchOrders             = CFSTR("SupplementalMatchOrders");
+const CFStringRef kSCPropNetDNSServiceIdentifier                   = CFSTR("ServiceIdentifier");
+const CFStringRef kSCPropNetDNSSupplementalMatchDomainsNoSearch    = CFSTR("SupplementalMatchDomainsNoSearch");
 const CFStringRef kSCPropNetEthernetMediaSubType                   = CFSTR("MediaSubType");
 const CFStringRef kSCPropNetEthernetMediaOptions                   = CFSTR("MediaOptions");
 const CFStringRef kSCPropNetEthernetMTU                            = CFSTR("MTU");
 const CFStringRef kSCPropNetEthernetMediaSubType                   = CFSTR("MediaSubType");
 const CFStringRef kSCPropNetEthernetMediaOptions                   = CFSTR("MediaOptions");
 const CFStringRef kSCPropNetEthernetMTU                            = CFSTR("MTU");
@@ -156,6 +160,8 @@ const CFStringRef kSCPropNetIPSecXAuthEnabled                      = CFSTR("XAut
 const CFStringRef kSCPropNetIPSecXAuthName                         = CFSTR("XAuthName");
 const CFStringRef kSCPropNetIPSecXAuthPassword                     = CFSTR("XAuthPassword");
 const CFStringRef kSCPropNetIPSecXAuthPasswordEncryption           = CFSTR("XAuthPasswordEncryption");
 const CFStringRef kSCPropNetIPSecXAuthName                         = CFSTR("XAuthName");
 const CFStringRef kSCPropNetIPSecXAuthPassword                     = CFSTR("XAuthPassword");
 const CFStringRef kSCPropNetIPSecXAuthPasswordEncryption           = CFSTR("XAuthPasswordEncryption");
+const CFStringRef kSCPropNetIPSecDisconnectOnWake                  = CFSTR("DisconnectOnWake");
+const CFStringRef kSCPropNetIPSecDisconnectOnWakeTimer             = CFSTR("DisconnectOnWakeTimer");
 const CFStringRef kSCValNetIPSecAuthenticationMethodSharedSecret   = CFSTR("SharedSecret");
 const CFStringRef kSCValNetIPSecAuthenticationMethodCertificate    = CFSTR("Certificate");
 const CFStringRef kSCValNetIPSecAuthenticationMethodHybrid         = CFSTR("Hybrid");
 const CFStringRef kSCValNetIPSecAuthenticationMethodSharedSecret   = CFSTR("SharedSecret");
 const CFStringRef kSCValNetIPSecAuthenticationMethodCertificate    = CFSTR("Certificate");
 const CFStringRef kSCValNetIPSecAuthenticationMethodHybrid         = CFSTR("Hybrid");
@@ -209,6 +215,9 @@ const CFStringRef kSCPropNetIPv6RouteGatewayAddress                = CFSTR("Gate
 const CFStringRef kSCPropNet6to4Relay                              = CFSTR("Relay");
 const CFStringRef kSCPropNetLinkActive                             = CFSTR("Active");
 const CFStringRef kSCPropNetLinkDetaching                          = CFSTR("Detaching");
 const CFStringRef kSCPropNet6to4Relay                              = CFSTR("Relay");
 const CFStringRef kSCPropNetLinkActive                             = CFSTR("Active");
 const CFStringRef kSCPropNetLinkDetaching                          = CFSTR("Detaching");
+const CFStringRef kSCPropNetLinkIssuesModuleID                     = CFSTR("ModuleID");
+const CFStringRef kSCPropNetLinkIssuesInfo                         = CFSTR("Info");
+const CFStringRef kSCPropNetLinkIssuesTimeStamp                    = CFSTR("TimeStamp");
 const CFStringRef kSCPropNetLinkQuality                            = CFSTR("LinkQuality");
 const CFStringRef kSCPropNetModemAccessPointName                   = CFSTR("AccessPointName");
 const CFStringRef kSCPropNetModemConnectionPersonality             = CFSTR("ConnectionPersonality");
 const CFStringRef kSCPropNetLinkQuality                            = CFSTR("LinkQuality");
 const CFStringRef kSCPropNetModemAccessPointName                   = CFSTR("AccessPointName");
 const CFStringRef kSCPropNetModemConnectionPersonality             = CFSTR("ConnectionPersonality");
@@ -253,6 +262,8 @@ const CFStringRef kSCPropNetPPPDisconnectOnIdle                    = CFSTR("Disc
 const CFStringRef kSCPropNetPPPDisconnectOnIdleTimer               = CFSTR("DisconnectOnIdleTimer");
 const CFStringRef kSCPropNetPPPDisconnectOnLogout                  = CFSTR("DisconnectOnLogout");
 const CFStringRef kSCPropNetPPPDisconnectOnSleep                   = CFSTR("DisconnectOnSleep");
 const CFStringRef kSCPropNetPPPDisconnectOnIdleTimer               = CFSTR("DisconnectOnIdleTimer");
 const CFStringRef kSCPropNetPPPDisconnectOnLogout                  = CFSTR("DisconnectOnLogout");
 const CFStringRef kSCPropNetPPPDisconnectOnSleep                   = CFSTR("DisconnectOnSleep");
+const CFStringRef kSCPropNetPPPDisconnectOnWake                    = CFSTR("DisconnectOnWake");
+const CFStringRef kSCPropNetPPPDisconnectOnWakeTimer               = CFSTR("DisconnectOnWakeTimer");
 const CFStringRef kSCPropNetPPPDisconnectTime                      = CFSTR("DisconnectTime");
 const CFStringRef kSCPropNetPPPIdleReminderTimer                   = CFSTR("IdleReminderTimer");
 const CFStringRef kSCPropNetPPPIdleReminder                        = CFSTR("IdleReminder");
 const CFStringRef kSCPropNetPPPDisconnectTime                      = CFSTR("DisconnectTime");
 const CFStringRef kSCPropNetPPPIdleReminderTimer                   = CFSTR("IdleReminderTimer");
 const CFStringRef kSCPropNetPPPIdleReminder                        = CFSTR("IdleReminder");
@@ -347,9 +358,12 @@ const CFStringRef kSCPropNetProxiesProxyAutoConfigEnable           = CFSTR("Prox
 const CFStringRef kSCPropNetProxiesProxyAutoConfigJavaScript       = CFSTR("ProxyAutoConfigJavaScript");
 const CFStringRef kSCPropNetProxiesProxyAutoConfigURLString        = CFSTR("ProxyAutoConfigURLString");
 const CFStringRef kSCPropNetProxiesProxyAutoDiscoveryEnable        = CFSTR("ProxyAutoDiscoveryEnable");
 const CFStringRef kSCPropNetProxiesProxyAutoConfigJavaScript       = CFSTR("ProxyAutoConfigJavaScript");
 const CFStringRef kSCPropNetProxiesProxyAutoConfigURLString        = CFSTR("ProxyAutoConfigURLString");
 const CFStringRef kSCPropNetProxiesProxyAutoDiscoveryEnable        = CFSTR("ProxyAutoDiscoveryEnable");
+const CFStringRef kSCPropNetProxiesBypassAllowed                   = CFSTR("BypassAllowed");
+const CFStringRef kSCPropNetProxiesFallBackAllowed                 = CFSTR("FallBackAllowed");
 const CFStringRef kSCPropNetProxiesSupplementalMatchDomains        = CFSTR("SupplementalMatchDomains");
 const CFStringRef kSCPropNetProxiesSupplementalMatchOrders         = CFSTR("SupplementalMatchOrders");
 const CFStringRef kSCPropNetProxiesScoped                          = CFSTR("__SCOPED__");
 const CFStringRef kSCPropNetProxiesSupplementalMatchDomains        = CFSTR("SupplementalMatchDomains");
 const CFStringRef kSCPropNetProxiesSupplementalMatchOrders         = CFSTR("SupplementalMatchOrders");
 const CFStringRef kSCPropNetProxiesScoped                          = CFSTR("__SCOPED__");
+const CFStringRef kSCPropNetProxiesServices                        = CFSTR("__SERVICES__");
 const CFStringRef kSCPropNetProxiesSupplemental                    = CFSTR("__SUPPLEMENTAL__");
 const CFStringRef kSCPropNetProxiesSupplementalMatchDomain         = CFSTR("__MATCH_DOMAIN__");
 const CFStringRef kSCPropNetServicePrimaryRank                     = CFSTR("PrimaryRank");
 const CFStringRef kSCPropNetProxiesSupplemental                    = CFSTR("__SUPPLEMENTAL__");
 const CFStringRef kSCPropNetProxiesSupplementalMatchDomain         = CFSTR("__MATCH_DOMAIN__");
 const CFStringRef kSCPropNetServicePrimaryRank                     = CFSTR("PrimaryRank");
@@ -370,9 +384,12 @@ const CFStringRef kSCValNetSMBNetBIOSNodeTypeMixed                 = CFSTR("Mixe
 const CFStringRef kSCValNetSMBNetBIOSNodeTypeHybrid                = CFSTR("Hybrid");
 #endif // !TARGET_OS_IPHONE
 
 const CFStringRef kSCValNetSMBNetBIOSNodeTypeHybrid                = CFSTR("Hybrid");
 #endif // !TARGET_OS_IPHONE
 
+const CFStringRef kSCPropNetVPNAppRules                            = CFSTR("AppRules");
+const CFStringRef kSCPropNetVPNAuthCredentialPassword              = CFSTR("AuthCredentialPassword");
 const CFStringRef kSCPropNetVPNAuthName                            = CFSTR("AuthName");
 const CFStringRef kSCPropNetVPNAuthPassword                        = CFSTR("AuthPassword");
 const CFStringRef kSCPropNetVPNAuthPasswordEncryption              = CFSTR("AuthPasswordEncryption");
 const CFStringRef kSCPropNetVPNAuthName                            = CFSTR("AuthName");
 const CFStringRef kSCPropNetVPNAuthPassword                        = CFSTR("AuthPassword");
 const CFStringRef kSCPropNetVPNAuthPasswordEncryption              = CFSTR("AuthPasswordEncryption");
+const CFStringRef kSCPropNetVPNAuthPasswordPluginType              = CFSTR("AuthPasswordPluginType");
 const CFStringRef kSCPropNetVPNAuthenticationMethod                = CFSTR("AuthenticationMethod");
 const CFStringRef kSCPropNetVPNConnectTime                         = CFSTR("ConnectTime");
 const CFStringRef kSCPropNetVPNDisconnectOnFastUserSwitch          = CFSTR("DisconnectOnFastUserSwitch");
 const CFStringRef kSCPropNetVPNAuthenticationMethod                = CFSTR("AuthenticationMethod");
 const CFStringRef kSCPropNetVPNConnectTime                         = CFSTR("ConnectTime");
 const CFStringRef kSCPropNetVPNDisconnectOnFastUserSwitch          = CFSTR("DisconnectOnFastUserSwitch");
@@ -380,20 +397,57 @@ const CFStringRef kSCPropNetVPNDisconnectOnIdle                    = CFSTR("Disc
 const CFStringRef kSCPropNetVPNDisconnectOnIdleTimer               = CFSTR("DisconnectOnIdleTimer");
 const CFStringRef kSCPropNetVPNDisconnectOnLogout                  = CFSTR("DisconnectOnLogout");
 const CFStringRef kSCPropNetVPNDisconnectOnSleep                   = CFSTR("DisconnectOnSleep");
 const CFStringRef kSCPropNetVPNDisconnectOnIdleTimer               = CFSTR("DisconnectOnIdleTimer");
 const CFStringRef kSCPropNetVPNDisconnectOnLogout                  = CFSTR("DisconnectOnLogout");
 const CFStringRef kSCPropNetVPNDisconnectOnSleep                   = CFSTR("DisconnectOnSleep");
+const CFStringRef kSCPropNetVPNDisconnectOnWake                    = CFSTR("DisconnectOnWake");
+const CFStringRef kSCPropNetVPNDisconnectOnWakeTimer               = CFSTR("DisconnectOnWakeTimer");
 const CFStringRef kSCPropNetVPNLocalCertificate                    = CFSTR("LocalCertificate");
 const CFStringRef kSCPropNetVPNLogfile                             = CFSTR("Logfile");
 const CFStringRef kSCPropNetVPNMTU                                 = CFSTR("MTU");
 const CFStringRef kSCPropNetVPNOnDemandEnabled                     = CFSTR("OnDemandEnabled");
 const CFStringRef kSCPropNetVPNLocalCertificate                    = CFSTR("LocalCertificate");
 const CFStringRef kSCPropNetVPNLogfile                             = CFSTR("Logfile");
 const CFStringRef kSCPropNetVPNMTU                                 = CFSTR("MTU");
 const CFStringRef kSCPropNetVPNOnDemandEnabled                     = CFSTR("OnDemandEnabled");
+const CFStringRef kSCPropNetVPNOnDemandMatchAppEnabled             = CFSTR("OnDemandMatchAppEnabled");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsAlways          = CFSTR("OnDemandMatchDomainsAlways");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsOnRetry         = CFSTR("OnDemandMatchDomainsOnRetry");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsNever           = CFSTR("OnDemandMatchDomainsNever");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsAlways          = CFSTR("OnDemandMatchDomainsAlways");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsOnRetry         = CFSTR("OnDemandMatchDomainsOnRetry");
 const CFStringRef kSCPropNetVPNOnDemandMatchDomainsNever           = CFSTR("OnDemandMatchDomainsNever");
+const CFStringRef kSCPropNetVPNOnDemandRules                       = CFSTR("OnDemandRules");
+const CFStringRef kSCPropNetVPNOnDemandSuspended                   = CFSTR("OnDemandSuspended");
+const CFStringRef kSCPropNetVPNPluginCapability                    = CFSTR("PluginCapability");
 const CFStringRef kSCPropNetVPNRemoteAddress                       = CFSTR("RemoteAddress");
 const CFStringRef kSCPropNetVPNStatus                              = CFSTR("Status");
 const CFStringRef kSCPropNetVPNVerboseLogging                      = CFSTR("VerboseLogging");
 const CFStringRef kSCPropNetVPNRemoteAddress                       = CFSTR("RemoteAddress");
 const CFStringRef kSCPropNetVPNStatus                              = CFSTR("Status");
 const CFStringRef kSCPropNetVPNVerboseLogging                      = CFSTR("VerboseLogging");
+const CFStringRef kSCValNetVPNAppRuleAccountIdentifierMatch        = CFSTR("AccountIdentifierMatch");
+const CFStringRef kSCValNetVPNAppRuleDNSDomainMatch                = CFSTR("DNSDomainMatch");
+const CFStringRef kSCValNetVPNAppRuleExecutableMatch               = CFSTR("ExecutableMatch");
+const CFStringRef kSCValNetVPNAppRuleIdentifier                    = CFSTR("Identifier");
+const CFStringRef kSCValNetVPNAppRuleExecutableDesignatedRequirement = CFSTR("DesignatedRequirement");
+const CFStringRef kSCValNetVPNAppRuleExecutableSigningIdentifier   = CFSTR("SigningIdentifier");
 const CFStringRef kSCValNetVPNAuthenticationMethodPassword         = CFSTR("Password");
 const CFStringRef kSCValNetVPNAuthenticationMethodCertificate      = CFSTR("Certificate");
 const CFStringRef kSCValNetVPNAuthenticationMethodPassword         = CFSTR("Password");
 const CFStringRef kSCValNetVPNAuthenticationMethodCertificate      = CFSTR("Certificate");
+const CFStringRef kSCValNetVPNAuthPasswordEncryptionExternal       = CFSTR("External");
 const CFStringRef kSCValNetVPNAuthPasswordEncryptionKeychain       = CFSTR("Keychain");
 const CFStringRef kSCValNetVPNAuthPasswordEncryptionPrompt         = CFSTR("Prompt");
 const CFStringRef kSCValNetVPNAuthPasswordEncryptionKeychain       = CFSTR("Keychain");
 const CFStringRef kSCValNetVPNAuthPasswordEncryptionPrompt         = CFSTR("Prompt");
+const CFStringRef kSCPropNetVPNOnDemandRuleAction                  = CFSTR("Action");
+const CFStringRef kSCPropNetVPNOnDemandRuleActionParameters        = CFSTR("ActionParameters");
+const CFStringRef kSCPropNetVPNOnDemandRuleDNSDomainMatch          = CFSTR("DNSDomainMatch");
+const CFStringRef kSCPropNetVPNOnDemandRuleDNSServerAddressMatch   = CFSTR("DNSServerAddressMatch");
+const CFStringRef kSCPropNetVPNOnDemandRuleSSIDMatch               = CFSTR("SSIDMatch");
+const CFStringRef kSCPropNetVPNOnDemandRuleInterfaceTypeMatch      = CFSTR("InterfaceTypeMatch");
+const CFStringRef kSCPropNetVPNOnDemandRuleURLStringProbe          = CFSTR("URLStringProbe");
+const CFStringRef kSCValNetVPNOnDemandRuleActionAllow              = CFSTR("Allow");
+const CFStringRef kSCValNetVPNOnDemandRuleActionIgnore             = CFSTR("Ignore");
+const CFStringRef kSCValNetVPNOnDemandRuleActionConnect            = CFSTR("Connect");
+const CFStringRef kSCValNetVPNOnDemandRuleActionDisconnect         = CFSTR("Disconnect");
+const CFStringRef kSCValNetVPNOnDemandRuleActionEvaluateConnection = CFSTR("EvaluateConnection");
+const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersDomainAction = CFSTR("DomainAction");
+const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersDomains = CFSTR("Domains");
+const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers = CFSTR("RequiredDNSServers");
+const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe = CFSTR("RequiredURLStringProbe");
+const CFStringRef kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded = CFSTR("ConnectIfNeeded");
+const CFStringRef kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect = CFSTR("NeverConnect");
+
+
+const CFStringRef kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet = CFSTR("Ethernet");
+const CFStringRef kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi   = CFSTR("WiFi");
+const CFStringRef kSCValNetVPNPluginCapabilityAuth                 = CFSTR("Auth");
+const CFStringRef kSCValNetVPNPluginCapabilityConnect              = CFSTR("Connect");
 
 #if !TARGET_OS_IPHONE
 const CFStringRef kSCEntUsersConsoleUser                           = CFSTR("ConsoleUser");
 
 #if !TARGET_OS_IPHONE
 const CFStringRef kSCEntUsersConsoleUser                           = CFSTR("ConsoleUser");
index 22e2b0b40c96ed498118dd6da50b9b6617b383e8..af6f711430aaeec37977fd1fc62eabd2e7ab0431 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  *   kSCPropNetLocalHostName                            "LocalHostName"                CFString
  *
  *
  *   kSCPropNetLocalHostName                            "LocalHostName"                CFString
  *
- * kSCEntNetAirPort (Hardware) Entity Keys
- *
- *   kSCPropNetAirPortAllowNetCreation                  "AllowNetCreation"             CFNumber (0 or 1)
- *   kSCPropNetAirPortAuthPassword                      "AuthPassword"                 CFData
- *   kSCPropNetAirPortAuthPasswordEncryption            "AuthPasswordEncryption"       CFString
- *   kSCPropNetAirPortJoinMode                          "JoinMode"                     CFString
- *   kSCPropNetAirPortPowerEnabled                      "PowerEnabled"                 CFNumber (0 or 1)
- *   kSCPropNetAirPortPreferredNetwork                  "PreferredNetwork"             CFString
- *   kSCPropNetAirPortSavePasswords                     "SavePasswords"                CFNumber (0 or 1)
- *
- *   --- kSCPropNetAirPortJoinMode values ---
- *   kSCValNetAirPortJoinModeAutomatic                  "Automatic"
- *   kSCValNetAirPortJoinModePreferred                  "Preferred"
- *   kSCValNetAirPortJoinModeRanked                     "Ranked"
- *   kSCValNetAirPortJoinModeRecent                     "Recent"
- *   kSCValNetAirPortJoinModeStrongest                  "Strongest"
- *
- *   --- kSCPropNetAirPortPasswordEncryption values ---
- *   kSCValNetAirPortAuthPasswordEncryptionKeychain     "Keychain"
- *
  * kSCEntNetDNS Entity Keys
  *
  *   kSCPropNetDNSDomainName                            "DomainName"                   CFString
  * kSCEntNetDNS Entity Keys
  *
  *   kSCPropNetDNSDomainName                            "DomainName"                   CFString
@@ -806,79 +786,79 @@ extern const CFStringRef kSCPropNetLocalHostName;
 
 /*!
   @const kSCPropNetAirPortAllowNetCreation
 
 /*!
   @const kSCPropNetAirPortAllowNetCreation
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortAllowNetCreation;
 
 /*!
   @const kSCPropNetAirPortAuthPassword
  */
 extern const CFStringRef kSCPropNetAirPortAllowNetCreation;
 
 /*!
   @const kSCPropNetAirPortAuthPassword
-  @availability Introduced in Mac OS X 10.1.
+  @availability Introduced in Mac OS X 10.1, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortAuthPassword;
 
 /*!
   @const kSCPropNetAirPortAuthPasswordEncryption
  */
 extern const CFStringRef kSCPropNetAirPortAuthPassword;
 
 /*!
   @const kSCPropNetAirPortAuthPasswordEncryption
-  @availability Introduced in Mac OS X 10.1.
+  @availability Introduced in Mac OS X 10.1, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortAuthPasswordEncryption;
 
 /*!
   @const kSCPropNetAirPortJoinMode
  */
 extern const CFStringRef kSCPropNetAirPortAuthPasswordEncryption;
 
 /*!
   @const kSCPropNetAirPortJoinMode
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortJoinMode;
 
 /*!
   @const kSCPropNetAirPortPowerEnabled
  */
 extern const CFStringRef kSCPropNetAirPortJoinMode;
 
 /*!
   @const kSCPropNetAirPortPowerEnabled
-  @availability Introduced in Mac OS X 10.1.
+  @availability Introduced in Mac OS X 10.1, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortPowerEnabled;
 
 /*!
   @const kSCPropNetAirPortPreferredNetwork
  */
 extern const CFStringRef kSCPropNetAirPortPowerEnabled;
 
 /*!
   @const kSCPropNetAirPortPreferredNetwork
-  @availability Introduced in Mac OS X 10.1.
+  @availability Introduced in Mac OS X 10.1, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortPreferredNetwork;
 
 /*!
   @const kSCPropNetAirPortSavePasswords
  */
 extern const CFStringRef kSCPropNetAirPortPreferredNetwork;
 
 /*!
   @const kSCPropNetAirPortSavePasswords
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCPropNetAirPortSavePasswords;
 
 /*!
   @const kSCValNetAirPortJoinModeAutomatic
  */
 extern const CFStringRef kSCPropNetAirPortSavePasswords;
 
 /*!
   @const kSCValNetAirPortJoinModeAutomatic
-  @availability Introduced in Mac OS X 10.3.
+  @availability Introduced in Mac OS X 10.3, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortJoinModeAutomatic;
 
 /*!
   @const kSCValNetAirPortJoinModePreferred
  */
 extern const CFStringRef kSCValNetAirPortJoinModeAutomatic;
 
 /*!
   @const kSCValNetAirPortJoinModePreferred
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortJoinModePreferred;
 
 /*!
   @const kSCValNetAirPortJoinModeRanked
  */
 extern const CFStringRef kSCValNetAirPortJoinModePreferred;
 
 /*!
   @const kSCValNetAirPortJoinModeRanked
-  @availability Introduced in Mac OS X 10.4.
+  @availability Introduced in Mac OS X 10.4, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortJoinModeRanked;
 
 /*!
   @const kSCValNetAirPortJoinModeRecent
  */
 extern const CFStringRef kSCValNetAirPortJoinModeRanked;
 
 /*!
   @const kSCValNetAirPortJoinModeRecent
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortJoinModeRecent;
 
 /*!
   @const kSCValNetAirPortJoinModeStrongest
  */
 extern const CFStringRef kSCValNetAirPortJoinModeRecent;
 
 /*!
   @const kSCValNetAirPortJoinModeStrongest
-  @availability Introduced in Mac OS X 10.2.
+  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortJoinModeStrongest;
 
 /*!
   @const kSCValNetAirPortAuthPasswordEncryptionKeychain
  */
 extern const CFStringRef kSCValNetAirPortJoinModeStrongest;
 
 /*!
   @const kSCValNetAirPortAuthPasswordEncryptionKeychain
-  @availability Introduced in Mac OS X 10.3.
+  @availability Introduced in Mac OS X 10.3, but later deprecated in Mac OS X 10.9.
  */
 extern const CFStringRef kSCValNetAirPortAuthPasswordEncryptionKeychain;
 
  */
 extern const CFStringRef kSCValNetAirPortAuthPasswordEncryptionKeychain;
 
@@ -2375,6 +2355,7 @@ extern const CFStringRef kSCPropUsersConsoleUserGID;
 
 /* -------------------- Schema declarations -------------------- */
 
 
 /* -------------------- Schema declarations -------------------- */
 
+#define        __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_FUTURE  __AVAILABILITY_INTERNAL__IPHONE_2_0/*SPI*/
 
   SC_SCHEMA_DECLARATION(kSCResvLink, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
   #define kSCResvLink                                                   \
 
   SC_SCHEMA_DECLARATION(kSCResvLink, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
   #define kSCResvLink                                                   \
@@ -2652,79 +2633,79 @@ extern const CFStringRef kSCPropUsersConsoleUserGID;
                      ,"LocalHostName"                                  \
                      ,CFString                                         )
 
                      ,"LocalHostName"                                  \
                      ,CFString                                         )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAllowNetCreation, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAllowNetCreation, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortAllowNetCreation                             \
          SC_SCHEMA_KV(kSCPropNetAirPortAllowNetCreation                \
                      ,"AllowNetCreation"                               \
                      ,CFNumber (0 or 1)                                )
 
   #define kSCPropNetAirPortAllowNetCreation                             \
          SC_SCHEMA_KV(kSCPropNetAirPortAllowNetCreation                \
                      ,"AllowNetCreation"                               \
                      ,CFNumber (0 or 1)                                )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAuthPassword, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAuthPassword, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortAuthPassword                                 \
          SC_SCHEMA_KV(kSCPropNetAirPortAuthPassword                    \
                      ,"AuthPassword"                                   \
                      ,CFData                                           )
 
   #define kSCPropNetAirPortAuthPassword                                 \
          SC_SCHEMA_KV(kSCPropNetAirPortAuthPassword                    \
                      ,"AuthPassword"                                   \
                      ,CFData                                           )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAuthPasswordEncryption, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortAuthPasswordEncryption, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortAuthPasswordEncryption                       \
          SC_SCHEMA_KV(kSCPropNetAirPortAuthPasswordEncryption          \
                      ,"AuthPasswordEncryption"                         \
                      ,CFString                                         )
 
   #define kSCPropNetAirPortAuthPasswordEncryption                       \
          SC_SCHEMA_KV(kSCPropNetAirPortAuthPasswordEncryption          \
                      ,"AuthPasswordEncryption"                         \
                      ,CFString                                         )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortJoinMode, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortJoinMode, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortJoinMode                                     \
          SC_SCHEMA_KV(kSCPropNetAirPortJoinMode                        \
                      ,"JoinMode"                                       \
                      ,CFString                                         )
 
   #define kSCPropNetAirPortJoinMode                                     \
          SC_SCHEMA_KV(kSCPropNetAirPortJoinMode                        \
                      ,"JoinMode"                                       \
                      ,CFString                                         )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortPowerEnabled, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortPowerEnabled, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortPowerEnabled                                 \
          SC_SCHEMA_KV(kSCPropNetAirPortPowerEnabled                    \
                      ,"PowerEnabled"                                   \
                      ,CFNumber (0 or 1)                                )
 
   #define kSCPropNetAirPortPowerEnabled                                 \
          SC_SCHEMA_KV(kSCPropNetAirPortPowerEnabled                    \
                      ,"PowerEnabled"                                   \
                      ,CFNumber (0 or 1)                                )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortPreferredNetwork, __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortPreferredNetwork, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortPreferredNetwork                             \
          SC_SCHEMA_KV(kSCPropNetAirPortPreferredNetwork                \
                      ,"PreferredNetwork"                               \
                      ,CFString                                         )
 
   #define kSCPropNetAirPortPreferredNetwork                             \
          SC_SCHEMA_KV(kSCPropNetAirPortPreferredNetwork                \
                      ,"PreferredNetwork"                               \
                      ,CFString                                         )
 
-  SC_SCHEMA_DECLARATION(kSCPropNetAirPortSavePasswords, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCPropNetAirPortSavePasswords, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCPropNetAirPortSavePasswords                                \
          SC_SCHEMA_KV(kSCPropNetAirPortSavePasswords                   \
                      ,"SavePasswords"                                  \
                      ,CFNumber (0 or 1)                                )
 
   #define kSCPropNetAirPortSavePasswords                                \
          SC_SCHEMA_KV(kSCPropNetAirPortSavePasswords                   \
                      ,"SavePasswords"                                  \
                      ,CFNumber (0 or 1)                                )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeAutomatic, __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeAutomatic, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortJoinModeAutomatic                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeAutomatic                \
                      ,"Automatic"                                      \
                      ,                                                 )
 
   #define kSCValNetAirPortJoinModeAutomatic                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeAutomatic                \
                      ,"Automatic"                                      \
                      ,                                                 )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModePreferred, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModePreferred, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortJoinModePreferred                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModePreferred                \
                      ,"Preferred"                                      \
                      ,                                                 )
 
   #define kSCValNetAirPortJoinModePreferred                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModePreferred                \
                      ,"Preferred"                                      \
                      ,                                                 )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeRanked, __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeRanked, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortJoinModeRanked                                \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeRanked                   \
                      ,"Ranked"                                         \
                      ,                                                 )
 
   #define kSCValNetAirPortJoinModeRanked                                \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeRanked                   \
                      ,"Ranked"                                         \
                      ,                                                 )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeRecent, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeRecent, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortJoinModeRecent                                \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeRecent                   \
                      ,"Recent"                                         \
                      ,                                                 )
 
   #define kSCValNetAirPortJoinModeRecent                                \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeRecent                   \
                      ,"Recent"                                         \
                      ,                                                 )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeStrongest, __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortJoinModeStrongest, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortJoinModeStrongest                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeStrongest                \
                      ,"Strongest"                                      \
                      ,                                                 )
 
   #define kSCValNetAirPortJoinModeStrongest                             \
          SC_SCHEMA_KV(kSCValNetAirPortJoinModeStrongest                \
                      ,"Strongest"                                      \
                      ,                                                 )
 
-  SC_SCHEMA_DECLARATION(kSCValNetAirPortAuthPasswordEncryptionKeychain, __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0/*SPI*/))
+  SC_SCHEMA_DECLARATION(kSCValNetAirPortAuthPasswordEncryptionKeychain, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))
   #define kSCValNetAirPortAuthPasswordEncryptionKeychain                \
          SC_SCHEMA_KV(kSCValNetAirPortAuthPasswordEncryptionKeychain   \
                      ,"Keychain"                                       \
   #define kSCValNetAirPortAuthPasswordEncryptionKeychain                \
          SC_SCHEMA_KV(kSCValNetAirPortAuthPasswordEncryptionKeychain   \
                      ,"Keychain"                                       \
index ee3ca283b59f6c06d51b52b3950b3baeb665f7eb..509be002d5f80cb92050cca00960eba19e682be3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -34,7 +34,9 @@
  * Network Entity Keys
  *
  *   kSCEntNetCommCenter                                "com.apple.CommCenter"         CFDictionary
  * Network Entity Keys
  *
  *   kSCEntNetCommCenter                                "com.apple.CommCenter"         CFDictionary
+ *   kSCEntNetAppLayer                                  "AppLayer"                     CFDictionary
  *   kSCEntNetEAPOL                                     "EAPOL"                        CFDictionary
  *   kSCEntNetEAPOL                                     "EAPOL"                        CFDictionary
+ *   kSCEntNetLinkIssues                                "LinkIssues"                   CFDictionary
  *   kSCEntNetLinkQuality                               "LinkQuality"                  CFDictionary
  *   kSCEntNetLoopback                                  "Loopback"                     CFDictionary
  *   kSCEntNetOnDemand                                  "OnDemand"                     CFDictionary
  *   kSCEntNetLinkQuality                               "LinkQuality"                  CFDictionary
  *   kSCEntNetLoopback                                  "Loopback"                     CFDictionary
  *   kSCEntNetOnDemand                                  "OnDemand"                     CFDictionary
  *   kSCPropNetCommCenterAllowNetworkAccess             "AllowNetworkAccess"           CFNumber (0 or 1)
  *   kSCPropNetCommCenterAvailable                      "Available"                    CFNumber (0 or 1)
  *
  *   kSCPropNetCommCenterAllowNetworkAccess             "AllowNetworkAccess"           CFNumber (0 or 1)
  *   kSCPropNetCommCenterAvailable                      "Available"                    CFNumber (0 or 1)
  *
+ * kSCEntNetDNS Entity Keys
+ *
+ *   kSCPropNetDNSServiceIdentifier                     "ServiceIdentifier"            CFNumber
+ *   kSCPropNetDNSSupplementalMatchDomainsNoSearch      "SupplementalMatchDomainsNoSearch" CFNumber (0 or 1)
+ *
  * kSCEntNetEthernet (Hardware) Entity Keys
  *
  *   kSCPropNetEthernetCapabilityAV                     "AV"                           CFNumber (0 or 1)
  * kSCEntNetEthernet (Hardware) Entity Keys
  *
  *   kSCPropNetEthernetCapabilityAV                     "AV"                           CFNumber (0 or 1)
@@ -69,6 +76,8 @@
  *   kSCValNetInterfaceTypeLoopback                     "Loopback"
  *   kSCValNetInterfaceTypeVPN                          "VPN"
  *
  *   kSCValNetInterfaceTypeLoopback                     "Loopback"
  *   kSCValNetInterfaceTypeVPN                          "VPN"
  *
+ *   kSCPropNetIPSecDisconnectOnWake                    "DisconnectOnWake"             CFNumber (0 or 1)
+ *   kSCPropNetIPSecDisconnectOnWakeTimer               "DisconnectOnWakeTimer"        CFNumber
  * kSCEntNetIPSec Entity Keys
  *
  *   kSCPropNetIPSecLastCause                           "LastCause"                    CFNumber
  * kSCEntNetIPSec Entity Keys
  *
  *   kSCPropNetIPSecLastCause                           "LastCause"                    CFNumber
  *   kSCPropNetIPv6RoutePrefixLength                    "PrefixLength"                 CFNumber
  *   kSCPropNetIPv6RouteGatewayAddress                  "GatewayAddress"               CFString
  *
  *   kSCPropNetIPv6RoutePrefixLength                    "PrefixLength"                 CFNumber
  *   kSCPropNetIPv6RouteGatewayAddress                  "GatewayAddress"               CFString
  *
+ * kSCEntNetLinkIssues Entity Keys
+ *
+ *   kSCPropNetLinkIssuesModuleID                       "ModuleID"                     CFData
+ *   kSCPropNetLinkIssuesInfo                           "Info"                         CFData
+ *   kSCPropNetLinkIssuesTimeStamp                      "TimeStamp"                    CFDATE
+ *
  * kSCEntNetLinkQuality Entity Keys
  *
  *   kSCPropNetLinkQuality                              "LinkQuality"                  CFNumber
  *
  * kSCEntNetLinkQuality Entity Keys
  *
  *   kSCPropNetLinkQuality                              "LinkQuality"                  CFNumber
  *
+ *   kSCPropNetPPPDisconnectOnWake                      "DisconnectOnWake"             CFNumber (0 or 1)
+ *   kSCPropNetPPPDisconnectOnWakeTimer                 "DisconnectOnWakeTimer"        CFNumber
  * kSCEntNetPPP Entity Keys
  *
  *   --- OnDemand: ---
  * kSCEntNetPPP Entity Keys
  *
  *   --- OnDemand: ---
  *
  * kSCEntNetProxies Entity Keys
  *
  *
  * kSCEntNetProxies Entity Keys
  *
+ *   kSCPropNetProxiesBypassAllowed                     "BypassAllowed"                CFNumber (0 or 1)
+ *   kSCPropNetProxiesFallBackAllowed                   "FallBackAllowed"              CFNumber (0 or 1)
  *   kSCPropNetProxiesSupplementalMatchDomains          "SupplementalMatchDomains"     CFArray[CFString]
  *   kSCPropNetProxiesSupplementalMatchOrders           "SupplementalMatchOrders"      CFArray[CFNumber]
  *
  *   kSCPropNetProxiesScoped                            "__SCOPED__"                   CFDictionary
  *   kSCPropNetProxiesSupplementalMatchDomains          "SupplementalMatchDomains"     CFArray[CFString]
  *   kSCPropNetProxiesSupplementalMatchOrders           "SupplementalMatchOrders"      CFArray[CFNumber]
  *
  *   kSCPropNetProxiesScoped                            "__SCOPED__"                   CFDictionary
+ *   kSCPropNetProxiesServices                          "__SERVICES__"                 CFDictionary
  *   kSCPropNetProxiesSupplemental                      "__SUPPLEMENTAL__"             CFArray[CFDictionary]
  *   kSCPropNetProxiesSupplementalMatchDomain           "__MATCH_DOMAIN__"             CFString
  *
  *   kSCPropNetProxiesSupplemental                      "__SUPPLEMENTAL__"             CFArray[CFDictionary]
  *   kSCPropNetProxiesSupplementalMatchDomain           "__MATCH_DOMAIN__"             CFString
  *
  *
  * kSCEntNetVPN Entity Keys
  *
  *
  * kSCEntNetVPN Entity Keys
  *
+ *   kSCPropNetVPNAppRules                              "AppRules"                     CFArray[CFDictionary]
+ *   kSCPropNetVPNAuthCredentialPassword                "AuthCredentialPassword"       CFString
  *   kSCPropNetVPNAuthName                              "AuthName"                     CFString
  *   kSCPropNetVPNAuthPassword                          "AuthPassword"                 CFString
  *   kSCPropNetVPNAuthPasswordEncryption                "AuthPasswordEncryption"       CFString
  *   kSCPropNetVPNAuthName                              "AuthName"                     CFString
  *   kSCPropNetVPNAuthPassword                          "AuthPassword"                 CFString
  *   kSCPropNetVPNAuthPasswordEncryption                "AuthPasswordEncryption"       CFString
+ *   kSCPropNetVPNAuthPasswordPluginType                "AuthPasswordPluginType"       CFString
  *   kSCPropNetVPNAuthenticationMethod                  "AuthenticationMethod"         CFString
  *   kSCPropNetVPNConnectTime                           "ConnectTime"                  CFString
  *   kSCPropNetVPNDisconnectOnFastUserSwitch            "DisconnectOnFastUserSwitch"   CFNumber (0 or 1)
  *   kSCPropNetVPNAuthenticationMethod                  "AuthenticationMethod"         CFString
  *   kSCPropNetVPNConnectTime                           "ConnectTime"                  CFString
  *   kSCPropNetVPNDisconnectOnFastUserSwitch            "DisconnectOnFastUserSwitch"   CFNumber (0 or 1)
  *   kSCPropNetVPNDisconnectOnIdleTimer                 "DisconnectOnIdleTimer"        CFNumber
  *   kSCPropNetVPNDisconnectOnLogout                    "DisconnectOnLogout"           CFNumber (0 or 1)
  *   kSCPropNetVPNDisconnectOnSleep                     "DisconnectOnSleep"            CFNumber (0 or 1)
  *   kSCPropNetVPNDisconnectOnIdleTimer                 "DisconnectOnIdleTimer"        CFNumber
  *   kSCPropNetVPNDisconnectOnLogout                    "DisconnectOnLogout"           CFNumber (0 or 1)
  *   kSCPropNetVPNDisconnectOnSleep                     "DisconnectOnSleep"            CFNumber (0 or 1)
+ *   kSCPropNetVPNDisconnectOnWake                      "DisconnectOnWake"             CFNumber (0 or 1)
+ *   kSCPropNetVPNDisconnectOnWakeTimer                 "DisconnectOnWakeTimer"        CFNumber
  *   kSCPropNetVPNLocalCertificate                      "LocalCertificate"             CFData
  *   kSCPropNetVPNLogfile                               "Logfile"                      CFString
  *   kSCPropNetVPNMTU                                   "MTU"                          CFNumber
  *   kSCPropNetVPNOnDemandEnabled                       "OnDemandEnabled"              CFNumber (0 or 1)
  *   kSCPropNetVPNLocalCertificate                      "LocalCertificate"             CFData
  *   kSCPropNetVPNLogfile                               "Logfile"                      CFString
  *   kSCPropNetVPNMTU                                   "MTU"                          CFNumber
  *   kSCPropNetVPNOnDemandEnabled                       "OnDemandEnabled"              CFNumber (0 or 1)
+ *   kSCPropNetVPNOnDemandMatchAppEnabled               "OnDemandMatchAppEnabled"      CFBoolean
  *   kSCPropNetVPNOnDemandMatchDomainsAlways            "OnDemandMatchDomainsAlways"   CFArray[CFString]
  *   kSCPropNetVPNOnDemandMatchDomainsOnRetry           "OnDemandMatchDomainsOnRetry"  CFArray[CFString]
  *   kSCPropNetVPNOnDemandMatchDomainsNever             "OnDemandMatchDomainsNever"    CFArray[CFString]
  *   kSCPropNetVPNOnDemandMatchDomainsAlways            "OnDemandMatchDomainsAlways"   CFArray[CFString]
  *   kSCPropNetVPNOnDemandMatchDomainsOnRetry           "OnDemandMatchDomainsOnRetry"  CFArray[CFString]
  *   kSCPropNetVPNOnDemandMatchDomainsNever             "OnDemandMatchDomainsNever"    CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRules                         "OnDemandRules"                CFArray[CFDictionary]
+ *   kSCPropNetVPNOnDemandSuspended                     "OnDemandSuspended"            CFNumber
+ *   kSCPropNetVPNPluginCapability                      "PluginCapability"             CFString
  *   kSCPropNetVPNRemoteAddress                         "RemoteAddress"                CFString
  *   kSCPropNetVPNStatus                                "Status"                       CFNumber
  *   kSCPropNetVPNVerboseLogging                        "VerboseLogging"               CFNumber (0 or 1)
  *
  *   kSCPropNetVPNRemoteAddress                         "RemoteAddress"                CFString
  *   kSCPropNetVPNStatus                                "Status"                       CFNumber
  *   kSCPropNetVPNVerboseLogging                        "VerboseLogging"               CFNumber (0 or 1)
  *
+ *   --- kSCPropNetVPNAppRules [CFDictionary] keys ---
+ *   kSCValNetVPNAppRuleAccountIdentifierMatch          "AccountIdentifierMatch"       CFArray[CFString]
+ *   kSCValNetVPNAppRuleDNSDomainMatch                  "DNSDomainMatch"               CFArray[CFString]
+ *   kSCValNetVPNAppRuleExecutableMatch                 "ExecutableMatch"              CFArray[CFDictionary]
+ *   kSCValNetVPNAppRuleIdentifier                      "Identifier"                   CFString
+ *
+ *   --- kSCValNetVPNAppRuleExecutableMatch [CFDictionary] keys ---
+ *   kSCValNetVPNAppRuleExecutableDesignatedRequirement "DesignatedRequirement"        CFString
+ *   kSCValNetVPNAppRuleExecutableSigningIdentifier     "SigningIdentifier"            CFString
+ *
  *   --- kSCPropNetVPNAuthenticationMethod values ---
  *   kSCValNetVPNAuthenticationMethodPassword           "Password"
  *   kSCValNetVPNAuthenticationMethodCertificate        "Certificate"
  *
  *   --- kSCPropNetVPNAuthPasswordEncryption values ---
  *   --- kSCPropNetVPNAuthenticationMethod values ---
  *   kSCValNetVPNAuthenticationMethodPassword           "Password"
  *   kSCValNetVPNAuthenticationMethodCertificate        "Certificate"
  *
  *   --- kSCPropNetVPNAuthPasswordEncryption values ---
+ *   kSCValNetVPNAuthPasswordEncryptionExternal         "External"
  *   kSCValNetVPNAuthPasswordEncryptionKeychain         "Keychain"
  *   kSCValNetVPNAuthPasswordEncryptionPrompt           "Prompt"
  *
  *   kSCValNetVPNAuthPasswordEncryptionKeychain         "Keychain"
  *   kSCValNetVPNAuthPasswordEncryptionPrompt           "Prompt"
  *
+ *   --- kSCPropNetVPNOnDemandRules [CFDictionary] keys ---
+ *   kSCPropNetVPNOnDemandRuleAction                    "Action"                       CFString
+ *   kSCPropNetVPNOnDemandRuleActionParameters          "ActionParameters"             CFArray[CFDictionary]
+ *   kSCPropNetVPNOnDemandRuleDNSDomainMatch            "DNSDomainMatch"               CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRuleDNSServerAddressMatch     "DNSServerAddressMatch"        CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRuleSSIDMatch                 "SSIDMatch"                    CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRuleInterfaceTypeMatch        "InterfaceTypeMatch"           CFString
+ *   kSCPropNetVPNOnDemandRuleURLStringProbe            "URLStringProbe"               CFString
+ *
+ *   --- kSCPropNetVPNOnDemandRuleAction values ---
+ *   kSCValNetVPNOnDemandRuleActionAllow                "Allow"
+ *   kSCValNetVPNOnDemandRuleActionIgnore               "Ignore"
+ *   kSCValNetVPNOnDemandRuleActionConnect              "Connect"
+ *   kSCValNetVPNOnDemandRuleActionDisconnect           "Disconnect"
+ *   kSCValNetVPNOnDemandRuleActionEvaluateConnection   "EvaluateConnection"
+ *
+ *   --- kSCPropNetVPNOnDemandRuleActionParameters [CFDictionary] keys ---
+ *   kSCPropNetVPNOnDemandRuleActionParametersDomainAction "DomainAction"                 CFString
+ *   kSCPropNetVPNOnDemandRuleActionParametersDomains   "Domains"                      CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers "RequiredDNSServers"           CFArray[CFString]
+ *   kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe "RequiredURLStringProbe"       CFString
+ *
+ *   --- kSCPropNetVPNOnDemandRuleActionParametersDomainAction values ---
+ *   kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded "ConnectIfNeeded"
+ *   kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect "NeverConnect"
+ *
+ *   --- kSCPropNetVPNOnDemandRuleInterfaceTypeMatch values ---
+ *   kSCValNetVPNOnDemandRuleInterfaceTypeMatchCellular "Cellular"
+ *   kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet "Ethernet"
+ *   kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi     "WiFi"
+ *
+ *   --- kSCPropNetVPNPluginCapability values ---
+ *   kSCValNetVPNPluginCapabilityAuth                   "Auth"
+ *   kSCValNetVPNPluginCapabilityConnect                "Connect"
+ *
  * kSCCompSystem Properties
  *
  *   kSCPropSystemComputerNameRegion                    "ComputerNameRegion"           CFNumber
  * kSCCompSystem Properties
  *
  *   kSCPropSystemComputerNameRegion                    "ComputerNameRegion"           CFNumber
@@ -236,12 +311,24 @@ extern const CFStringRef kSCPrefVirtualNetworkInterfaces;
  */
 extern const CFStringRef kSCEntNetCommCenter;
 
  */
 extern const CFStringRef kSCEntNetCommCenter;
 
+/*!
+  @const kSCEntNetAppLayer
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCEntNetAppLayer;
+
 /*!
   @const kSCEntNetEAPOL
   @availability Introduced in Mac OS X 10.5.
  */
 extern const CFStringRef kSCEntNetEAPOL;
 
 /*!
   @const kSCEntNetEAPOL
   @availability Introduced in Mac OS X 10.5.
  */
 extern const CFStringRef kSCEntNetEAPOL;
 
+/*!
+  @const kSCEntNetLinkIssues
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCEntNetLinkIssues;
+
 /*!
   @const kSCEntNetLinkQuality
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCEntNetLinkQuality
   @availability Introduced in Mac OS X 10.7.
@@ -298,6 +385,22 @@ extern const CFStringRef kSCPropNetCommCenterAllowNetworkAccess;
  */
 extern const CFStringRef kSCPropNetCommCenterAvailable;
 
  */
 extern const CFStringRef kSCPropNetCommCenterAvailable;
 
+/*!
+  @group kSCEntNetDNS Entity Keys
+ */
+
+/*!
+  @const kSCPropNetDNSServiceIdentifier
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetDNSServiceIdentifier;
+
+/*!
+  @const kSCPropNetDNSSupplementalMatchDomainsNoSearch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetDNSSupplementalMatchDomainsNoSearch;
+
 /*!
   @group kSCEntNetEthernet (Hardware) Entity Keys
  */
 /*!
   @group kSCEntNetEthernet (Hardware) Entity Keys
  */
@@ -378,6 +481,18 @@ extern const CFStringRef kSCValNetInterfaceTypeLoopback;
  */
 extern const CFStringRef kSCValNetInterfaceTypeVPN;
 
  */
 extern const CFStringRef kSCValNetInterfaceTypeVPN;
 
+/*!
+  @const kSCPropNetIPSecDisconnectOnWake
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetIPSecDisconnectOnWake;
+
+/*!
+  @const kSCPropNetIPSecDisconnectOnWakeTimer
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetIPSecDisconnectOnWakeTimer;
+
 /*!
   @group kSCEntNetIPSec Entity Keys
  */
 /*!
   @group kSCEntNetIPSec Entity Keys
  */
@@ -498,6 +613,28 @@ extern const CFStringRef kSCPropNetIPv6RoutePrefixLength;
  */
 extern const CFStringRef kSCPropNetIPv6RouteGatewayAddress;
 
  */
 extern const CFStringRef kSCPropNetIPv6RouteGatewayAddress;
 
+/*!
+  @group kSCEntNetLinkIssues Entity Keys
+ */
+
+/*!
+  @const kSCPropNetLinkIssuesModuleID
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetLinkIssuesModuleID;
+
+/*!
+  @const kSCPropNetLinkIssuesInfo
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetLinkIssuesInfo;
+
+/*!
+  @const kSCPropNetLinkIssuesTimeStamp
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetLinkIssuesTimeStamp;
+
 /*!
   @group kSCEntNetLinkQuality Entity Keys
  */
 /*!
   @group kSCEntNetLinkQuality Entity Keys
  */
@@ -508,6 +645,18 @@ extern const CFStringRef kSCPropNetIPv6RouteGatewayAddress;
  */
 extern const CFStringRef kSCPropNetLinkQuality;
 
  */
 extern const CFStringRef kSCPropNetLinkQuality;
 
+/*!
+  @const kSCPropNetPPPDisconnectOnWake
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetPPPDisconnectOnWake;
+
+/*!
+  @const kSCPropNetPPPDisconnectOnWakeTimer
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetPPPDisconnectOnWakeTimer;
+
 /*!
   @group kSCEntNetPPP Entity Keys
  */
 /*!
   @group kSCEntNetPPP Entity Keys
  */
@@ -600,6 +749,18 @@ extern const CFStringRef kSCValNetPPPOnDemandPriorityLow;
   @group kSCEntNetProxies Entity Keys
  */
 
   @group kSCEntNetProxies Entity Keys
  */
 
+/*!
+  @const kSCPropNetProxiesBypassAllowed
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetProxiesBypassAllowed;
+
+/*!
+  @const kSCPropNetProxiesFallBackAllowed
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetProxiesFallBackAllowed;
+
 /*!
   @const kSCPropNetProxiesSupplementalMatchDomains
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetProxiesSupplementalMatchDomains
   @availability Introduced in Mac OS X 10.7.
@@ -618,6 +779,12 @@ extern const CFStringRef kSCPropNetProxiesSupplementalMatchOrders;
  */
 extern const CFStringRef kSCPropNetProxiesScoped;
 
  */
 extern const CFStringRef kSCPropNetProxiesScoped;
 
+/*!
+  @const kSCPropNetProxiesServices
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetProxiesServices;
+
 /*!
   @const kSCPropNetProxiesSupplemental
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetProxiesSupplemental
   @availability Introduced in Mac OS X 10.7.
@@ -668,6 +835,18 @@ extern const CFStringRef kSCValNetServicePrimaryRankNever;
   @group kSCEntNetVPN Entity Keys
  */
 
   @group kSCEntNetVPN Entity Keys
  */
 
+/*!
+  @const kSCPropNetVPNAppRules
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNAppRules;
+
+/*!
+  @const kSCPropNetVPNAuthCredentialPassword
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNAuthCredentialPassword;
+
 /*!
   @const kSCPropNetVPNAuthName
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetVPNAuthName
   @availability Introduced in Mac OS X 10.7.
@@ -686,6 +865,12 @@ extern const CFStringRef kSCPropNetVPNAuthPassword;
  */
 extern const CFStringRef kSCPropNetVPNAuthPasswordEncryption;
 
  */
 extern const CFStringRef kSCPropNetVPNAuthPasswordEncryption;
 
+/*!
+  @const kSCPropNetVPNAuthPasswordPluginType
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNAuthPasswordPluginType;
+
 /*!
   @const kSCPropNetVPNAuthenticationMethod
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetVPNAuthenticationMethod
   @availability Introduced in Mac OS X 10.7.
@@ -728,6 +913,18 @@ extern const CFStringRef kSCPropNetVPNDisconnectOnLogout;
  */
 extern const CFStringRef kSCPropNetVPNDisconnectOnSleep;
 
  */
 extern const CFStringRef kSCPropNetVPNDisconnectOnSleep;
 
+/*!
+  @const kSCPropNetVPNDisconnectOnWake
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNDisconnectOnWake;
+
+/*!
+  @const kSCPropNetVPNDisconnectOnWakeTimer
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNDisconnectOnWakeTimer;
+
 /*!
   @const kSCPropNetVPNLocalCertificate
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetVPNLocalCertificate
   @availability Introduced in Mac OS X 10.7.
@@ -752,6 +949,12 @@ extern const CFStringRef kSCPropNetVPNMTU;
  */
 extern const CFStringRef kSCPropNetVPNOnDemandEnabled;
 
  */
 extern const CFStringRef kSCPropNetVPNOnDemandEnabled;
 
+/*!
+  @const kSCPropNetVPNOnDemandMatchAppEnabled
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandMatchAppEnabled;
+
 /*!
   @const kSCPropNetVPNOnDemandMatchDomainsAlways
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetVPNOnDemandMatchDomainsAlways
   @availability Introduced in Mac OS X 10.7.
@@ -770,6 +973,24 @@ extern const CFStringRef kSCPropNetVPNOnDemandMatchDomainsOnRetry;
  */
 extern const CFStringRef kSCPropNetVPNOnDemandMatchDomainsNever;
 
  */
 extern const CFStringRef kSCPropNetVPNOnDemandMatchDomainsNever;
 
+/*!
+  @const kSCPropNetVPNOnDemandRules
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRules;
+
+/*!
+  @const kSCPropNetVPNOnDemandSuspended
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandSuspended;
+
+/*!
+  @const kSCPropNetVPNPluginCapability
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNPluginCapability;
+
 /*!
   @const kSCPropNetVPNRemoteAddress
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCPropNetVPNRemoteAddress
   @availability Introduced in Mac OS X 10.7.
@@ -788,6 +1009,42 @@ extern const CFStringRef kSCPropNetVPNStatus;
  */
 extern const CFStringRef kSCPropNetVPNVerboseLogging;
 
  */
 extern const CFStringRef kSCPropNetVPNVerboseLogging;
 
+/*!
+  @const kSCValNetVPNAppRuleAccountIdentifierMatch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleAccountIdentifierMatch;
+
+/*!
+  @const kSCValNetVPNAppRuleDNSDomainMatch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleDNSDomainMatch;
+
+/*!
+  @const kSCValNetVPNAppRuleExecutableMatch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleExecutableMatch;
+
+/*!
+  @const kSCValNetVPNAppRuleIdentifier
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleIdentifier;
+
+/*!
+  @const kSCValNetVPNAppRuleExecutableDesignatedRequirement
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleExecutableDesignatedRequirement;
+
+/*!
+  @const kSCValNetVPNAppRuleExecutableSigningIdentifier
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAppRuleExecutableSigningIdentifier;
+
 /*!
   @const kSCValNetVPNAuthenticationMethodPassword
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCValNetVPNAuthenticationMethodPassword
   @availability Introduced in Mac OS X 10.7.
@@ -800,6 +1057,12 @@ extern const CFStringRef kSCValNetVPNAuthenticationMethodPassword;
  */
 extern const CFStringRef kSCValNetVPNAuthenticationMethodCertificate;
 
  */
 extern const CFStringRef kSCValNetVPNAuthenticationMethodCertificate;
 
+/*!
+  @const kSCValNetVPNAuthPasswordEncryptionExternal
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNAuthPasswordEncryptionExternal;
+
 /*!
   @const kSCValNetVPNAuthPasswordEncryptionKeychain
   @availability Introduced in Mac OS X 10.7.
 /*!
   @const kSCValNetVPNAuthPasswordEncryptionKeychain
   @availability Introduced in Mac OS X 10.7.
@@ -812,6 +1075,144 @@ extern const CFStringRef kSCValNetVPNAuthPasswordEncryptionKeychain;
  */
 extern const CFStringRef kSCValNetVPNAuthPasswordEncryptionPrompt;
 
  */
 extern const CFStringRef kSCValNetVPNAuthPasswordEncryptionPrompt;
 
+/*!
+  @const kSCPropNetVPNOnDemandRuleAction
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleAction;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleActionParameters
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleActionParameters;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleDNSDomainMatch
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleDNSDomainMatch;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleDNSServerAddressMatch
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleDNSServerAddressMatch;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleSSIDMatch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleSSIDMatch;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleInterfaceTypeMatch
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleInterfaceTypeMatch;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleURLStringProbe
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleURLStringProbe;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionAllow
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionAllow;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionIgnore
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionIgnore;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionConnect
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionConnect;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionDisconnect
+  @availability Introduced in Mac OS X 10.8.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionDisconnect;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionEvaluateConnection
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionEvaluateConnection;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleActionParametersDomainAction
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersDomainAction;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleActionParametersDomains
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersDomains;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers;
+
+/*!
+  @const kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleInterfaceTypeMatchCellular
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleInterfaceTypeMatchCellular;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet;
+
+/*!
+  @const kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi;
+
+/*!
+  @const kSCValNetVPNPluginCapabilityAuth
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNPluginCapabilityAuth;
+
+/*!
+  @const kSCValNetVPNPluginCapabilityConnect
+  @availability Introduced in Mac OS X 10.9.
+ */
+extern const CFStringRef kSCValNetVPNPluginCapabilityConnect;
+
 /*!
   @group kSCCompSystem Properties
  */
 /*!
   @group kSCCompSystem Properties
  */
@@ -893,12 +1294,24 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,CFDictionary                                     )
 
 
                      ,CFDictionary                                     )
 
 
+  SC_SCHEMA_DECLARATION(kSCEntNetAppLayer, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCEntNetAppLayer                                             \
+         SC_SCHEMA_KV(kSCEntNetAppLayer                                \
+                     ,"AppLayer"                                       \
+                     ,CFDictionary                                     )
+
   SC_SCHEMA_DECLARATION(kSCEntNetEAPOL, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCEntNetEAPOL                                                \
          SC_SCHEMA_KV(kSCEntNetEAPOL                                   \
                      ,"EAPOL"                                          \
                      ,CFDictionary                                     )
 
   SC_SCHEMA_DECLARATION(kSCEntNetEAPOL, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCEntNetEAPOL                                                \
          SC_SCHEMA_KV(kSCEntNetEAPOL                                   \
                      ,"EAPOL"                                          \
                      ,CFDictionary                                     )
 
+  SC_SCHEMA_DECLARATION(kSCEntNetLinkIssues, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCEntNetLinkIssues                                           \
+         SC_SCHEMA_KV(kSCEntNetLinkIssues                              \
+                     ,"LinkIssues"                                     \
+                     ,CFDictionary                                     )
+
   SC_SCHEMA_DECLARATION(kSCEntNetLinkQuality, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCEntNetLinkQuality                                          \
          SC_SCHEMA_KV(kSCEntNetLinkQuality                             \
   SC_SCHEMA_DECLARATION(kSCEntNetLinkQuality, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCEntNetLinkQuality                                          \
          SC_SCHEMA_KV(kSCEntNetLinkQuality                             \
@@ -936,6 +1349,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,CFBoolean                                        )
 
 
                      ,CFBoolean                                        )
 
 
+  SC_SCHEMA_DECLARATION(kSCPropNetDNSServiceIdentifier, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetDNSServiceIdentifier                                \
+         SC_SCHEMA_KV(kSCPropNetDNSServiceIdentifier                   \
+                     ,"ServiceIdentifier"                              \
+                     ,CFNumber                                         )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetDNSSupplementalMatchDomainsNoSearch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetDNSSupplementalMatchDomainsNoSearch                 \
+         SC_SCHEMA_KV(kSCPropNetDNSSupplementalMatchDomainsNoSearch    \
+                     ,"SupplementalMatchDomainsNoSearch"               \
+                     ,CFNumber (0 or 1)                                )
+
   SC_SCHEMA_DECLARATION(kSCPropNetEthernetCapabilityAV, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetEthernetCapabilityAV                                \
          SC_SCHEMA_KV(kSCPropNetEthernetCapabilityAV                   \
   SC_SCHEMA_DECLARATION(kSCPropNetEthernetCapabilityAV, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetEthernetCapabilityAV                                \
          SC_SCHEMA_KV(kSCPropNetEthernetCapabilityAV                   \
@@ -1008,6 +1433,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"VPN"                                            \
                      ,                                                 )
 
                      ,"VPN"                                            \
                      ,                                                 )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetIPSecDisconnectOnWake, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetIPSecDisconnectOnWake                               \
+         SC_SCHEMA_KV(kSCPropNetIPSecDisconnectOnWake                  \
+                     ,"DisconnectOnWake"                               \
+                     ,CFNumber (0 or 1)                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetIPSecDisconnectOnWakeTimer, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetIPSecDisconnectOnWakeTimer                          \
+         SC_SCHEMA_KV(kSCPropNetIPSecDisconnectOnWakeTimer             \
+                     ,"DisconnectOnWakeTimer"                          \
+                     ,CFNumber                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetIPSecLastCause, __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0/*SPI*/))
   #define kSCPropNetIPSecLastCause                                      \
          SC_SCHEMA_KV(kSCPropNetIPSecLastCause                         \
   SC_SCHEMA_DECLARATION(kSCPropNetIPSecLastCause, __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0/*SPI*/))
   #define kSCPropNetIPSecLastCause                                      \
          SC_SCHEMA_KV(kSCPropNetIPSecLastCause                         \
@@ -1116,12 +1553,42 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"GatewayAddress"                                 \
                      ,CFString                                         )
 
                      ,"GatewayAddress"                                 \
                      ,CFString                                         )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetLinkIssuesModuleID, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetLinkIssuesModuleID                                  \
+         SC_SCHEMA_KV(kSCPropNetLinkIssuesModuleID                     \
+                     ,"ModuleID"                                       \
+                     ,CFData                                           )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetLinkIssuesInfo, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetLinkIssuesInfo                                      \
+         SC_SCHEMA_KV(kSCPropNetLinkIssuesInfo                         \
+                     ,"Info"                                           \
+                     ,CFData                                           )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetLinkIssuesTimeStamp, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetLinkIssuesTimeStamp                                 \
+         SC_SCHEMA_KV(kSCPropNetLinkIssuesTimeStamp                    \
+                     ,"TimeStamp"                                      \
+                     ,CFDATE                                           )
+
   SC_SCHEMA_DECLARATION(kSCPropNetLinkQuality, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetLinkQuality                                         \
          SC_SCHEMA_KV(kSCPropNetLinkQuality                            \
                      ,"LinkQuality"                                    \
                      ,CFNumber                                         )
 
   SC_SCHEMA_DECLARATION(kSCPropNetLinkQuality, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetLinkQuality                                         \
          SC_SCHEMA_KV(kSCPropNetLinkQuality                            \
                      ,"LinkQuality"                                    \
                      ,CFNumber                                         )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetPPPDisconnectOnWake, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetPPPDisconnectOnWake                                 \
+         SC_SCHEMA_KV(kSCPropNetPPPDisconnectOnWake                    \
+                     ,"DisconnectOnWake"                               \
+                     ,CFNumber (0 or 1)                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetPPPDisconnectOnWakeTimer, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetPPPDisconnectOnWakeTimer                            \
+         SC_SCHEMA_KV(kSCPropNetPPPDisconnectOnWakeTimer               \
+                     ,"DisconnectOnWakeTimer"                          \
+                     ,CFNumber                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetPPPOnDemandDomains, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCPropNetPPPOnDemandDomains                                  \
          SC_SCHEMA_KV(kSCPropNetPPPOnDemandDomains                     \
   SC_SCHEMA_DECLARATION(kSCPropNetPPPOnDemandDomains, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCPropNetPPPOnDemandDomains                                  \
          SC_SCHEMA_KV(kSCPropNetPPPOnDemandDomains                     \
@@ -1206,6 +1673,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"Low"                                            \
                      ,                                                 )
 
                      ,"Low"                                            \
                      ,                                                 )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetProxiesBypassAllowed, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetProxiesBypassAllowed                                \
+         SC_SCHEMA_KV(kSCPropNetProxiesBypassAllowed                   \
+                     ,"BypassAllowed"                                  \
+                     ,CFNumber (0 or 1)                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetProxiesFallBackAllowed, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetProxiesFallBackAllowed                              \
+         SC_SCHEMA_KV(kSCPropNetProxiesFallBackAllowed                 \
+                     ,"FallBackAllowed"                                \
+                     ,CFNumber (0 or 1)                                )
+
   SC_SCHEMA_DECLARATION(kSCPropNetProxiesSupplementalMatchDomains, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetProxiesSupplementalMatchDomains                     \
          SC_SCHEMA_KV(kSCPropNetProxiesSupplementalMatchDomains        \
   SC_SCHEMA_DECLARATION(kSCPropNetProxiesSupplementalMatchDomains, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetProxiesSupplementalMatchDomains                     \
          SC_SCHEMA_KV(kSCPropNetProxiesSupplementalMatchDomains        \
@@ -1224,6 +1703,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"__SCOPED__"                                     \
                      ,CFDictionary                                     )
 
                      ,"__SCOPED__"                                     \
                      ,CFDictionary                                     )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetProxiesServices, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetProxiesServices                                     \
+         SC_SCHEMA_KV(kSCPropNetProxiesServices                        \
+                     ,"__SERVICES__"                                   \
+                     ,CFDictionary                                     )
+
   SC_SCHEMA_DECLARATION(kSCPropNetProxiesSupplemental, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetProxiesSupplemental                                 \
          SC_SCHEMA_KV(kSCPropNetProxiesSupplemental                    \
   SC_SCHEMA_DECLARATION(kSCPropNetProxiesSupplemental, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))
   #define kSCPropNetProxiesSupplemental                                 \
          SC_SCHEMA_KV(kSCPropNetProxiesSupplemental                    \
@@ -1266,6 +1751,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"Never"                                          \
                      ,                                                 )
 
                      ,"Never"                                          \
                      ,                                                 )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNAppRules, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNAppRules                                         \
+         SC_SCHEMA_KV(kSCPropNetVPNAppRules                            \
+                     ,"AppRules"                                       \
+                     ,CFArray[CFDictionary]                            )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthCredentialPassword, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNAuthCredentialPassword                           \
+         SC_SCHEMA_KV(kSCPropNetVPNAuthCredentialPassword              \
+                     ,"AuthCredentialPassword"                         \
+                     ,CFString                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthName, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNAuthName                                         \
          SC_SCHEMA_KV(kSCPropNetVPNAuthName                            \
   SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthName, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNAuthName                                         \
          SC_SCHEMA_KV(kSCPropNetVPNAuthName                            \
@@ -1284,6 +1781,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"AuthPasswordEncryption"                         \
                      ,CFString                                         )
 
                      ,"AuthPasswordEncryption"                         \
                      ,CFString                                         )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthPasswordPluginType, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNAuthPasswordPluginType                           \
+         SC_SCHEMA_KV(kSCPropNetVPNAuthPasswordPluginType              \
+                     ,"AuthPasswordPluginType"                         \
+                     ,CFString                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthenticationMethod, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNAuthenticationMethod                             \
          SC_SCHEMA_KV(kSCPropNetVPNAuthenticationMethod                \
   SC_SCHEMA_DECLARATION(kSCPropNetVPNAuthenticationMethod, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNAuthenticationMethod                             \
          SC_SCHEMA_KV(kSCPropNetVPNAuthenticationMethod                \
@@ -1326,6 +1829,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"DisconnectOnSleep"                              \
                      ,CFNumber (0 or 1)                                )
 
                      ,"DisconnectOnSleep"                              \
                      ,CFNumber (0 or 1)                                )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNDisconnectOnWake, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNDisconnectOnWake                                 \
+         SC_SCHEMA_KV(kSCPropNetVPNDisconnectOnWake                    \
+                     ,"DisconnectOnWake"                               \
+                     ,CFNumber (0 or 1)                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNDisconnectOnWakeTimer, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNDisconnectOnWakeTimer                            \
+         SC_SCHEMA_KV(kSCPropNetVPNDisconnectOnWakeTimer               \
+                     ,"DisconnectOnWakeTimer"                          \
+                     ,CFNumber                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetVPNLocalCertificate, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNLocalCertificate                                 \
          SC_SCHEMA_KV(kSCPropNetVPNLocalCertificate                    \
   SC_SCHEMA_DECLARATION(kSCPropNetVPNLocalCertificate, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNLocalCertificate                                 \
          SC_SCHEMA_KV(kSCPropNetVPNLocalCertificate                    \
@@ -1350,6 +1865,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"OnDemandEnabled"                                \
                      ,CFNumber (0 or 1)                                )
 
                      ,"OnDemandEnabled"                                \
                      ,CFNumber (0 or 1)                                )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandMatchAppEnabled, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandMatchAppEnabled                          \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandMatchAppEnabled             \
+                     ,"OnDemandMatchAppEnabled"                        \
+                     ,CFBoolean                                        )
+
   SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandMatchDomainsAlways, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNOnDemandMatchDomainsAlways                       \
          SC_SCHEMA_KV(kSCPropNetVPNOnDemandMatchDomainsAlways          \
   SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandMatchDomainsAlways, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNOnDemandMatchDomainsAlways                       \
          SC_SCHEMA_KV(kSCPropNetVPNOnDemandMatchDomainsAlways          \
@@ -1368,6 +1889,24 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"OnDemandMatchDomainsNever"                      \
                      ,CFArray[CFString]                                )
 
                      ,"OnDemandMatchDomainsNever"                      \
                      ,CFArray[CFString]                                )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRules, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRules                                    \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRules                       \
+                     ,"OnDemandRules"                                  \
+                     ,CFArray[CFDictionary]                            )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandSuspended, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandSuspended                                \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandSuspended                   \
+                     ,"OnDemandSuspended"                              \
+                     ,CFNumber                                         )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNPluginCapability, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNPluginCapability                                 \
+         SC_SCHEMA_KV(kSCPropNetVPNPluginCapability                    \
+                     ,"PluginCapability"                               \
+                     ,CFString                                         )
+
   SC_SCHEMA_DECLARATION(kSCPropNetVPNRemoteAddress, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNRemoteAddress                                    \
          SC_SCHEMA_KV(kSCPropNetVPNRemoteAddress                       \
   SC_SCHEMA_DECLARATION(kSCPropNetVPNRemoteAddress, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCPropNetVPNRemoteAddress                                    \
          SC_SCHEMA_KV(kSCPropNetVPNRemoteAddress                       \
@@ -1386,6 +1925,42 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"VerboseLogging"                                 \
                      ,CFNumber (0 or 1)                                )
 
                      ,"VerboseLogging"                                 \
                      ,CFNumber (0 or 1)                                )
 
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleAccountIdentifierMatch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleAccountIdentifierMatch                     \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleAccountIdentifierMatch        \
+                     ,"AccountIdentifierMatch"                         \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleDNSDomainMatch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleDNSDomainMatch                             \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleDNSDomainMatch                \
+                     ,"DNSDomainMatch"                                 \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleExecutableMatch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleExecutableMatch                            \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleExecutableMatch               \
+                     ,"ExecutableMatch"                                \
+                     ,CFArray[CFDictionary]                            )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleIdentifier, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleIdentifier                                 \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleIdentifier                    \
+                     ,"Identifier"                                     \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleExecutableDesignatedRequirement, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleExecutableDesignatedRequirement              \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleExecutableDesignatedRequirement \
+                     ,"DesignatedRequirement"                          \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAppRuleExecutableSigningIdentifier, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAppRuleExecutableSigningIdentifier                \
+         SC_SCHEMA_KV(kSCValNetVPNAppRuleExecutableSigningIdentifier   \
+                     ,"SigningIdentifier"                              \
+                     ,CFString                                         )
+
   SC_SCHEMA_DECLARATION(kSCValNetVPNAuthenticationMethodPassword, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCValNetVPNAuthenticationMethodPassword                      \
          SC_SCHEMA_KV(kSCValNetVPNAuthenticationMethodPassword         \
   SC_SCHEMA_DECLARATION(kSCValNetVPNAuthenticationMethodPassword, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCValNetVPNAuthenticationMethodPassword                      \
          SC_SCHEMA_KV(kSCValNetVPNAuthenticationMethodPassword         \
@@ -1398,6 +1973,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"Certificate"                                    \
                      ,                                                 )
 
                      ,"Certificate"                                    \
                      ,                                                 )
 
+  SC_SCHEMA_DECLARATION(kSCValNetVPNAuthPasswordEncryptionExternal, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNAuthPasswordEncryptionExternal                    \
+         SC_SCHEMA_KV(kSCValNetVPNAuthPasswordEncryptionExternal       \
+                     ,"External"                                       \
+                     ,                                                 )
+
   SC_SCHEMA_DECLARATION(kSCValNetVPNAuthPasswordEncryptionKeychain, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCValNetVPNAuthPasswordEncryptionKeychain                    \
          SC_SCHEMA_KV(kSCValNetVPNAuthPasswordEncryptionKeychain       \
   SC_SCHEMA_DECLARATION(kSCValNetVPNAuthPasswordEncryptionKeychain, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0/*SPI*/))
   #define kSCValNetVPNAuthPasswordEncryptionKeychain                    \
          SC_SCHEMA_KV(kSCValNetVPNAuthPasswordEncryptionKeychain       \
@@ -1410,6 +1991,139 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions;
                      ,"Prompt"                                         \
                      ,                                                 )
 
                      ,"Prompt"                                         \
                      ,                                                 )
 
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleAction, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleAction                               \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleAction                  \
+                     ,"Action"                                         \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleActionParameters, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleActionParameters                     \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleActionParameters        \
+                     ,"ActionParameters"                               \
+                     ,CFArray[CFDictionary]                            )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleDNSDomainMatch, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleDNSDomainMatch                       \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleDNSDomainMatch          \
+                     ,"DNSDomainMatch"                                 \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleDNSServerAddressMatch, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleDNSServerAddressMatch                \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleDNSServerAddressMatch   \
+                     ,"DNSServerAddressMatch"                          \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleSSIDMatch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleSSIDMatch                            \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleSSIDMatch               \
+                     ,"SSIDMatch"                                      \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleInterfaceTypeMatch, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleInterfaceTypeMatch                   \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleInterfaceTypeMatch      \
+                     ,"InterfaceTypeMatch"                             \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleURLStringProbe, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleURLStringProbe                       \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleURLStringProbe          \
+                     ,"URLStringProbe"                                 \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionAllow, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionAllow                           \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionAllow              \
+                     ,"Allow"                                          \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionIgnore, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionIgnore                          \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionIgnore             \
+                     ,"Ignore"                                         \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionConnect, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionConnect                         \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionConnect            \
+                     ,"Connect"                                        \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionDisconnect, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionDisconnect                      \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionDisconnect         \
+                     ,"Disconnect"                                     \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionEvaluateConnection, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionEvaluateConnection              \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionEvaluateConnection \
+                     ,"EvaluateConnection"                             \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleActionParametersDomainAction, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleActionParametersDomainAction              \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleActionParametersDomainAction \
+                     ,"DomainAction"                                   \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleActionParametersDomains, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleActionParametersDomains              \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleActionParametersDomains \
+                     ,"Domains"                                        \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers              \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers \
+                     ,"RequiredDNSServers"                             \
+                     ,CFArray[CFString]                                )
+
+  SC_SCHEMA_DECLARATION(kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe              \
+         SC_SCHEMA_KV(kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe \
+                     ,"RequiredURLStringProbe"                         \
+                     ,CFString                                         )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded              \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded \
+                     ,"ConnectIfNeeded"                                \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect              \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect \
+                     ,"NeverConnect"                                   \
+                     ,                                                 )
+
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet              \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet \
+                     ,"Ethernet"                                       \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi                \
+         SC_SCHEMA_KV(kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi   \
+                     ,"WiFi"                                           \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNPluginCapabilityAuth, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNPluginCapabilityAuth                              \
+         SC_SCHEMA_KV(kSCValNetVPNPluginCapabilityAuth                 \
+                     ,"Auth"                                           \
+                     ,                                                 )
+
+  SC_SCHEMA_DECLARATION(kSCValNetVPNPluginCapabilityConnect, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))
+  #define kSCValNetVPNPluginCapabilityConnect                           \
+         SC_SCHEMA_KV(kSCValNetVPNPluginCapabilityConnect              \
+                     ,"Connect"                                        \
+                     ,                                                 )
+
   SC_SCHEMA_DECLARATION(kSCPropSystemComputerNameRegion, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCPropSystemComputerNameRegion                               \
          SC_SCHEMA_KV(kSCPropSystemComputerNameRegion                  \
   SC_SCHEMA_DECLARATION(kSCPropSystemComputerNameRegion, __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0/*SPI*/))
   #define kSCPropSystemComputerNameRegion                               \
          SC_SCHEMA_KV(kSCPropSystemComputerNameRegion                  \
diff --git a/SystemConfiguration.fproj/SNHelper.c b/SystemConfiguration.fproj/SNHelper.c
new file mode 100644 (file)
index 0000000..4ae0fd9
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2013 Apple Inc.
+ * All rights reserved.
+ */
+#include <errno.h>
+#include <syslog.h>
+#include <xpc/xpc.h>
+
+#include "SNHelperPrivate.h"
+
+static xpc_connection_t
+create_connection(dispatch_queue_t queue)
+{
+       xpc_connection_t new_connection;
+
+       new_connection = xpc_connection_create_mach_service(kSNHelperService, queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
+       if (isa_xpc_connection(new_connection)) {
+               xpc_connection_set_event_handler(new_connection,
+                       ^(xpc_object_t message) {
+                               if (isa_xpc_error(message)) {
+                                       syslog(LOG_INFO, "Got an error on the snhelper connection");
+                               } else if (isa_xpc_dictionary(message)) {
+                                       syslog(LOG_INFO, "Got an unexpected message on the snhelper connection");
+                               }
+                       });
+               xpc_connection_resume(new_connection);
+       }
+
+       return new_connection;
+}
+
+static xpc_object_t
+copy_response(xpc_object_t request)
+{
+       dispatch_queue_t conn_queue = dispatch_queue_create("snhelper request", NULL);
+       xpc_connection_t connection = create_connection(conn_queue);
+       xpc_object_t response = NULL;
+
+       if (connection) {
+               response = xpc_connection_send_message_with_reply_sync(connection, request);
+               xpc_connection_cancel(connection);
+               xpc_release(connection);
+       }
+
+       dispatch_release(conn_queue);
+
+       return response;
+}
+
+static int
+flow_divert_uuid_policy_operate(const uuid_t uuid, int operation)
+{
+       int result = 0;
+       xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
+       xpc_object_t response;
+
+       xpc_dictionary_set_uint64(request, kSNHelperMessageType, operation);
+       xpc_dictionary_set_uuid(request, kSNHelperMessageUUID, uuid);
+
+       response = copy_response(request);
+
+       if (isa_xpc_dictionary(response)) {
+               result = xpc_dictionary_get_int64(request, kSNHelperMessageResult);
+       } else {
+               result = EINVAL;
+       }
+
+       xpc_release(response);
+       xpc_release(request);
+
+       return result;
+}
+
+int
+snhelper_flow_divert_uuid_policy_add(const uuid_t uuid)
+{
+       return flow_divert_uuid_policy_operate(uuid, kSNHelperMessageTypeFlowDivertUUIDAdd);
+}
+
+int
+snhelper_flow_divert_uuid_policy_remove(const uuid_t uuid)
+{
+       return flow_divert_uuid_policy_operate(uuid, kSNHelperMessageTypeFlowDivertUUIDRemove);
+}
+
+int
+snhelper_flow_divert_uuid_policy_clear(void)
+{
+       int result = 0;
+       xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
+       xpc_object_t response;
+
+       xpc_dictionary_set_uint64(request, kSNHelperMessageType, kSNHelperMessageTypeFlowDivertUUIDClear);
+
+       response = copy_response(request);
+
+       if (isa_xpc_dictionary(response)) {
+               result = xpc_dictionary_get_int64(request, kSNHelperMessageResult);
+       } else {
+               result = EINVAL;
+       }
+
+       xpc_release(response);
+       xpc_release(request);
+
+       return result;
+}
+
+static bool
+isa_xpc_object_of_type(xpc_object_t obj, xpc_type_t type)
+{
+       return (obj != NULL && xpc_get_type(obj) == type);
+}
+
+bool
+isa_xpc_connection(xpc_object_t obj)
+{
+       return isa_xpc_object_of_type(obj, XPC_TYPE_CONNECTION);
+}
+
+bool
+isa_xpc_bool(xpc_object_t obj)
+{
+       return isa_xpc_object_of_type(obj, XPC_TYPE_BOOL);
+}
+
+bool
+isa_xpc_dictionary(xpc_object_t obj)
+{
+       return isa_xpc_object_of_type(obj, XPC_TYPE_DICTIONARY);
+}
+
+bool
+isa_xpc_error(xpc_object_t obj)
+{
+       return isa_xpc_object_of_type(obj, XPC_TYPE_ERROR);
+}
+
diff --git a/SystemConfiguration.fproj/SNHelperPrivate.h b/SystemConfiguration.fproj/SNHelperPrivate.h
new file mode 100644 (file)
index 0000000..4d2aefb
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Apple Inc.
+ * All rights reserved.
+ */
+
+#ifndef __SYSTEMCONFIGURATION_SNHELPER_PRIVATE_H__
+#define __SYSTEMCONFIGURATION_SNHELPER_PRIVATE_H__
+
+#include <xpc/xpc.h>
+
+#define kSNHelperService               "com.apple.snhelper"
+
+#define kSNHelperMessageType   "message-type"
+#define kSNHelperMessageUUID   "uuid"
+#define kSNHelperMessageResult "result-code"
+
+enum {
+       kSNHelperMessageTypeFlowDivertUUIDAdd,
+       kSNHelperMessageTypeFlowDivertUUIDRemove,
+       kSNHelperMessageTypeFlowDivertUUIDClear,
+};
+
+int snhelper_flow_divert_uuid_policy_add(const uuid_t uuid);
+int snhelper_flow_divert_uuid_policy_remove(const uuid_t uuid);
+int snhelper_flow_divert_uuid_policy_clear(void);
+
+bool isa_xpc_connection(xpc_object_t obj);
+bool isa_xpc_bool(xpc_object_t obj);
+bool isa_xpc_dictionary(xpc_object_t obj);
+bool isa_xpc_error(xpc_object_t obj);
+
+#endif /* __SYSTEMCONFIGURATION_SNHELPER_PRIVATE_H__ */
index a1337bd7631e5f60185eca300768681d9c7e672f..9cb4bc2740aab3a846b6ff1d8254457068ceec35 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2008-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008-2010, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -109,6 +109,9 @@ enum {
        kSCStatusConnectionNoService            = 5001, /* Network service for connection not available
                                                           __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0)
                                                         */
        kSCStatusConnectionNoService            = 5001, /* Network service for connection not available
                                                           __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0)
                                                         */
+       kSCStatusConnectionIgnore               = 5002, /* Network connection information not available at this time
+                                                          __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0)
+                                                        */
 };
 
 
 };
 
 
index a73c9100e709f1fd99ed1cd23f58258e9a2efd55..dc073605700584e0612681b8665a194f1e180127 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -104,10 +104,21 @@ add_configured_interface(const void *key, const void *value, void *context)
 
        // create the VLAN interface
        vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if);
 
        // create the VLAN interface
        vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if);
+       assert(vlan != NULL);
 
        // set physical interface and tag
        vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if,
                                                             kIncludeBondInterfaces);
 
        // set physical interface and tag
        vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if,
                                                             kIncludeBondInterfaces);
+       assert(vlan_physical != NULL);
+
+       // since we KNOW that the physical interface supported VLANs when
+       // it was first established it's OK to force that state here ...
+       // and this is needed for the case when the interface (e.g. a
+       // dongle) is not currently attached to the system
+       interfacePrivate = (SCNetworkInterfacePrivateRef)vlan_physical;
+       interfacePrivate->supportsVLAN = TRUE;
+
+       // and now we associate the physical interface and tag
        SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag);
        CFRelease(vlan_physical);
 
        SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag);
        CFRelease(vlan_physical);
 
@@ -134,126 +145,6 @@ add_configured_interface(const void *key, const void *value, void *context)
 }
 
 
 }
 
 
-static void
-add_legacy_configuration(addContextRef myContext)
-{
-       CFIndex                         i;
-       CFIndex                         n;
-       SCPreferencesRef                prefs;
-       CFArrayRef                      vlans;
-
-#define VLAN_PREFERENCES_ID            CFSTR("VirtualNetworkInterfaces.plist")
-#define        VLAN_PREFERENCES_VLANS          CFSTR("VLANs")
-#define        __kVLANInterface_interface      CFSTR("interface")      // e.g. vlan0, vlan1, ...
-#define        __kVLANInterface_device         CFSTR("device")         // e.g. en0, en1, ...
-#define __kVLANInterface_tag           CFSTR("tag")            // e.g. 1 <= tag <= 4094
-#define __kVLANInterface_options       CFSTR("options")        // e.g. UserDefinedName
-
-       prefs = SCPreferencesCreate(NULL, CFSTR("SCVLANInterfaceCopyAll"), VLAN_PREFERENCES_ID);
-       if (prefs == NULL) {
-               return;
-       }
-
-       vlans = SCPreferencesGetValue(prefs, VLAN_PREFERENCES_VLANS);
-       if ((vlans != NULL) && !isA_CFArray(vlans)) {
-               CFRelease(prefs);       // if the prefs are confused
-               return;
-       }
-
-       n = (vlans != NULL) ? CFArrayGetCount(vlans) : 0;
-       for (i = 0; i < n; i++) {
-               CFDictionaryRef                 dict;
-               SCNetworkInterfacePrivateRef    interfacePrivate;
-               Boolean                         ok;
-               CFDictionaryRef                 options;
-               CFStringRef                     path;
-               SCVLANInterfaceRef              vlan;
-               CFStringRef                     vlan_if;
-               CFDictionaryRef                 vlan_dict;
-               SCNetworkInterfaceRef           vlan_physical;
-               CFStringRef                     vlan_physical_if;
-               CFNumberRef                     vlan_tag;
-
-               vlan_dict = CFArrayGetValueAtIndex(vlans, i);
-               if (!isA_CFDictionary(vlan_dict)) {
-                       continue;       // if the prefs are confused
-               }
-
-               vlan_if = CFDictionaryGetValue(vlan_dict, __kVLANInterface_interface);
-               if (!isA_CFString(vlan_if)) {
-                       continue;       // if the prefs are confused
-               }
-
-               vlan_physical_if = CFDictionaryGetValue(vlan_dict, __kVLANInterface_device);
-               if (!isA_CFString(vlan_physical_if)) {
-                       continue;       // if the prefs are confused
-               }
-
-               vlan_tag = CFDictionaryGetValue(vlan_dict, __kVLANInterface_tag);
-               if (!isA_CFNumber(vlan_tag)) {
-                       continue;       // if the prefs are confused
-               }
-
-               // check if this VLAN interface has already been allocated
-               path = CFStringCreateWithFormat(NULL,
-                                               NULL,
-                                               CFSTR("/%@/%@/%@"),
-                                               kSCPrefVirtualNetworkInterfaces,
-                                               kSCNetworkInterfaceTypeVLAN,
-                                               vlan_if);
-               dict = SCPreferencesPathGetValue(myContext->prefs, path);
-               if (dict != NULL) {
-                       // if VLAN interface name not available
-                       CFRelease(path);
-                       continue;
-               }
-
-               // add a placeholder for the VLAN in the stored preferences
-               dict = CFDictionaryCreate(NULL,
-                                         NULL, NULL, 0,
-                                         &kCFTypeDictionaryKeyCallBacks,
-                                         &kCFTypeDictionaryValueCallBacks);
-               ok = SCPreferencesPathSetValue(myContext->prefs, path, dict);
-               CFRelease(dict);
-               CFRelease(path);
-               if (!ok) {
-                       // if the VLAN could not be saved
-                       continue;
-               }
-
-               // create the VLAN interface
-               vlan = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if);
-
-               // estabish link to the stored configuration
-               interfacePrivate = (SCNetworkInterfacePrivateRef)vlan;
-               interfacePrivate->prefs = CFRetain(myContext->prefs);
-
-               // set the interface and tag (which updates the stored preferences)
-               vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if,
-                                                                    kIncludeBondInterfaces);
-               SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag);
-               CFRelease(vlan_physical);
-
-               // set display name (which updates the stored preferences)
-               options = CFDictionaryGetValue(vlan_dict, __kVLANInterface_options);
-               if (isA_CFDictionary(options)) {
-                       CFStringRef     vlan_name;
-
-                       vlan_name = CFDictionaryGetValue(options, CFSTR("VLAN Name"));
-                       if (isA_CFString(vlan_name)) {
-                               SCVLANInterfaceSetLocalizedDisplayName(vlan, vlan_name);
-                       }
-               }
-
-               CFArrayAppendValue(myContext->vlans, vlan);
-               CFRelease(vlan);
-       }
-
-       CFRelease(prefs);
-       return;
-}
-
-
 static SCVLANInterfaceRef
 findVLANInterfaceAndTag(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CFNumberRef tag)
 {
 static SCVLANInterfaceRef
 findVLANInterfaceAndTag(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CFNumberRef tag)
 {
@@ -299,6 +190,22 @@ findVLANInterfaceAndTag(SCPreferencesRef prefs, SCNetworkInterfaceRef physical,
 #pragma mark SCVLANInterface APIs
 
 
 #pragma mark SCVLANInterface APIs
 
 
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef                   theDict,
+                            CFDictionaryApplierFunction        applier,
+                            void                               *context)
+{
+       CFAllocatorRef  myAllocator;
+       CFDictionaryRef myDict;
+
+       myAllocator = CFGetAllocator(theDict);
+       myDict      = CFDictionaryCreateCopy(myAllocator, theDict);
+       CFDictionaryApplyFunction(myDict, applier, context);
+       CFRelease(myDict);
+       return;
+}
+
+
 CFArrayRef
 SCVLANInterfaceCopyAll(SCPreferencesRef prefs)
 {
 CFArrayRef
 SCVLANInterfaceCopyAll(SCPreferencesRef prefs)
 {
@@ -315,20 +222,10 @@ SCVLANInterfaceCopyAll(SCPreferencesRef prefs)
                                        kSCPrefVirtualNetworkInterfaces,
                                        kSCNetworkInterfaceTypeVLAN);
        dict = SCPreferencesPathGetValue(prefs, path);
                                        kSCPrefVirtualNetworkInterfaces,
                                        kSCNetworkInterfaceTypeVLAN);
        dict = SCPreferencesPathGetValue(prefs, path);
+       CFRelease(path);
        if (isA_CFDictionary(dict)) {
        if (isA_CFDictionary(dict)) {
-               CFDictionaryApplyFunction(dict, add_configured_interface, &context);
-       } else {
-               // no VLAN configuration, upgrade from legacy configuration
-               dict = CFDictionaryCreate(NULL,
-                                         NULL, NULL, 0,
-                                         &kCFTypeDictionaryKeyCallBacks,
-                                         &kCFTypeDictionaryValueCallBacks);
-               (void) SCPreferencesPathSetValue(prefs, path, dict);
-               CFRelease(dict);
-
-               add_legacy_configuration(&context);
+               my_CFDictionaryApplyFunction(dict, add_configured_interface, &context);
        }
        }
-       CFRelease(path);
 
        return context.vlans;
 }
 
        return context.vlans;
 }
@@ -481,6 +378,7 @@ _SCVLANInterfaceCopyActive(void)
                // create the VLAN interface
                vlan_if = CFStringCreateWithCString(NULL, ifp->ifa_name, kCFStringEncodingASCII);
                vlan    = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if);
                // create the VLAN interface
                vlan_if = CFStringCreateWithCString(NULL, ifp->ifa_name, kCFStringEncodingASCII);
                vlan    = (SCVLANInterfaceRef)_SCVLANInterfaceCreatePrivate(NULL, vlan_if);
+               assert(vlan != NULL);
                CFRelease(vlan_if);
 
                // set the physical interface and tag
                CFRelease(vlan_if);
 
                // set the physical interface and tag
@@ -488,10 +386,12 @@ _SCVLANInterfaceCopyActive(void)
                vlan_physical_if = CFStringCreateWithCString(NULL, vlr_parent, kCFStringEncodingASCII);
                vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if,
                                                                     kIncludeBondInterfaces);
                vlan_physical_if = CFStringCreateWithCString(NULL, vlr_parent, kCFStringEncodingASCII);
                vlan_physical = _SCNetworkInterfaceCreateWithBSDName(NULL, vlan_physical_if,
                                                                     kIncludeBondInterfaces);
+               assert(vlan_physical != NULL);
                CFRelease(vlan_physical_if);
 
                vlr_tag  = vreq.vlr_tag;
                vlan_tag = CFNumberCreate(NULL, kCFNumberIntType, &vlr_tag);
                CFRelease(vlan_physical_if);
 
                vlr_tag  = vreq.vlr_tag;
                vlan_tag = CFNumberCreate(NULL, kCFNumberIntType, &vlr_tag);
+               assert(vlan_tag != NULL);
 
                SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag);
                CFRelease(vlan_physical);
 
                SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag);
                CFRelease(vlan_physical);
@@ -504,7 +404,9 @@ _SCVLANInterfaceCopyActive(void)
 
     done :
 
 
     done :
 
-       (void) close(s);
+       if (s != -1) {
+               (void) close(s);
+       }
        freeifaddrs(ifap);
        return vlans;
 }
        freeifaddrs(ifap);
        return vlans;
 }
@@ -564,7 +466,7 @@ SCVLANInterfaceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CF
                Boolean                         ok;
                CFStringRef                     path;
 
                Boolean                         ok;
                CFStringRef                     path;
 
-               vlan_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("vlan%d"), i);
+               vlan_if = CFStringCreateWithFormat(allocator, NULL, CFSTR("vlan%ld"), i);
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
                path    = CFStringCreateWithFormat(allocator,
                                                   NULL,
                                                   CFSTR("/%@/%@/%@"),
@@ -757,7 +659,9 @@ SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan, SCNetworkInte
                                     kSCPropVirtualNetworkInterfacesVLANInterface,
                                     SCNetworkInterfaceGetBSDName(physical));
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANTag, tag);
                                     kSCPropVirtualNetworkInterfacesVLANInterface,
                                     SCNetworkInterfaceGetBSDName(physical));
                CFDictionarySetValue(newDict, kSCPropVirtualNetworkInterfacesVLANTag, tag);
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -827,7 +731,9 @@ SCVLANInterfaceSetLocalizedDisplayName(SCVLANInterfaceRef vlan, CFStringRef newN
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
@@ -889,7 +795,9 @@ SCVLANInterfaceSetOptions(SCVLANInterfaceRef vlan, CFDictionaryRef newOptions)
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesVLANOptions);
                }
                } else {
                        CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesVLANOptions);
                }
-               ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               if (!CFEqual(dict, newDict)) {
+                       ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict);
+               }
                CFRelease(newDict);
                CFRelease(path);
        }
                CFRelease(newDict);
                CFRelease(path);
        }
diff --git a/SystemConfiguration.fproj/VPNAppLayer.c b/SystemConfiguration.fproj/VPNAppLayer.c
new file mode 100644 (file)
index 0000000..01901ca
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2012, 2013 Apple Inc.
+ * All rights reserved.
+ */
+
diff --git a/SystemConfiguration.fproj/VPNAppLayerPrivate.h b/SystemConfiguration.fproj/VPNAppLayerPrivate.h
new file mode 100644 (file)
index 0000000..01901ca
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * Copyright (c) 2012, 2013 Apple Inc.
+ * All rights reserved.
+ */
+
index 4e587a2ed67ba9e4914e36ce87ed3c91771ccc12..58acb55566492ca3c3a57fce6e6e7c18a8057c92 100644 (file)
@@ -1,4 +1,4 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  */
 
  */
 
index 4e587a2ed67ba9e4914e36ce87ed3c91771ccc12..d7d8fa0247537b254d6d0a6a92931ff2d699c006 100644 (file)
@@ -1,4 +1,4 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2011, 2013 Apple Inc. All rights reserved.
  */
 
  */
 
diff --git a/SystemConfiguration.fproj/VPNFlow.c b/SystemConfiguration.fproj/VPNFlow.c
new file mode 100644 (file)
index 0000000..d286c3d
--- /dev/null
@@ -0,0 +1,4 @@
+/*
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+ */
+
diff --git a/SystemConfiguration.fproj/VPNFlow.h b/SystemConfiguration.fproj/VPNFlow.h
new file mode 100644 (file)
index 0000000..d286c3d
--- /dev/null
@@ -0,0 +1,4 @@
+/*
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+ */
+
diff --git a/SystemConfiguration.fproj/VPNFlowPrivate.h b/SystemConfiguration.fproj/VPNFlowPrivate.h
new file mode 100644 (file)
index 0000000..a24886f
--- /dev/null
@@ -0,0 +1,4 @@
+/*
+ * Copyright (c) 2012, 2013 Apple Inc. All rights reserved.
+ */
+
index 2dfbed31dbaa81a2f2ce0217b4c23efcf99867bb..b4b9a4b6b4ec02e87eb5e9c9b04c3f2843e05968 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  */
 
 
  */
 
 
diff --git a/SystemConfiguration.fproj/VPNService.c b/SystemConfiguration.fproj/VPNService.c
new file mode 100644 (file)
index 0000000..8be02b4
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2012, 2013 Apple Inc. All rights reserved.
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SCPrivate.h>
+
+static Boolean
+isA_VPNService(CFTypeRef cf)
+{
+       if (isA_SCNetworkService(cf)) {
+               SCNetworkInterfaceRef   interface = SCNetworkServiceGetInterface((SCNetworkServiceRef)cf);
+
+               return (interface != NULL &&
+                       CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypeVPN));
+       }
+
+       return FALSE;
+}
+
+
+static CFArrayRef
+copy_matching_services(SCPreferencesRef prefs, CFStringRef identifierDomain, CFStringRef identifier)
+{
+       CFMutableArrayRef       results         = NULL;
+       CFArrayRef                      services;
+
+       services = SCNetworkServiceCopyAll(prefs);
+       if (services != NULL) {
+               CFIndex idx;
+               CFIndex service_count = CFArrayGetCount(services);
+
+               for (idx = 0; idx < service_count; idx++) {
+                       SCNetworkServiceRef             service = CFArrayGetValueAtIndex(services, idx);
+                       Boolean                                 matches = FALSE;
+
+                       if (isA_VPNService(service)) {
+                               if (isA_CFString(identifierDomain) && isA_CFString(identifier)) {
+                                       CFStringRef     ex_identifier = SCNetworkServiceCopyExternalID(service, identifierDomain);
+                                       if (ex_identifier != NULL) {
+                                               matches = CFEqual(ex_identifier, identifier);
+                                               CFRelease(ex_identifier);
+                                       }
+                               } else {
+                                       matches = TRUE;
+                               }
+                       }
+
+                       if (matches) {
+                               if (results == NULL) {
+                                       results = CFArrayCreateMutable(kCFAllocatorDefault, CFArrayGetCount(services) - idx, &kCFTypeArrayCallBacks);
+                               }
+                               CFArrayAppendValue(results, service);
+                       }
+               }
+
+               CFRelease(services);
+       }
+
+       return results;
+}
+
+
+static CFIndex
+find_app_rule(CFDictionaryRef vpn_config, CFStringRef ruleIdentifier)
+{
+       CFArrayRef      app_rules = CFDictionaryGetValue(vpn_config, kSCPropNetVPNAppRules);
+       CFIndex         idx;
+
+       if (isA_CFArray(app_rules)) {
+               CFIndex rule_count = CFArrayGetCount(app_rules);
+
+               for (idx = 0; idx < rule_count; idx++) {
+                       CFDictionaryRef rule = CFArrayGetValueAtIndex(app_rules, idx);
+
+                       if (isA_CFDictionary(rule)) {
+                               CFStringRef     rule_id = CFDictionaryGetValue(rule, kSCValNetVPNAppRuleIdentifier);
+
+                               if (CFEqual(ruleIdentifier, rule_id)) {
+                                       return idx;
+                               }
+                       }
+               }
+       }
+
+       return -1;
+}
+
+static Boolean
+validate_app_rule(CFDictionaryRef ruleSettings)
+{
+       CFIndex         account_count;
+       CFArrayRef      accounts;
+       Boolean         accounts_valid = FALSE;
+       CFArrayRef      executables;
+       Boolean         executables_valid = FALSE;
+       CFIndex         executable_count;
+       CFIndex         idx;
+       CFArrayRef      match_domains;
+
+       if (!isA_CFDictionary(ruleSettings)) {
+               return FALSE;
+       }
+
+       /* Validate the executable array. It needs to have at least one value. */
+       executables = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleExecutableMatch);
+       if (isA_CFArray(executables) && (executable_count = CFArrayGetCount(executables)) > 0) {
+               executables_valid = TRUE;
+               for (idx = 0; idx < executable_count; idx++) {
+                       CFDictionaryRef executable      = CFArrayGetValueAtIndex(executables, idx);
+
+                       if (isA_CFDictionary(executable)) {
+                               CFStringRef             signingID       = CFDictionaryGetValue(executable, kSCValNetVPNAppRuleExecutableSigningIdentifier);
+                               CFStringRef             requirement     = CFDictionaryGetValue(executable, kSCValNetVPNAppRuleExecutableDesignatedRequirement);
+
+                               if (!isA_CFString(signingID) || CFStringGetLength(signingID) == 0) {
+                                       executables_valid = FALSE;
+                                       break;
+                               }
+
+                               if (requirement != NULL) {
+                                       if (!isA_CFString(requirement) || CFStringGetLength(requirement) == 0) {
+                                               executables_valid = FALSE;
+                                               break;
+                                       }
+#if !TARGET_OS_IPHONE
+                               } else {
+                                       executables_valid = FALSE;
+                                       break;
+#endif /* !TARGET_OS_IPHONE */
+                               }
+                       }
+               }
+       }
+
+       /* Validate the accounts array. It needs to have at least one value. */
+       accounts = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleAccountIdentifierMatch);
+       if (isA_CFArray(accounts) && (account_count = CFArrayGetCount(accounts)) > 0) {
+               accounts_valid = TRUE;
+               for (idx = 0; idx < account_count; idx++) {
+                       CFStringRef     account = CFArrayGetValueAtIndex(accounts, idx);
+                       if (!isA_CFString(account)) {
+                               accounts_valid = FALSE;
+                               break;
+                       }
+               }
+       }
+
+       /* Either executables or accounts must be present */
+       if (!executables_valid && !accounts_valid) {
+               return FALSE;
+       }
+
+       /* Validate the domains array. It's optional, so just make sure that it contains only strings if it's present. */
+       match_domains = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleDNSDomainMatch);
+       if (match_domains != NULL) {
+               CFIndex match_domain_count;
+
+               if (!isA_CFArray(match_domains)) {
+                       return FALSE;
+               }
+
+               match_domain_count = CFArrayGetCount(match_domains);
+               for (idx = 0; idx < match_domain_count; idx++) {
+                       CFStringRef     domain  = CFArrayGetValueAtIndex(match_domains, idx);
+                       if (!isA_CFString(domain)) {
+                               return FALSE;
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
+
+CFArrayRef
+VPNServiceCopyAllMatchingExternalID(SCPreferencesRef prefs, CFStringRef identifierDomain, CFStringRef identifier)
+{
+       CFArrayRef      services;
+
+       if (prefs == NULL || !isA_CFString(identifierDomain) || !isA_CFString(identifier)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       services = copy_matching_services(prefs, identifierDomain, identifier);
+       if (services == NULL) {
+               _SCErrorSet(kSCStatusOK);
+       }
+
+       return services;
+}
+
+
+CFArrayRef
+VPNServiceCopyAll(SCPreferencesRef prefs)
+{
+       CFArrayRef      services;
+
+       if (prefs == NULL) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       services = copy_matching_services(prefs, NULL, NULL);
+       if (services == NULL) {
+               _SCErrorSet(kSCStatusOK);
+       }
+
+       return services;
+}
+
+
+CFArrayRef
+VPNServiceCopyAppRuleIDs(VPNServiceRef service)
+{
+       CFMutableArrayRef               results         = NULL;
+       CFDictionaryRef                 vpn_config;
+
+       if (!isA_VPNService(service)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       vpn_config = SCNetworkInterfaceGetConfiguration(SCNetworkServiceGetInterface(service));
+
+       if (isA_CFDictionary(vpn_config)) {
+               CFArrayRef      app_rules = CFDictionaryGetValue(vpn_config, kSCPropNetVPNAppRules);
+               if (isA_CFArray(app_rules)) {
+                       CFIndex app_rule_count = CFArrayGetCount(app_rules);
+                       CFIndex idx;
+                       results = CFArrayCreateMutable(kCFAllocatorDefault, app_rule_count, &kCFTypeArrayCallBacks);
+                       for (idx = 0; idx < app_rule_count; idx++) {
+                               CFDictionaryRef rule = CFArrayGetValueAtIndex(app_rules, idx);
+                               if (isA_CFDictionary(rule)) {
+                                       CFStringRef     rule_ID = CFDictionaryGetValue(rule, kSCValNetVPNAppRuleIdentifier);
+                                       if (isA_CFString(rule_ID)) {
+                                               CFArrayAppendValue(results, CFDictionaryGetValue(rule, kSCValNetVPNAppRuleIdentifier));
+                                       }
+                               }
+                       }
+                       if (CFArrayGetCount(results) == 0) {
+                               CFRelease(results);
+                               results = NULL;
+                       }
+               }
+       }
+
+       if (results == NULL) {
+               _SCErrorSet(kSCStatusOK);
+       }
+
+       return results;
+}
+
+
+Boolean
+VPNServiceSetAppRule(VPNServiceRef service, CFStringRef ruleIdentifier, CFDictionaryRef ruleSettings)
+{
+       CFArrayRef                              accounts;
+       CFArrayRef                              app_rules;
+       CFArrayRef                              executables;
+       CFIndex                                 existing_idx            = -1;
+       CFArrayRef                              match_domains;
+       CFMutableArrayRef               new_app_rules;
+       CFMutableDictionaryRef  new_settings;
+       CFMutableDictionaryRef  new_vpn_config;
+       CFDictionaryRef                 vpn_config;
+
+       /* Basic parameter validation */
+
+       if (!isA_VPNService(service) || !isA_CFString(ruleIdentifier)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (!validate_app_rule(ruleSettings)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       executables = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleExecutableMatch);
+       match_domains = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleDNSDomainMatch);
+       accounts = CFDictionaryGetValue(ruleSettings, kSCValNetVPNAppRuleAccountIdentifierMatch);
+
+       /* Set the new rule config, replacing any existing rule */
+
+       vpn_config = SCNetworkInterfaceGetConfiguration(SCNetworkServiceGetInterface(service));
+       if (isA_CFDictionary(vpn_config)) {
+               existing_idx = find_app_rule(vpn_config, ruleIdentifier);
+               new_vpn_config = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, vpn_config);
+       } else {
+               new_vpn_config = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                                                  0,
+                                                                                                  &kCFTypeDictionaryKeyCallBacks,
+                                                                                                  &kCFTypeDictionaryValueCallBacks);
+       }
+
+       app_rules = CFDictionaryGetValue(new_vpn_config, kSCPropNetVPNAppRules);
+       if (isA_CFArray(app_rules)) {
+               new_app_rules = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, app_rules);
+       } else {
+               new_app_rules = CFArrayCreateMutable(kCFAllocatorDefault,
+                                                                                    0,
+                                                                                    &kCFTypeArrayCallBacks);
+       }
+
+       new_settings = CFDictionaryCreateMutable(kCFAllocatorDefault,
+                                                                                        0,
+                                                                                        &kCFTypeDictionaryKeyCallBacks,
+                                                                                        &kCFTypeDictionaryValueCallBacks);
+
+       CFDictionarySetValue(new_settings, kSCValNetVPNAppRuleIdentifier, ruleIdentifier);
+       if (executables != NULL && CFArrayGetCount(executables) > 0) {
+               CFDictionarySetValue(new_settings, kSCValNetVPNAppRuleExecutableMatch, executables);
+       }
+       if (match_domains != NULL && CFArrayGetCount(match_domains) > 0) {
+               CFDictionarySetValue(new_settings, kSCValNetVPNAppRuleDNSDomainMatch, match_domains);
+       }
+       if (accounts != NULL && CFArrayGetCount(accounts) > 0) {
+               CFDictionarySetValue(new_settings, kSCValNetVPNAppRuleAccountIdentifierMatch, accounts);
+       }
+
+       if (existing_idx >= 0) {
+               CFArraySetValueAtIndex(new_app_rules, existing_idx, new_settings);
+       } else {
+               CFArrayAppendValue(new_app_rules, new_settings);
+       }
+
+       CFDictionarySetValue(new_vpn_config, kSCPropNetVPNAppRules, new_app_rules);
+
+       SCNetworkInterfaceSetConfiguration(SCNetworkServiceGetInterface(service), new_vpn_config);
+
+       CFRelease(new_vpn_config);
+       CFRelease(new_app_rules);
+       CFRelease(new_settings);
+
+       return TRUE;
+}
+
+
+CFDictionaryRef
+VPNServiceCopyAppRule(VPNServiceRef service, CFStringRef ruleIdentifier)
+{
+       CFDictionaryRef vpn_config;
+
+       if (!isA_VPNService(service) || !isA_CFString(ruleIdentifier)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       vpn_config = SCNetworkInterfaceGetConfiguration(SCNetworkServiceGetInterface(service));
+       if (isA_CFDictionary(vpn_config)) {
+               CFIndex idx = find_app_rule(vpn_config, ruleIdentifier);
+               if (idx >= 0) {
+                       CFArrayRef              app_rules               = CFDictionaryGetValue(vpn_config, kSCPropNetVPNAppRules);
+                       CFDictionaryRef ruleSettings    = CFArrayGetValueAtIndex(app_rules, idx);
+
+                       if (validate_app_rule(ruleSettings)) {
+                               return (CFDictionaryRef)CFRetain(ruleSettings);
+                       } else {
+                               _SCErrorSet(kSCStatusFailed);
+                       }
+               } else {
+                       _SCErrorSet(kSCStatusNoKey);
+               }
+       } else {
+               _SCErrorSet(kSCStatusFailed);
+       }
+
+       return NULL;
+}
+
+
+Boolean
+VPNServiceRemoveAppRule(VPNServiceRef service, CFStringRef ruleIdentifier)
+{
+       CFDictionaryRef vpn_config;
+
+       if (!isA_VPNService(service) || !isA_CFString(ruleIdentifier)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       vpn_config = SCNetworkInterfaceGetConfiguration(SCNetworkServiceGetInterface(service));
+       if (isA_CFDictionary(vpn_config)) {
+               CFIndex idx = find_app_rule(vpn_config, ruleIdentifier);
+               if (idx >= 0) {
+                       CFArrayRef                              current_app_rules;
+                       current_app_rules = CFDictionaryGetValue(vpn_config, kSCPropNetVPNAppRules);
+                       if (isA_CFArray(current_app_rules)) {
+                               CFMutableDictionaryRef  new_vpn_config;
+                               CFMutableArrayRef               new_app_rules;
+
+                               new_vpn_config = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, vpn_config);
+                               new_app_rules = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, current_app_rules);
+
+                               CFArrayRemoveValueAtIndex(new_app_rules, idx);
+                               if (CFArrayGetCount(new_app_rules) > 0) {
+                                       CFDictionarySetValue(new_vpn_config, kSCPropNetVPNAppRules, new_app_rules);
+                               } else {
+                                       CFDictionaryRemoveValue(new_vpn_config, kSCPropNetVPNAppRules);
+                               }
+
+                               SCNetworkInterfaceSetConfiguration(SCNetworkServiceGetInterface(service), new_vpn_config);
+
+                               CFRelease(new_vpn_config);
+                               CFRelease(new_app_rules);
+
+                               return TRUE;
+                       } else {
+                               _SCErrorSet(kSCStatusFailed);
+                       }
+               } else {
+                       _SCErrorSet(kSCStatusNoKey);
+               }
+       } else {
+               _SCErrorSet(kSCStatusFailed);
+       }
+
+       return FALSE;
+}
+
index 4e587a2ed67ba9e4914e36ce87ed3c91771ccc12..58acb55566492ca3c3a57fce6e6e7c18a8057c92 100644 (file)
@@ -1,4 +1,4 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  */
 
  */
 
index 4e587a2ed67ba9e4914e36ce87ed3c91771ccc12..58acb55566492ca3c3a57fce6e6e7c18a8057c92 100644 (file)
@@ -1,4 +1,4 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  */
 
  */
 
index 4e587a2ed67ba9e4914e36ce87ed3c91771ccc12..58acb55566492ca3c3a57fce6e6e7c18a8057c92 100644 (file)
@@ -1,4 +1,4 @@
 /*
 /*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
  */
 
  */
 
index a3a63cadd499440c5eb046117ea36dfe34c22386..fb930198dc5b7213b3e367562424a20641ac97bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003, 2005, 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2005, 2007, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 /*
  * Mach server port name
  */
 /*
  * Mach server port name
  */
+#if    !TARGET_IPHONE_SIMULATOR
 #define SCD_SERVER     "com.apple.SystemConfiguration.configd"
 #define SCD_SERVER     "com.apple.SystemConfiguration.configd"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define SCD_SERVER_HOST        "com.apple.SystemConfiguration.configd"
+#define SCD_SERVER     "com.apple.SystemConfiguration.configd_sim"
+#endif // !TARGET_IPHONE_SIMULATOR
 
 /*
  * Input arguments: serialized key's, list delimiters, ...
 
 /*
  * Input arguments: serialized key's, list delimiters, ...
index 9366fe4f0d24b5ca5f51c1ed2fec6031cdb9e8c3..e2c1089786dc6e73cf0bf4e2f882dc6e0e4d712f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2008, 2010-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2008, 2010-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -37,7 +37,6 @@
 #include "dy_framework.h"
 
 
 #include "dy_framework.h"
 
 
-
 #pragma mark -
 #pragma mark IOKit.framework APIs
 
 #pragma mark -
 #pragma mark IOKit.framework APIs
 
@@ -338,6 +337,9 @@ SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchLimit)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchLimitAll)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchSearchList)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecReturnRef)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchLimitAll)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchSearchList)
 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecReturnRef)
+SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecGuestAttributePid)
+SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecCodeInfoIdentifier)
+SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecCodeInfoUnique)
 
 __private_extern__ OSStatus
 _AuthorizationMakeExternalForm(AuthorizationRef authorization, AuthorizationExternalForm *extForm)
 
 __private_extern__ OSStatus
 _AuthorizationMakeExternalForm(AuthorizationRef authorization, AuthorizationExternalForm *extForm)
@@ -565,3 +567,4 @@ _SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data)
        return dyfunc ? dyfunc(allocator, data) : NULL;
 }
 
        return dyfunc ? dyfunc(allocator, data) : NULL;
 }
 
+
index 3cd5bd89cb02940312771b501f9d6cbe84a97ceb..0faee13b5c50a6b0e2f59c3cdd0e22785b3cf607 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2002-2008, 2010-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2008, 2010-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -204,6 +204,15 @@ CFTypeRef _kSecMatchSearchList();
 CFTypeRef _kSecReturnRef();
 #define kSecReturnRef _kSecReturnRef()
 
 CFTypeRef _kSecReturnRef();
 #define kSecReturnRef _kSecReturnRef()
 
+CFTypeRef _kSecGuestAttributePid();
+#define kSecGuestAttributePid _kSecGuestAttributePid()
+
+CFTypeRef _kSecCodeInfoIdentifier();
+#define kSecCodeInfoIdentifier _kSecCodeInfoIdentifier()
+
+CFTypeRef _kSecCodeInfoUnique();
+#define kSecCodeInfoUnique _kSecCodeInfoUnique()
+
 OSStatus
 _AuthorizationMakeExternalForm         (
                                        AuthorizationRef                authorization,
 OSStatus
 _AuthorizationMakeExternalForm         (
                                        AuthorizationRef                authorization,
@@ -355,6 +364,8 @@ _SecCertificateCreateWithData               (
                                        );
 #define SecCertificateCreateWithData _SecCertificateCreateWithData
 
                                        );
 #define SecCertificateCreateWithData _SecCertificateCreateWithData
 
+
+
 __END_DECLS
 
 #endif // _DY_FRAMEWORK_H
 __END_DECLS
 
 #endif // _DY_FRAMEWORK_H
index 5cff79768517a07f475a0f7cf14175a2807e8377..69114d554a57d54a3c5374ac3de36df7df0676f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -59,7 +59,7 @@
 
 char copyright_string[] =
 "/*\n"
 
 char copyright_string[] =
 "/*\n"
-" * Copyright (c) 2000-2011 Apple Inc. All rights reserved.\n"
+" * Copyright (c) 2000-2013 Apple Inc. All rights reserved.\n"
 " *\n"
 " * @APPLE_LICENSE_HEADER_START@\n"
 " * \n"
 " *\n"
 " * @APPLE_LICENSE_HEADER_START@\n"
 " * \n"
@@ -97,6 +97,10 @@ typedef enum {
        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_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
+       SC_10_4_10_9,   // deprecated in 10.9
        SC_10_6_IPHONE_2_0,
        SC_10_6_IPHONE_3_0,
        SC_10_7_IPHONE_4_0,
        SC_10_6_IPHONE_2_0,
        SC_10_6_IPHONE_3_0,
        SC_10_7_IPHONE_4_0,
@@ -107,6 +111,9 @@ typedef enum {
        SC_10_6_IPHONE_3_0_PRIVATE,
        SC_10_7_IPHONE_4_0_PRIVATE,
        SC_10_7_IPHONE_5_0_PRIVATE,
        SC_10_6_IPHONE_3_0_PRIVATE,
        SC_10_7_IPHONE_4_0_PRIVATE,
        SC_10_7_IPHONE_5_0_PRIVATE,
+       SC_10_8_IPHONE_6_0_PRIVATE,
+       SC_10_9_IPHONE_6_0_PRIVATE,
+       SC_10_9_IPHONE_7_0_PRIVATE,
        SC_IPHONE_2_0_PRIVATE,
        COMMENT_DEPRECATED,
        GROUP_DEPRECATED,
        SC_IPHONE_2_0_PRIVATE,
        COMMENT_DEPRECATED,
        GROUP_DEPRECATED,
@@ -141,14 +148,18 @@ typedef enum {
 #define CFARRAY_CFSTRING       "CFArray[CFString]"
 #define CFBOOLEAN              "CFBoolean"
 #define CFDATA                 "CFData"
 #define CFARRAY_CFSTRING       "CFArray[CFString]"
 #define CFBOOLEAN              "CFBoolean"
 #define CFDATA                 "CFData"
+#define CFDATE                 "CFDATE"
 #define CFDICTIONARY           "CFDictionary"
 #define CFNUMBER               "CFNumber"
 #define CFNUMBER_BOOL          "CFNumber (0 or 1)"
 #define CFSTRING               "CFString"
 
 #define CFDICTIONARY           "CFDictionary"
 #define CFNUMBER               "CFNumber"
 #define CFNUMBER_BOOL          "CFNumber (0 or 1)"
 #define CFSTRING               "CFString"
 
+#define APP                    "App"
 #define ARP                    "ARP"
 #define ACCESSPOINTNAME                "AccessPointName"
 #define ARP                    "ARP"
 #define ACCESSPOINTNAME                "AccessPointName"
+#define ACCOUNT                        "Account"
 #define ACSP                   "ACSP"                  // Apple Client Server Protocol
 #define ACSP                   "ACSP"                  // Apple Client Server Protocol
+#define ACTION                 "Action"
 #define ACTIVE                 "Active"
 #define ADDRESS                        "Address"
 #define ADDRESSES              "Addresses"
 #define ACTIVE                 "Active"
 #define ADDRESS                        "Address"
 #define ADDRESSES              "Addresses"
@@ -156,6 +167,8 @@ typedef enum {
 #define AGGRESSIVE             "Aggressive"
 #define AIRPORT                        "AirPort"
 #define ALERT                  "Alert"
 #define AGGRESSIVE             "Aggressive"
 #define AIRPORT                        "AirPort"
 #define ALERT                  "Alert"
+#define ALLOW                  "Allow"
+#define ALLOWED                        "Allowed"
 #define ALLOWNETCREATION       "AllowNetCreation"
 #define ALTERNATE              "Alternate"
 #define ALWAYS                 "Always"
 #define ALLOWNETCREATION       "AllowNetCreation"
 #define ALTERNATE              "Alternate"
 #define ALWAYS                 "Always"
@@ -173,12 +186,14 @@ typedef enum {
 #define BOOTP                  "BOOTP"
 #define        BRIDGE                  "Bridge"
 #define BROADCAST              "Broadcast"
 #define BOOTP                  "BOOTP"
 #define        BRIDGE                  "Bridge"
 #define BROADCAST              "Broadcast"
+#define BYPASS                 "Bypass"
 #define CALLWAITINGAUDIBLEALERT        "CallWaitingAudibleAlert"
 #define CAPABILITY             "Capability"
 #define CAPABILITIES           "Capabilities"
 #define CAUSE                  "Cause"
 #define CCP                    "CCP"
 #define CHAP                   "CHAP"
 #define CALLWAITINGAUDIBLEALERT        "CallWaitingAudibleAlert"
 #define CAPABILITY             "Capability"
 #define CAPABILITIES           "Capabilities"
 #define CAUSE                  "Cause"
 #define CCP                    "CCP"
 #define CHAP                   "CHAP"
+#define CELLULAR               "Cellular"
 #define CERTIFICATE            "Certificate"
 #define COMM                   "Comm"
 #define COMPATIBLE             "Compatible"
 #define CERTIFICATE            "Certificate"
 #define COMM                   "Comm"
 #define COMPATIBLE             "Compatible"
@@ -187,6 +202,7 @@ typedef enum {
 #define COMPRESSIONVJ          "CompressionVJ"
 #define COMPUTERNAME           "ComputerName"
 #define CONFIGMETHOD           "ConfigMethod"
 #define COMPRESSIONVJ          "CompressionVJ"
 #define COMPUTERNAME           "ComputerName"
 #define CONFIGMETHOD           "ConfigMethod"
+#define CONNECT                        "Connect"
 #define CONNECTDELAY           "ConnectDelay"
 #define CONNECTION             "Connection"
 #define CONNECTSPEED           "ConnectSpeed"
 #define CONNECTDELAY           "ConnectDelay"
 #define CONNECTION             "Connection"
 #define CONNECTSPEED           "ConnectSpeed"
@@ -194,10 +210,12 @@ typedef enum {
 #define CONSERVATIVE           "Conservative"
 #define CONSOLEUSER            "ConsoleUser"
 #define CONTEXTID              "ContextID"
 #define CONSERVATIVE           "Conservative"
 #define CONSOLEUSER            "ConsoleUser"
 #define CONTEXTID              "ContextID"
+#define CREDENTIAL             "Credential"
 #define CURRENTSET             "CurrentSet"
 #define DATACOMPRESSION                "DataCompression"
 #define DEFAULT                        "Default"
 #define DEFAULTZONE            "DefaultZone"
 #define CURRENTSET             "CurrentSet"
 #define DATACOMPRESSION                "DataCompression"
 #define DEFAULT                        "Default"
 #define DEFAULTZONE            "DefaultZone"
+#define DESIGNATED             "Designated"
 #define DEST                   "Dest"
 #define DESTINATION            "Destination"
 #define DETACHING              "Detaching"
 #define DEST                   "Dest"
 #define DESTINATION            "Destination"
 #define DETACHING              "Detaching"
@@ -207,12 +225,15 @@ typedef enum {
 #define DHCPCLIENTID           "DHCPClientID"
 #define DIALMODE               "DialMode"
 #define DIALONDEMAND           "DialOnDemand"
 #define DHCPCLIENTID           "DHCPClientID"
 #define DIALMODE               "DialMode"
 #define DIALONDEMAND           "DialOnDemand"
+#define DISCONNECT             "Disconnect"
 #define DISCONNECTONANSWER     "DisconnectOnAnswer"
 #define DISCONNECTONFASTUSERSWITCH     "DisconnectOnFastUserSwitch"
 #define DISCONNECTONIDLE       "DisconnectOnIdle"
 #define DISCONNECTONIDLETIMER  "DisconnectOnIdleTimer"
 #define DISCONNECTONLOGOUT     "DisconnectOnLogout"
 #define DISCONNECTONSLEEP      "DisconnectOnSleep"
 #define DISCONNECTONANSWER     "DisconnectOnAnswer"
 #define DISCONNECTONFASTUSERSWITCH     "DisconnectOnFastUserSwitch"
 #define DISCONNECTONIDLE       "DisconnectOnIdle"
 #define DISCONNECTONIDLETIMER  "DisconnectOnIdleTimer"
 #define DISCONNECTONLOGOUT     "DisconnectOnLogout"
 #define DISCONNECTONSLEEP      "DisconnectOnSleep"
+#define DISCONNECTONWAKE       "DisconnectOnWake"
+#define DISCONNECTONWAKETIMER  "DisconnectOnWakeTimer"
 #define DISCONNECTTIME         "DisconnectTime"
 #define DISPLAYTERMINALWINDOW  "DisplayTerminalWindow"
 #define DNS                    "DNS"
 #define DISCONNECTTIME         "DisconnectTime"
 #define DISPLAYTERMINALWINDOW  "DisplayTerminalWindow"
 #define DNS                    "DNS"
@@ -229,10 +250,14 @@ typedef enum {
 #define ENCRYPTION             "Encryption"
 #define ERRORCORRECTION                "ErrorCorrection"
 #define ETHERNET               "Ethernet"
 #define ENCRYPTION             "Encryption"
 #define ERRORCORRECTION                "ErrorCorrection"
 #define ETHERNET               "Ethernet"
+#define EVALUATE               "Evaluate"
 #define EXCEPTIONSLIST         "ExceptionsList"
 #define EXCLUDED               "Excluded"
 #define EXCLUDESIMPLEHOSTNAMES "ExcludeSimpleHostnames"
 #define EXCEPTIONSLIST         "ExceptionsList"
 #define EXCLUDED               "Excluded"
 #define EXCLUDESIMPLEHOSTNAMES "ExcludeSimpleHostnames"
+#define EXECUTABLE             "Executable"
+#define EXTERNAL               "External"
 #define FAILOVER               "Failover"
 #define FAILOVER               "Failover"
+#define        FALLBACK                "FallBack"
 #define FILE                   "File"
 #define FIREWIRE               "FireWire"
 #define FIRST                  "First"
 #define FILE                   "File"
 #define FIREWIRE               "FireWire"
 #define FIRST                  "First"
@@ -250,12 +275,16 @@ typedef enum {
 #define HTTP                   "HTTP"
 #define HTTPS                  "HTTPS"
 #define HYBRID                 "Hybrid"
 #define HTTP                   "HTTP"
 #define HTTPS                  "HTTPS"
 #define HYBRID                 "Hybrid"
+#define IDENTIFIER             "Identifier"
 #define IDLEREMINDER           "IdleReminder"
 #define IDLEREMINDERTIMER      "IdleReminderTimer"
 #define IDLEREMINDER           "IdleReminder"
 #define IDLEREMINDERTIMER      "IdleReminderTimer"
+#define IFNEEDED               "IfNeeded"
+#define IGNORE                 "Ignore"
 #define IGNOREDIALTONE         "IgnoreDialTone"
 #define IGNORELINKSTATUS       "IgnoreLinkStatus"
 #define INACTIVE               "Inactive"
 #define INCLUDED               "Included"
 #define IGNOREDIALTONE         "IgnoreDialTone"
 #define IGNORELINKSTATUS       "IgnoreLinkStatus"
 #define INACTIVE               "Inactive"
 #define INCLUDED               "Included"
+#define        INFO                    "Info"
 #define INFORM                 "INFORM"
 #define INTERFACE              "Interface"
 #define INTERFACENAME          "InterfaceName"
 #define INFORM                 "INFORM"
 #define INTERFACE              "Interface"
 #define INTERFACENAME          "InterfaceName"
@@ -272,8 +301,10 @@ typedef enum {
 #define KEYID                  "KeyID"
 #define L2TP                   "L2TP"
 #define LAST                   "Last"
 #define KEYID                  "KeyID"
 #define L2TP                   "L2TP"
 #define LAST                   "Last"
+#define LAYER                  "Layer"
 #define LCP                    "LCP"
 #define LINK                   "Link"
 #define LCP                    "LCP"
 #define LINK                   "Link"
+#define LINKISSUES             "LinkIssues"
 #define LINKLOCAL              "LinkLocal"
 #define LINKQUALITY            "LinkQuality"
 #define LOCALCERTIFICATE       "LocalCertificate"
 #define LINKLOCAL              "LinkLocal"
 #define LINKQUALITY            "LinkQuality"
 #define LOCALCERTIFICATE       "LocalCertificate"
@@ -291,6 +322,7 @@ typedef enum {
 #define MODEL                  "Model"
 #define MODE                   "Mode"
 #define MODEM                  "Modem"
 #define MODEL                  "Model"
 #define MODE                   "Mode"
 #define MODEM                  "Modem"
+#define MODULEID               "ModuleID"
 #define MPPE40                 "MPPE40"
 #define MPPE128                        "MPPE128"
 #define MRU                    "MRU"
 #define MPPE40                 "MPPE40"
 #define MPPE128                        "MPPE128"
 #define MRU                    "MRU"
@@ -305,6 +337,7 @@ typedef enum {
 #define NETWORKRANGE           "NetworkRange"
 #define NETWORKSERVICES                "NetworkServices"
 #define NEVER                  "Never"
 #define NETWORKRANGE           "NetworkRange"
 #define NETWORKSERVICES                "NetworkServices"
 #define NEVER                  "Never"
+#define NO                     "No"
 #define NODE                   "Node"
 #define NODEID                 "NodeID"
 #define NOTE                   "Note"
 #define NODE                   "Node"
 #define NODEID                 "NodeID"
 #define NOTE                   "Note"
@@ -315,6 +348,7 @@ typedef enum {
 #define ORDERS                 "Orders"
 #define OVERRIDEPRIMARY                "OverridePrimary"
 #define PAP                    "PAP"
 #define ORDERS                 "Orders"
 #define OVERRIDEPRIMARY                "OverridePrimary"
 #define PAP                    "PAP"
+#define PARAMETERS             "Parameters"
 #define PASSIVE                        "Passive"
 #define PASSWORD               "Password"
 #define PEER                   "Peer"
 #define PASSIVE                        "Passive"
 #define PASSWORD               "Password"
 #define PEER                   "Peer"
@@ -334,6 +368,7 @@ typedef enum {
 #define PRIMARYRANK            "PrimaryRank"
 #define PRIMARYSERVICE         "PrimaryService"
 #define PRIORITY               "Priority"
 #define PRIMARYRANK            "PrimaryRank"
 #define PRIMARYSERVICE         "PrimaryService"
 #define PRIORITY               "Priority"
+#define PROBE                  "Probe"
 #define PROMPT                 "Prompt"
 #define PROTOCOL               "Protocol"
 #define PROXIES                        "Proxies"
 #define PROMPT                 "Prompt"
 #define PROTOCOL               "Protocol"
 #define PROXIES                        "Proxies"
@@ -350,6 +385,8 @@ typedef enum {
 #define REMINDER               "Reminder"
 #define REMINDERTIME           "ReminderTime"
 #define REMOTEADDRESS          "RemoteAddress"
 #define REMINDER               "Reminder"
 #define REMINDERTIME           "ReminderTime"
 #define REMOTEADDRESS          "RemoteAddress"
+#define REQUIRED               "Required"
+#define REQUIREMENT            "Requirement"
 #define RESOLVED               "Resolved"
 #define RETRYCONNECTTIME       "RetryConnectTime"
 #define ROOTSEPARATOR          "RootSeparator"
 #define RESOLVED               "Resolved"
 #define RETRYCONNECTTIME       "RetryConnectTime"
 #define ROOTSEPARATOR          "RootSeparator"
@@ -358,6 +395,8 @@ typedef enum {
 #define ROUTES                 "Routes"
 #define ROUTERADVERTISEMENT    "RouterAdvertisement"
 #define RTSP                   "RTSP"
 #define ROUTES                 "Routes"
 #define ROUTERADVERTISEMENT    "RouterAdvertisement"
 #define RTSP                   "RTSP"
+#define RULE                   "Rule"
+#define RULES                  "Rules"
 #define RXCSUM                 "RXCSUM"
 #define SAVEPASSWORDS          "SavePasswords"
 #define SCOPE                  "Scope"
 #define RXCSUM                 "RXCSUM"
 #define SAVEPASSWORDS          "SavePasswords"
 #define SCOPE                  "Scope"
@@ -368,17 +407,21 @@ typedef enum {
 #define SEEDROUTER             "SeedRouter"
 #define SEEDZONES              "SeedZones"
 #define SERVER                 "Server"
 #define SEEDROUTER             "SeedRouter"
 #define SEEDZONES              "SeedZones"
 #define SERVER                 "Server"
+#define SERVERS                        "Servers"
 #define SERVICE                        "Service"
 #define SERVICE                        "Service"
+#define SERVICES               "Services"
 #define SERVICEIDS             "ServiceIDs"
 #define SESSIONTIMER           "SessionTimer"
 #define SETS                   "Sets"
 #define SETUP                  "Setup"
 #define        SHAREDSECRET            "SharedSecret"
 #define SERVICEIDS             "ServiceIDs"
 #define SESSIONTIMER           "SessionTimer"
 #define SETS                   "Sets"
 #define SETUP                  "Setup"
 #define        SHAREDSECRET            "SharedSecret"
+#define SIGNING                        "Signing"
 #define SMB                    "SMB"
 #define SOCKS                  "SOCKS"
 #define SORTLIST               "SortList"
 #define SPEAKER                        "Speaker"
 #define SPEED                  "Speed"
 #define SMB                    "SMB"
 #define SOCKS                  "SOCKS"
 #define SORTLIST               "SortList"
 #define SPEAKER                        "Speaker"
 #define SPEED                  "Speed"
+#define SSID                   "SSID"
 #define STATE                  "State"
 #define STATUS                 "Status"
 #define STF                    "6to4"
 #define STATE                  "State"
 #define STATUS                 "Status"
 #define STF                    "6to4"
@@ -388,11 +431,13 @@ typedef enum {
 #define SUBTYPE                        "SubType"
 #define SUPPLEMENTAL           "Supplemental"
 #define SUPPORTSMODEMONHOLD    "SupportsModemOnHold"
 #define SUBTYPE                        "SubType"
 #define SUPPLEMENTAL           "Supplemental"
 #define SUPPORTSMODEMONHOLD    "SupportsModemOnHold"
+#define SUSPENDED              "Suspended"
 #define SYSTEM                 "System"
 #define TAG                    "Tag"
 #define TAGS                   "Tags"
 #define TERMINALSCRIPT         "TerminalScript"
 #define TIMEOUT                        "Timeout"
 #define SYSTEM                 "System"
 #define TAG                    "Tag"
 #define TAGS                   "Tags"
 #define TERMINALSCRIPT         "TerminalScript"
 #define TIMEOUT                        "Timeout"
+#define TIMESTAMP              "TimeStamp"
 #define TOKEN                  "Token"
 #define TRANSMITACCM           "TransmitACCM"
 #define TRANSPORT              "Transport"
 #define TOKEN                  "Token"
 #define TRANSMITACCM           "TransmitACCM"
 #define TRANSPORT              "Transport"
@@ -415,6 +460,7 @@ typedef enum {
 #define VLAN_MTU               "VLAN_MTU"
 #define        VPN                     "VPN"
 #define WAITFORDIALTONE                "WaitForDialTone"
 #define VLAN_MTU               "VLAN_MTU"
 #define        VPN                     "VPN"
 #define WAITFORDIALTONE                "WaitForDialTone"
+#define WIFI                   "WiFi"
 #define WINS                   "WINS"
 #define WORKGROUP              "Workgroup"
 #define XAUTH                  "XAuth"
 #define WINS                   "WINS"
 #define WORKGROUP              "Workgroup"
 #define XAUTH                  "XAuth"
@@ -505,7 +551,9 @@ static schemaDefinition names[] = {
 
   { GROUP_PRIVATE, NETENT, "Network Entity Keys", NULL, NULL },
 
 
   { GROUP_PRIVATE, NETENT, "Network Entity Keys", NULL, NULL },
 
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETENT, APP LAYER, NULL, CFDICTIONARY},
     { SC_10_5_PRIVATE, NETENT, EAPOL, NULL, CFDICTIONARY },
     { SC_10_5_PRIVATE, NETENT, EAPOL, NULL, CFDICTIONARY },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETENT, LINKISSUES, NULL, CFDICTIONARY},
     { 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_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 },
@@ -525,36 +573,36 @@ static schemaDefinition names[] = {
     { SC_10_5_PRIVATE, NETPROP, IGNORELINKSTATUS, NULL, CFBOOLEAN },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL }, 
        
     { SC_10_5_PRIVATE, NETPROP, IGNORELINKSTATUS, NULL, CFBOOLEAN },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL }, 
        
-  { GROUP, NETPROP AIRPORT, KEY_PREFIX COMP NETWORK INTERFACE " Properties", NULL, NULL },
+  { GROUP, NETPROP INTERFACES, KEY_PREFIX COMP NETWORK INTERFACE " Properties", NULL, NULL },
 
     { SC_10_2, NETPROP, INTERFACES, NULL, CFARRAY_CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
 
     { SC_10_2, NETPROP, INTERFACES, NULL, CFARRAY_CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-  { GROUP, NETPROP AIRPORT, KEY_PREFIX COMP NETWORK HOSTNAMES " Properties", NULL, NULL },
+  { GROUP, NETPROP LOCALHOSTNAME, KEY_PREFIX COMP NETWORK HOSTNAMES " Properties", NULL, NULL },
 
     { SC_10_2, NETPROP, LOCALHOSTNAME, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
 
     { SC_10_2, NETPROP, LOCALHOSTNAME, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-  { GROUP, NETPROP AIRPORT, KEY_PREFIX NETENT AIRPORT " (Hardware) Entity Keys", NULL, NULL },
+  { GROUP_DEPRECATED, NETPROP AIRPORT, KEY_PREFIX NETENT AIRPORT " (Hardware) Entity Keys", NULL, NULL },
 
 
-    { SC_10_2, NETPROP AIRPORT, ALLOWNETCREATION, NULL, CFNUMBER_BOOL },
-    { SC_10_1, NETPROP AIRPORT, AUTH PASSWORD, NULL, CFDATA },
-    { SC_10_1, NETPROP AIRPORT, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
-    { SC_10_2, NETPROP AIRPORT, JOIN MODE, NULL, CFSTRING },
-    { SC_10_1, NETPROP AIRPORT, POWER ENABLED, NULL, CFNUMBER_BOOL },
-    { SC_10_1, NETPROP AIRPORT, PREFERRED NETWORK, NULL, CFSTRING },
-    { SC_10_2, NETPROP AIRPORT, SAVEPASSWORDS, NULL, CFNUMBER_BOOL },
-    { COMMENT, "", NULL, NULL, NULL },
-    { COMMENT, "--- " KEY_PREFIX NETPROP AIRPORT JOIN MODE " values ---", NULL, NULL, NULL },
-    { SC_10_3, NETVAL AIRPORT JOIN MODE, AUTOMATIC, NULL, NULL },
-    { SC_10_2, NETVAL AIRPORT JOIN MODE, PREFERRED, NULL, NULL },
-    { SC_10_4, NETVAL AIRPORT JOIN MODE, RANKED, NULL, NULL },
-    { SC_10_2, NETVAL AIRPORT JOIN MODE, RECENT, NULL, NULL },
-    { SC_10_2, NETVAL AIRPORT JOIN MODE, STRONGEST, NULL, NULL },
-    { COMMENT, "", NULL, NULL, NULL },
-    { COMMENT, "--- " KEY_PREFIX NETPROP AIRPORT PASSWORD ENCRYPTION " values ---", NULL, NULL, NULL },
-    { SC_10_3, NETVAL AIRPORT AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
-    { COMMENT, "", NULL, NULL, NULL },
+    { SC_10_2_10_9, NETPROP AIRPORT, ALLOWNETCREATION, NULL, CFNUMBER_BOOL },
+    { SC_10_1_10_9, NETPROP AIRPORT, AUTH PASSWORD, NULL, CFDATA },
+    { SC_10_1_10_9, NETPROP AIRPORT, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
+    { SC_10_2_10_9, NETPROP AIRPORT, JOIN MODE, NULL, CFSTRING },
+    { SC_10_1_10_9, NETPROP AIRPORT, POWER ENABLED, NULL, CFNUMBER_BOOL },
+    { SC_10_1_10_9, NETPROP AIRPORT, PREFERRED NETWORK, NULL, CFSTRING },
+    { SC_10_2_10_9, NETPROP AIRPORT, SAVEPASSWORDS, NULL, CFNUMBER_BOOL },
+    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
+    { COMMENT_DEPRECATED, "--- " KEY_PREFIX NETPROP AIRPORT JOIN MODE " values ---", NULL, NULL, NULL },
+    { SC_10_3_10_9, NETVAL AIRPORT JOIN MODE, AUTOMATIC, NULL, NULL },
+    { SC_10_2_10_9, NETVAL AIRPORT JOIN MODE, PREFERRED, NULL, NULL },
+    { SC_10_4_10_9, NETVAL AIRPORT JOIN MODE, RANKED, NULL, NULL },
+    { SC_10_2_10_9, NETVAL AIRPORT JOIN MODE, RECENT, NULL, NULL },
+    { SC_10_2_10_9, NETVAL AIRPORT JOIN MODE, STRONGEST, NULL, NULL },
+    { COMMENT_DEPRECATED, "", NULL, NULL, NULL },
+    { COMMENT_DEPRECATED, "--- " KEY_PREFIX NETPROP AIRPORT PASSWORD ENCRYPTION " values ---", NULL, NULL, NULL },
+    { 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, NETPROP APPLETALK, KEY_PREFIX NETENT APPLETALK " Entity Keys", NULL, NULL },
 
@@ -591,6 +639,12 @@ static schemaDefinition names[] = {
     { SC_10_4, NETPROP DNS, SUPPLEMENTAL MATCH ORDERS, NULL, CFARRAY_CFNUMBER},
     { COMMENT, "", NULL, NULL, NULL },
 
     { SC_10_4, NETPROP DNS, SUPPLEMENTAL MATCH ORDERS, NULL, CFARRAY_CFNUMBER},
     { COMMENT, "", NULL, NULL, NULL },
 
+  { GROUP_PRIVATE, NETPROP DNS, KEY_PREFIX NETENT DNS " Entity Keys", NULL, NULL },
+
+       { 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 },
 
     { SC_10_2, NETPROP ETHERNET, MEDIA SUBTYPE, NULL, CFSTRING },
   { GROUP, NETPROP ETHERNET, KEY_PREFIX NETENT ETHERNET " (Hardware) Entity Keys", NULL, NULL },
 
     { SC_10_2, NETPROP ETHERNET, MEDIA SUBTYPE, NULL, CFSTRING },
@@ -661,6 +715,8 @@ static schemaDefinition names[] = {
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH NAME, NULL, CFSTRING },
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH PASSWORD, NULL, CFSTRING },
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH NAME, NULL, CFSTRING },
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH PASSWORD, NULL, CFSTRING },
     { SC_10_6_IPHONE_2_0, NETPROP IPSEC, XAUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP IPSEC, DISCONNECTONWAKE, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP IPSEC, DISCONNECTONWAKETIMER, NULL, CFNUMBER },
     { COMMENT, "", NULL, NULL, NULL },
     { COMMENT, "--- " KEY_PREFIX NETPROP IPSEC AUTHENTICATIONMETHOD " values ---", NULL, NULL, NULL },
     { SC_10_5, NETVAL IPSEC AUTHENTICATIONMETHOD, SHAREDSECRET, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
     { COMMENT, "--- " KEY_PREFIX NETPROP IPSEC AUTHENTICATIONMETHOD " values ---", NULL, NULL, NULL },
     { SC_10_5, NETVAL IPSEC AUTHENTICATIONMETHOD, SHAREDSECRET, NULL, NULL },
@@ -765,6 +821,13 @@ static schemaDefinition names[] = {
     { SC_10_2, NETPROP LINK, DETACHING, NULL, CFBOOLEAN },
     { COMMENT, "", NULL, NULL, NULL },
 
     { SC_10_2, NETPROP LINK, DETACHING, NULL, CFBOOLEAN },
     { COMMENT, "", NULL, NULL, NULL },
 
+  { GROUP_PRIVATE, NETPROP LINK, KEY_PREFIX NETENT LINKISSUES " Entity Keys", NULL, NULL },
+
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP LINKISSUES, MODULEID, NULL, CFDATA },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP LINKISSUES, INFO, NULL, CFDATA },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP LINKISSUES, TIMESTAMP, NULL, CFDATE },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+
   { GROUP_PRIVATE, NETPROP LINK, KEY_PREFIX NETENT LINKQUALITY " Entity Keys", NULL, NULL },
 
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP, LINKQUALITY, NULL, CFNUMBER},
   { GROUP_PRIVATE, NETPROP LINK, KEY_PREFIX NETENT LINKQUALITY " Entity Keys", NULL, NULL },
 
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP, LINKQUALITY, NULL, CFNUMBER},
@@ -827,6 +890,8 @@ static schemaDefinition names[] = {
     { SC_10_1, NETPROP PPP, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
     { SC_10_2, NETPROP PPP, DISCONNECTONSLEEP, NULL, CFNUMBER_BOOL },
     { SC_10_1, NETPROP PPP, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
     { SC_10_2, NETPROP PPP, DISCONNECTONSLEEP, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP PPP, DISCONNECTONWAKE, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP PPP, DISCONNECTONWAKETIMER, NULL, CFNUMBER },
     { SC_10_3, NETPROP PPP, DISCONNECTTIME, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, IDLEREMINDERTIMER, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, IDLEREMINDER, NULL, CFNUMBER_BOOL },
     { SC_10_3, NETPROP PPP, DISCONNECTTIME, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, IDLEREMINDERTIMER, NULL, CFNUMBER },
     { SC_10_1, NETPROP PPP, IDLEREMINDER, NULL, CFNUMBER_BOOL },
@@ -982,10 +1047,13 @@ static schemaDefinition names[] = {
 
   { GROUP_PRIVATE, NETPROP PROXIES, KEY_PREFIX NETENT PROXIES " Entity Keys", NULL, NULL },
 
 
   { GROUP_PRIVATE, NETPROP PROXIES, KEY_PREFIX NETENT PROXIES " Entity Keys", NULL, NULL },
 
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP PROXIES, BYPASS ALLOWED, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_6_0_PRIVATE, NETPROP PROXIES, FALLBACK ALLOWED, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAINS, NULL, CFARRAY_CFSTRING},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH ORDERS, NULL, CFARRAY_CFNUMBER},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SCOPED, "__SCOPED__", CFDICTIONARY},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAINS, NULL, CFARRAY_CFSTRING},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH ORDERS, NULL, CFARRAY_CFNUMBER},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SCOPED, "__SCOPED__", CFDICTIONARY},
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP PROXIES, SERVICES, "__SERVICES__", CFDICTIONARY},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL, "__SUPPLEMENTAL__", CFARRAY_CFDICTIONARY},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAIN, "__MATCH_DOMAIN__", CFSTRING},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL, "__SUPPLEMENTAL__", CFARRAY_CFDICTIONARY},
     { SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAIN, "__MATCH_DOMAIN__", CFSTRING},
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
@@ -1020,9 +1088,12 @@ static schemaDefinition names[] = {
 
   { GROUP_PRIVATE, NETPROP VPN, KEY_PREFIX NETENT VPN " Entity Keys", NULL, NULL },
 
 
   { GROUP_PRIVATE, NETPROP VPN, KEY_PREFIX NETENT VPN " Entity Keys", NULL, NULL },
 
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, APP RULES, NULL, CFARRAY_CFDICTIONARY },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, AUTH CREDENTIAL PASSWORD, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH NAME, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH PASSWORD, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH NAME, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH PASSWORD, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, AUTH PASSWORD PLUGIN TYPE, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTHENTICATIONMETHOD, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, CONNECTTIME, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONFASTUSERSWITCH, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, AUTHENTICATIONMETHOD, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, CONNECTTIME, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONFASTUSERSWITCH, NULL, CFNUMBER_BOOL },
@@ -1030,25 +1101,76 @@ static schemaDefinition names[] = {
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONSLEEP, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, DISCONNECTONSLEEP, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, DISCONNECTONWAKE, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, DISCONNECTONWAKETIMER, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, LOCALCERTIFICATE, NULL, CFDATA },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, LOGFILE, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, MTU, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND ENABLED, NULL, CFNUMBER_BOOL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, LOCALCERTIFICATE, NULL, CFDATA },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, LOGFILE, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, MTU, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND ENABLED, NULL, CFNUMBER_BOOL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH APP ENABLED, NULL, CFBOOLEAN },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS ALWAYS, NULL, CFARRAY_CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS ONRETRY, NULL, CFARRAY_CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS NEVER, NULL, CFARRAY_CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS ALWAYS, NULL, CFARRAY_CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS ONRETRY, NULL, CFARRAY_CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, ONDEMAND MATCH DOMAINS NEVER, NULL, CFARRAY_CFSTRING },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETPROP VPN, ONDEMAND RULES, NULL, CFARRAY_CFDICTIONARY },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, ONDEMAND SUSPENDED, NULL, CFNUMBER },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN, PLUGIN CAPABILITY, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, REMOTEADDRESS, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, STATUS, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, VERBOSELOGGING, NULL, CFNUMBER_BOOL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, REMOTEADDRESS, NULL, CFSTRING },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, STATUS, NULL, CFNUMBER },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETPROP VPN, VERBOSELOGGING, NULL, CFNUMBER_BOOL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN APP RULES  " [CFDictionary] keys ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE, ACCOUNT IDENTIFIER MATCH, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE, DNS DOMAIN MATCH, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE, EXECUTABLE MATCH, NULL, CFARRAY_CFDICTIONARY },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE, IDENTIFIER, NULL, CFSTRING },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETVAL VPN APP RULE EXECUTABLE MATCH " [CFDictionary] keys ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE EXECUTABLE, DESIGNATED REQUIREMENT, NULL, CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN APP RULE EXECUTABLE, SIGNING IDENTIFIER, NULL, CFSTRING },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN AUTHENTICATIONMETHOD " values ---", NULL, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTHENTICATIONMETHOD, PASSWORD, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTHENTICATIONMETHOD, CERTIFICATE, NULL, NULL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN AUTH PASSWORD ENCRYPTION " values ---", NULL, NULL, NULL },
     { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN AUTHENTICATIONMETHOD " values ---", NULL, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTHENTICATIONMETHOD, PASSWORD, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTHENTICATIONMETHOD, CERTIFICATE, NULL, NULL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN AUTH PASSWORD ENCRYPTION " values ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN AUTH PASSWORD ENCRYPTION, EXTERNAL, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTH PASSWORD ENCRYPTION, PROMPT, NULL, NULL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
     { SC_10_7_IPHONE_4_0_PRIVATE, NETVAL VPN AUTH PASSWORD ENCRYPTION, PROMPT, NULL, NULL },
     { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN ONDEMAND RULES " [CFDictionary] keys ---", NULL, NULL, NULL },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETPROP VPN ONDEMAND RULE, ACTION, NULL, CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE, ACTION PARAMETERS, NULL, CFARRAY_CFDICTIONARY },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETPROP VPN ONDEMAND RULE, DNS DOMAIN MATCH, NULL, CFARRAY_CFSTRING },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETPROP VPN ONDEMAND RULE, DNS SERVER ADDRESS MATCH, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE, SSID MATCH, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE, INTERFACE TYPE MATCH, NULL, CFSTRING },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETPROP VPN ONDEMAND RULE, URLSTRING PROBE, NULL, CFSTRING },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN ONDEMAND RULE ACTION " values ---", NULL, NULL, NULL },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION, ALLOW, NULL, NULL },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION, IGNORE, NULL, NULL },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION, CONNECT, NULL, NULL },
+    { SC_10_8_IPHONE_6_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION, DISCONNECT, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION, EVALUATE CONNECTION, NULL, NULL },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN ONDEMAND RULE ACTION PARAMETERS " [CFDictionary] keys ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE ACTION PARAMETERS, DOMAIN ACTION, NULL, CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE ACTION PARAMETERS, DOMAINS, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE ACTION PARAMETERS, REQUIRED DNS SERVERS, NULL, CFARRAY_CFSTRING },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETPROP VPN ONDEMAND RULE ACTION PARAMETERS, REQUIRED URLSTRING PROBE, NULL, CFSTRING },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN ONDEMAND RULE ACTION PARAMETERS DOMAIN ACTION " values ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION PARAMETERS DOMAIN ACTION, CONNECT IFNEEDED, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN ONDEMAND RULE ACTION PARAMETERS DOMAIN ACTION, NEVER CONNECT, NULL, NULL },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN ONDEMAND RULE INTERFACE TYPE MATCH " values ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN ONDEMAND RULE INTERFACE TYPE MATCH, ETHERNET, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN ONDEMAND RULE INTERFACE TYPE MATCH, WIFI, NULL, NULL },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
+    { COMMENT_PRIVATE, "--- " KEY_PREFIX NETPROP VPN PLUGIN CAPABILITY " values ---", NULL, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN PLUGIN CAPABILITY, AUTH, NULL, NULL },
+    { SC_10_9_IPHONE_7_0_PRIVATE, NETVAL VPN PLUGIN CAPABILITY, CONNECT, NULL, NULL },
+    { COMMENT_PRIVATE, "", NULL, NULL, NULL },
 
   { GROUP, USERSENT CONSOLEUSER, KEY_PREFIX COMP USERS " Entity Keys", NULL, NULL },
 
 
   { GROUP, USERSENT CONSOLEUSER, KEY_PREFIX COMP USERS " Entity Keys", NULL, NULL },
 
@@ -1228,6 +1350,18 @@ print_headerdoc(schemaDefinition *def)
            case SC_10_2_10_6:
                printf("  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.6.\n");
                break;
            case SC_10_2_10_6:
                printf("  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.6.\n");
                break;
+           case SC_10_1_10_9:
+               printf("  @availability Introduced in Mac OS X 10.1, but later deprecated in Mac OS X 10.9.\n");
+               break;
+           case SC_10_2_10_9:
+               printf("  @availability Introduced in Mac OS X 10.2, but later deprecated in Mac OS X 10.9.\n");
+               break;
+           case SC_10_3_10_9:
+               printf("  @availability Introduced in Mac OS X 10.3, but later deprecated in Mac OS X 10.9.\n");
+               break;
+           case SC_10_4_10_9:
+               printf("  @availability Introduced in Mac OS X 10.4, but later deprecated in Mac OS X 10.9.\n");
+               break;
            case SC_10_6_IPHONE_2_0:
            case SC_10_6_IPHONE_2_0_PRIVATE:
                printf("  @availability Introduced in Mac OS X 10.6.\n");
            case SC_10_6_IPHONE_2_0:
            case SC_10_6_IPHONE_2_0_PRIVATE:
                printf("  @availability Introduced in Mac OS X 10.6.\n");
@@ -1241,6 +1375,13 @@ print_headerdoc(schemaDefinition *def)
            case SC_10_7_IPHONE_5_0_PRIVATE:
                printf("  @availability Introduced in Mac OS X 10.7.\n");
                break;
            case SC_10_7_IPHONE_5_0_PRIVATE:
                printf("  @availability Introduced in Mac OS X 10.7.\n");
                break;
+           case SC_10_8_IPHONE_6_0_PRIVATE:
+               printf("  @availability Introduced in Mac OS X 10.8.\n");
+               break;
+           case SC_10_9_IPHONE_6_0_PRIVATE:
+           case SC_10_9_IPHONE_7_0_PRIVATE:
+               printf("  @availability Introduced in Mac OS X 10.9.\n");
+               break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  @availability Introduced in iPhone OS 2.0.\n");
                break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  @availability Introduced in iPhone OS 2.0.\n");
                break;
@@ -1301,6 +1442,18 @@ print_hfile(schemaDefinition *def)
            case SC_10_2_10_6:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_6,__IPHONE_NA,__IPHONE_NA))\n", kbuf);
                break;
            case SC_10_2_10_6:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_6,__IPHONE_NA,__IPHONE_NA))\n", kbuf);
                break;
+           case SC_10_1_10_9:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))\n", kbuf);
+               break;
+           case SC_10_2_10_9:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))\n", kbuf);
+               break;
+           case SC_10_3_10_9:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))\n", kbuf);
+               break;
+           case SC_10_4_10_9:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_9,__IPHONE_2_0/*SPI*/,__IPHONE_FUTURE/*SPI*/))\n", kbuf);
+               break;
            case SC_10_6_IPHONE_2_0:
            case SC_10_6_IPHONE_2_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0/*SPI*/))\n", kbuf);
            case SC_10_6_IPHONE_2_0:
            case SC_10_6_IPHONE_2_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_2_0/*SPI*/))\n", kbuf);
@@ -1316,6 +1469,15 @@ print_hfile(schemaDefinition *def)
            case SC_10_7_IPHONE_5_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))\n", kbuf);
                break;
            case SC_10_7_IPHONE_5_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0/*SPI*/))\n", kbuf);
                break;
+           case SC_10_8_IPHONE_6_0_PRIVATE:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_6_0/*SPI*/))\n", kbuf);
+               break;
+           case SC_10_9_IPHONE_6_0_PRIVATE:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0/*SPI*/))\n", kbuf);
+               break;
+           case SC_10_9_IPHONE_7_0_PRIVATE:
+               printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0/*SPI*/))\n", kbuf);
+               break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_2_0/*SPI*/))\n", kbuf);
                break;
            case SC_IPHONE_2_0_PRIVATE:
                printf("  " SC_SCHEMA_DECLARATION "(%s, __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_2_0/*SPI*/))\n", kbuf);
                break;
@@ -1350,11 +1512,12 @@ dump_names(int type)
            case COMMENT: {
                switch (type) {
                    case gen_comments_e:
            case COMMENT: {
                switch (type) {
                    case gen_comments_e:
-                       if (names[i].prefix)
+                       if (names[i].prefix) {
                            if (strlen(names[i].prefix) > 0)
                                printf(" *   %s\n", names[i].prefix);
                            else
                                printf(" *\n");
                            if (strlen(names[i].prefix) > 0)
                                printf(" *   %s\n", names[i].prefix);
                            else
                                printf(" *\n");
+                       }
                        break;
                    default:
                        break;
                        break;
                    default:
                        break;
@@ -1365,11 +1528,12 @@ dump_names(int type)
            case COMMENT_PRIVATE: {
                switch (type) {
                    case gen_comments_private_e:
            case COMMENT_PRIVATE: {
                switch (type) {
                    case gen_comments_private_e:
-                       if (names[i].prefix)
+                       if (names[i].prefix) {
                            if (strlen(names[i].prefix) > 0)
                                printf(" *   %s\n", names[i].prefix);
                            else
                                printf(" *\n");
                            if (strlen(names[i].prefix) > 0)
                                printf(" *   %s\n", names[i].prefix);
                            else
                                printf(" *\n");
+                       }
                        break;
                    default:
                        break;
                        break;
                    default:
                        break;
@@ -1484,6 +1648,10 @@ dump_names(int type)
                            case SC_10_1_10_5:
                            case SC_10_1_10_6:
                            case SC_10_2_10_6:
                            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:
+                           case SC_10_4_10_9:
                                // don't report deprecated keys
                                break;
                            case SC_10_5_PRIVATE:
                                // don't report deprecated keys
                                break;
                            case SC_10_5_PRIVATE:
@@ -1491,6 +1659,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                // don't report private definitions
                                break;
                            case SC_IPHONE_2_0_PRIVATE:
                                // don't report private definitions
                                break;
@@ -1505,6 +1676,10 @@ dump_names(int type)
                            case SC_10_1_10_5:
                            case SC_10_1_10_6:
                            case SC_10_2_10_6:
                            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:
+                           case SC_10_4_10_9:
                                // don't report deprecated keys
                                break;
                            case SC_10_5_PRIVATE:
                                // don't report deprecated keys
                                break;
                            case SC_10_5_PRIVATE:
@@ -1512,6 +1687,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                print_comment(&names[i]);
                                break;
                            case SC_IPHONE_2_0_PRIVATE:
                                print_comment(&names[i]);
                                break;
@@ -1528,6 +1706,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                // don't report private definitions
                                break;
                            case SC_IPHONE_2_0_PRIVATE:
                                // don't report private definitions
                                break;
@@ -1543,6 +1724,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                print_headerdoc(&names[i]);
                                break;
                            case SC_IPHONE_2_0_PRIVATE:
                                print_headerdoc(&names[i]);
                                break;
@@ -1559,6 +1743,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                break;
                                // don't report private definitions
                            case SC_IPHONE_2_0_PRIVATE:
                                break;
                                // don't report private definitions
@@ -1574,6 +1761,9 @@ dump_names(int type)
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
                            case SC_10_6_IPHONE_3_0_PRIVATE:
                            case SC_10_7_IPHONE_4_0_PRIVATE:
                            case SC_10_7_IPHONE_5_0_PRIVATE:
+                           case SC_10_8_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_6_0_PRIVATE:
+                           case SC_10_9_IPHONE_7_0_PRIVATE:
                            case SC_IPHONE_2_0_PRIVATE:
                                print_hfile(&names[i]);
                                break;
                            case SC_IPHONE_2_0_PRIVATE:
                                print_hfile(&names[i]);
                                break;
@@ -1707,6 +1897,8 @@ main(int argc, char * argv[])
        printf("#endif\t/* 0 */\n\n\n");
 
        printf("/* -------------------- Schema declarations -------------------- */\n\n");
        printf("#endif\t/* 0 */\n\n\n");
 
        printf("/* -------------------- Schema declarations -------------------- */\n\n");
+
+       
        dump_names(gen_hfile_e);
        printf("\n");
 
        dump_names(gen_hfile_e);
        printf("\n");
 
index ad83e9cfdebd39691e4f8b3994d3221d65bbb743..01fd485249a2e014765357cef9094eae476c16c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2005-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -45,6 +45,8 @@
 #include "SCHelper_client.h"
 #include "helper_types.h"
 
 #include "SCHelper_client.h"
 #include "helper_types.h"
 
+#include <libproc_internal.h>
+
 
 #pragma mark -
 #pragma mark SCHelper session managment
 
 #pragma mark -
 #pragma mark SCHelper session managment
@@ -53,6 +55,7 @@
 //
 // entitlement used to control write access to a given "prefsID"
 //
 //
 // entitlement used to control write access to a given "prefsID"
 //
+#define        kSCReadEntitlementName          CFSTR("com.apple.SystemConfiguration.SCPreferences-read-access")
 #define        kSCWriteEntitlementName         CFSTR("com.apple.SystemConfiguration.SCPreferences-write-access")
 
 //
 #define        kSCWriteEntitlementName         CFSTR("com.apple.SystemConfiguration.SCPreferences-write-access")
 
 //
@@ -84,10 +87,13 @@ typedef struct {
        audit_token_t           auditToken;
 
        // write access entitlement associated with this session
        audit_token_t           auditToken;
 
        // write access entitlement associated with this session
+       lazyBoolean             callerReadAccess;
        lazyBoolean             callerWriteAccess;
 
        lazyBoolean             callerWriteAccess;
 
-       // VPN configuration filtering
-       CFArrayRef              vpnFilter;
+       // configuration filtering
+       lazyBoolean             isSetChange;    // only network "set" changes
+       lazyBoolean             isVPNChange;    // only VPN configuration changes
+       CFArrayRef              vpnTypes;
 
        // preferences
        SCPreferencesRef        prefs;
 
        // preferences
        SCPreferencesRef        prefs;
@@ -119,7 +125,7 @@ static pthread_mutex_t      sessions_lock                   = PTHREAD_MUTEX_INITIALIZER;
 #pragma mark Helper session management
 
 
 #pragma mark Helper session management
 
 
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
 static Boolean
  __SCHelperSessionUseEntitlement(SCHelperSessionRef session)
 {
 static Boolean
  __SCHelperSessionUseEntitlement(SCHelperSessionRef session)
 {
@@ -127,7 +133,7 @@ static Boolean
 
        return sessionPrivate->use_entitlement;
 }
 
        return sessionPrivate->use_entitlement;
 }
-#endif //!TARGET_OS_IPHONE
+#endif //!TARGET_OS_IPHONE
 
 
 static AuthorizationRef
 
 
 static AuthorizationRef
@@ -145,25 +151,31 @@ __SCHelperSessionSetAuthorization(SCHelperSessionRef session, CFTypeRef authoriz
        Boolean                         ok              = TRUE;
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
        Boolean                         ok              = TRUE;
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
+       /*
+        * On OSX, the authorizationData can either be a CFData-wrapped/externalized
+        * "authorization" or a CFString indicating that we should check entitlements.
+        *
+        * On iOS, the authorizationData is a CFString indicating that we should
+        * check entitlements.
+        */
        pthread_mutex_lock(&sessionPrivate->lock);
 
        if (sessionPrivate->authorization != NULL) {
        pthread_mutex_lock(&sessionPrivate->lock);
 
        if (sessionPrivate->authorization != NULL) {
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
                if (!__SCHelperSessionUseEntitlement(session)) {
                        AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDefaults);
 //                     AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDestroyRights);
                if (!__SCHelperSessionUseEntitlement(session)) {
                        AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDefaults);
 //                     AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDestroyRights);
-                       sessionPrivate->authorization = NULL;
                } else {
                } else {
-#endif //!TARGET_OS_IPHONE
                        CFRelease(sessionPrivate->authorization);
                        CFRelease(sessionPrivate->authorization);
-                       sessionPrivate->authorization = NULL;
-#if !TARGET_OS_IPHONE
                }
                }
-#endif //!TARGET_OS_IPHONE
+#else  //!TARGET_OS_IPHONE
+               CFRelease(sessionPrivate->authorization);
+#endif //!TARGET_OS_IPHONE
+               sessionPrivate->authorization = NULL;
                sessionPrivate->use_entitlement = FALSE;
        }
 
                sessionPrivate->use_entitlement = FALSE;
        }
 
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
        if (isA_CFData(authorizationData)) {
                AuthorizationExternalForm       extForm;
 
        if (isA_CFData(authorizationData)) {
                AuthorizationExternalForm       extForm;
 
@@ -181,13 +193,16 @@ __SCHelperSessionSetAuthorization(SCHelperSessionRef session, CFTypeRef authoriz
                                ok = FALSE;
                        }
                }
                                ok = FALSE;
                        }
                }
-       } else
-#endif //!TARGET_OS_IPHONE
-
+       } else if (isA_CFString(authorizationData)) {
+               sessionPrivate->authorization = (void *)CFRetain(authorizationData);
+               sessionPrivate->use_entitlement = TRUE;
+       }
+#else  //!TARGET_OS_IPHONE
        if (isA_CFString(authorizationData)) {
                sessionPrivate->authorization = (void *)CFRetain(authorizationData);
                sessionPrivate->use_entitlement = TRUE;
        }
        if (isA_CFString(authorizationData)) {
                sessionPrivate->authorization = (void *)CFRetain(authorizationData);
                sessionPrivate->use_entitlement = TRUE;
        }
+#endif //!TARGET_OS_IPHONE
 
        pthread_mutex_unlock(&sessionPrivate->lock);
 
 
        pthread_mutex_unlock(&sessionPrivate->lock);
 
@@ -287,29 +302,46 @@ __SCHelperSessionSetPreferences(SCHelperSessionRef session, SCPreferencesRef pre
 }
 
 
 }
 
 
-static CFArrayRef
-__SCHelperSessionGetVPNFilter(SCHelperSessionRef session)
+static void
+__SCHelperSessionSetNetworkSetFilter(SCHelperSessionRef session, Boolean setChange)
 {
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
 {
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
-       return sessionPrivate->vpnFilter;
+       pthread_mutex_lock(&sessionPrivate->lock);
+
+       sessionPrivate->isSetChange = setChange ? YES : NO;
+
+       pthread_mutex_unlock(&sessionPrivate->lock);
+
+       return;
 }
 
 
 static Boolean
 }
 
 
 static Boolean
-__SCHelperSessionSetVPNFilter(SCHelperSessionRef session, CFArrayRef vpnFilter)
+__SCHelperSessionUseNetworkSetFilter(SCHelperSessionRef session)
+{
+       SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
+
+       return (sessionPrivate->isSetChange == YES) ? TRUE : FALSE;
+}
+
+
+static Boolean
+__SCHelperSessionSetVPNFilter(SCHelperSessionRef session, Boolean vpnChange, CFArrayRef vpnTypes)
 {
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
        pthread_mutex_lock(&sessionPrivate->lock);
 
 {
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
        pthread_mutex_lock(&sessionPrivate->lock);
 
-       if (vpnFilter != NULL) {
-               CFRetain(vpnFilter);
+       sessionPrivate->isVPNChange = vpnChange ? YES : NO;
+
+       if (vpnTypes != NULL) {
+               CFRetain(vpnTypes);
        }
        }
-       if (sessionPrivate->vpnFilter != NULL) {
-               CFRelease(sessionPrivate->vpnFilter);
+       if (sessionPrivate->vpnTypes != NULL) {
+               CFRelease(sessionPrivate->vpnTypes);
        }
        }
-       sessionPrivate->vpnFilter = vpnFilter;
+       sessionPrivate->vpnTypes = vpnTypes;
 
        pthread_mutex_unlock(&sessionPrivate->lock);
 
 
        pthread_mutex_unlock(&sessionPrivate->lock);
 
@@ -317,6 +349,16 @@ __SCHelperSessionSetVPNFilter(SCHelperSessionRef session, CFArrayRef vpnFilter)
 }
 
 
 }
 
 
+static CFArrayRef
+__SCHelperSessionUseVPNFilter(SCHelperSessionRef session, CFArrayRef *vpnTypes)
+{
+       SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
+
+       *vpnTypes = sessionPrivate->vpnTypes;
+       return (sessionPrivate->vpnTypes != NULL) ? TRUE : FALSE;
+}
+
+
 static void
 __SCHelperSessionLog(const void *value, void *context)
 {
 static void
 __SCHelperSessionLog(const void *value, void *context)
 {
@@ -387,7 +429,7 @@ __SCHelperSessionCopyDescription(CFTypeRef cf)
        CFStringAppendFormat(result, NULL, CFSTR("authorization = %p"), sessionPrivate->authorization);
        if (sessionPrivate->mp != NULL) {
                CFStringAppendFormat(result, NULL,
        CFStringAppendFormat(result, NULL, CFSTR("authorization = %p"), sessionPrivate->authorization);
        if (sessionPrivate->mp != NULL) {
                CFStringAppendFormat(result, NULL,
-                                    CFSTR(", mp = %p (port = %p)"),
+                                    CFSTR(", mp = %p (port = 0x%x)"),
                                     sessionPrivate->mp,
                                     CFMachPortGetPort(sessionPrivate->mp));
        }
                                     sessionPrivate->mp,
                                     CFMachPortGetPort(sessionPrivate->mp));
        }
@@ -413,8 +455,9 @@ __SCHelperSessionDeallocate(CFTypeRef cf)
 
        // release resources
        __SCHelperSessionSetAuthorization(session, NULL);
 
        // release resources
        __SCHelperSessionSetAuthorization(session, NULL);
-       __SCHelperSessionSetPreferences  (session, NULL);
-       __SCHelperSessionSetVPNFilter    (session, NULL);
+       __SCHelperSessionSetPreferences(session, NULL);
+       __SCHelperSessionSetNetworkSetFilter(session, FALSE);
+       __SCHelperSessionSetVPNFilter(session, FALSE, NULL);
        pthread_mutex_destroy(&sessionPrivate->lock);
        if (sessionPrivate->backtraces != NULL) {
                CFRelease(sessionPrivate->backtraces);
        pthread_mutex_destroy(&sessionPrivate->lock);
        if (sessionPrivate->backtraces != NULL) {
                CFRelease(sessionPrivate->backtraces);
@@ -469,8 +512,11 @@ __SCHelperSessionCreate(CFAllocatorRef allocator)
        sessionPrivate->use_entitlement         = FALSE;
        sessionPrivate->port                    = MACH_PORT_NULL;
        sessionPrivate->mp                      = NULL;
        sessionPrivate->use_entitlement         = FALSE;
        sessionPrivate->port                    = MACH_PORT_NULL;
        sessionPrivate->mp                      = NULL;
+       sessionPrivate->callerReadAccess        = UNKNOWN;
        sessionPrivate->callerWriteAccess       = UNKNOWN;
        sessionPrivate->callerWriteAccess       = UNKNOWN;
-       sessionPrivate->vpnFilter               = NULL;
+       sessionPrivate->isSetChange             = UNKNOWN;
+       sessionPrivate->isVPNChange             = UNKNOWN;
+       sessionPrivate->vpnTypes                = NULL;
        sessionPrivate->prefs                   = NULL;
        sessionPrivate->backtraces              = NULL;
 
        sessionPrivate->prefs                   = NULL;
        sessionPrivate->backtraces              = NULL;
 
@@ -635,7 +681,7 @@ static Boolean
 do_Auth(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t *status, CFDataRef *reply)
 {
        CFDictionaryRef authorizationDict;
 do_Auth(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t *status, CFDataRef *reply)
 {
        CFDictionaryRef authorizationDict;
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
        CFDataRef       authorizationData       = NULL;
 #endif
        Boolean         ok                      = FALSE;
        CFDataRef       authorizationData       = NULL;
 #endif
        Boolean         ok                      = FALSE;
@@ -644,19 +690,23 @@ do_Auth(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t *status
                return FALSE;
        }
 
                return FALSE;
        }
 
-       if (isA_CFDictionary(authorizationDict) == FALSE) {
+       if (authorizationDict == NULL) {
+               return FALSE;
+       }
+
+       if (!isA_CFDictionary(authorizationDict)) {
                CFRelease(authorizationDict);
                return FALSE;
        }
 
                CFRelease(authorizationDict);
                return FALSE;
        }
 
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
        authorizationData = CFDictionaryGetValue(authorizationDict, kSCHelperAuthAuthorization);
        if (authorizationData != NULL && isA_CFData(authorizationData)) {
                ok = __SCHelperSessionSetAuthorization(session, authorizationData);
        } else
 #endif
        {
        authorizationData = CFDictionaryGetValue(authorizationDict, kSCHelperAuthAuthorization);
        if (authorizationData != NULL && isA_CFData(authorizationData)) {
                ok = __SCHelperSessionSetAuthorization(session, authorizationData);
        } else
 #endif
        {
-               CFStringRef authorizationInfo;
+               CFStringRef     authorizationInfo;
 
                authorizationInfo = CFDictionaryGetValue(authorizationDict, kSCHelperAuthCallerInfo);
                if (authorizationInfo != NULL && isA_CFString(authorizationInfo)) {
 
                authorizationInfo = CFDictionaryGetValue(authorizationDict, kSCHelperAuthCallerInfo);
                if (authorizationInfo != NULL && isA_CFString(authorizationInfo)) {
@@ -1123,38 +1173,42 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t
        SCPreferencesRef        prefs           = __SCHelperSessionGetPreferences(session);
        CFPropertyListRef       prefsData       = NULL;
        SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
        SCPreferencesRef        prefs           = __SCHelperSessionGetPreferences(session);
        CFPropertyListRef       prefsData       = NULL;
        SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-       CFArrayRef              vpnFilter;
+       Boolean                 useSetFilter;
+       Boolean                 useVPNFilter;
+       CFArrayRef              vpnTypes        = NULL;
 
        if (prefs == NULL) {
                return FALSE;
        }
 
 
        if (prefs == NULL) {
                return FALSE;
        }
 
-       if (data != NULL) {
-               ok = _SCUnserialize(&prefsData, data, NULL, 0);
-               if (!ok) {
-                       return FALSE;
-               }
+       if (data == NULL) {
+               // if commit with no changes
+               goto commit;
+       }
 
 
-               if (!isA_CFDictionary(prefsData)) {
-                       *status = kSCStatusFailed;
-                       ok = FALSE;
-                       goto done;
-               }
+       ok = _SCUnserialize(&prefsData, data, NULL, 0);
+       if (!ok) {
+               return FALSE;
        }
 
        }
 
-       vpnFilter = __SCHelperSessionGetVPNFilter(session);
-       if (vpnFilter != NULL) {
+       if (!isA_CFDictionary(prefsData)) {
+               *status = kSCStatusFailed;
                ok = FALSE;
                ok = FALSE;
+               goto done;
+       }
 
 
-               if ((prefsPrivate->prefs != NULL) && (prefsData != NULL)) {
+       useSetFilter = __SCHelperSessionUseNetworkSetFilter(session);
+       useVPNFilter = __SCHelperSessionUseVPNFilter(session, &vpnTypes);
+       if (useSetFilter || useVPNFilter) {
+               ok = FALSE;
+
+               if (prefsPrivate->prefs != NULL) {
                        CFIndex                 c;
                        CFMutableDictionaryRef  prefsNew        = NULL;
                        CFMutableDictionaryRef  prefsOld        = NULL;
                        CFMutableDictionaryRef  prefsSave       = prefsPrivate->prefs;
                        CFIndex                 c;
                        CFMutableDictionaryRef  prefsNew        = NULL;
                        CFMutableDictionaryRef  prefsOld        = NULL;
                        CFMutableDictionaryRef  prefsSave       = prefsPrivate->prefs;
-                       CFRange                 range           = CFRangeMake(0, CFArrayGetCount(vpnFilter));
 
                        for (c = 0; c < 2; c++) {
 
                        for (c = 0; c < 2; c++) {
-                               CFArrayRef      services;
 
                                switch (c) {
                                        case 0 :
 
                                switch (c) {
                                        case 0 :
@@ -1165,41 +1219,49 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t
                                                break;
                                }
 
                                                break;
                                }
 
-                               // filter out VPN services of the specified type
-                               services = SCNetworkServiceCopyAll(prefs);
-                               if (services != NULL) {
-                                       CFIndex i;
-                                       CFIndex n       = CFArrayGetCount(services);
-
-                                       for (i = 0; i < n; i++) {
-                                               SCNetworkServiceRef     service;
-
-                                               service = CFArrayGetValueAtIndex(services, i);
-                                               if (_SCNetworkServiceIsVPN(service)) {
-                                                       SCNetworkInterfaceRef   child;
-                                                       CFStringRef             childType       = NULL;
-                                                       SCNetworkInterfaceRef   interface;
-                                                       CFStringRef             interfaceType;
-
-                                                       interface     = SCNetworkServiceGetInterface(service);
-                                                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
-                                                       child         = SCNetworkInterfaceGetInterface(interface);
-                                                       if (child != NULL) {
-                                                               childType = SCNetworkInterfaceGetInterfaceType(child);
-                                                       }
-                                                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN) &&
-                                                           (childType != NULL) &&
-                                                           CFArrayContainsValue(vpnFilter, range, childType)) {
-                                                               // filter out VPN service
-                                                               (void) SCNetworkServiceRemove(service);
-                                                       } else {
-                                                               // mark all other VPN services "enabled"
-                                                               (void) SCNetworkServiceSetEnabled(service, TRUE);
+                               if (useSetFilter) {
+                                       // filter out current network set selection
+                                       (void) SCPreferencesRemoveValue(prefs, kSCPrefCurrentSet);
+                               } else if (useVPNFilter) {
+                                       CFRange         range           = CFRangeMake(0, CFArrayGetCount(vpnTypes));
+                                       CFArrayRef      services;
+
+                                       // filter out VPN services of the specified type
+                                       services = SCNetworkServiceCopyAll(prefs);
+                                       if (services != NULL) {
+                                               CFIndex i;
+                                               CFIndex n       = CFArrayGetCount(services);
+
+                                               for (i = 0; i < n; i++) {
+                                                       SCNetworkServiceRef     service;
+
+                                                       service = CFArrayGetValueAtIndex(services, i);
+                                                       if (_SCNetworkServiceIsVPN(service)) {
+                                                               SCNetworkInterfaceRef   child;
+                                                               CFStringRef             childType       = NULL;
+                                                               SCNetworkInterfaceRef   interface;
+                                                               CFStringRef             interfaceType;
+
+                                                               interface     = SCNetworkServiceGetInterface(service);
+                                                               interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                                                               child         = SCNetworkInterfaceGetInterface(interface);
+                                                               if (child != NULL) {
+                                                                       childType = SCNetworkInterfaceGetInterfaceType(child);
+                                                               }
+                                                               if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN) &&
+                                                                   (childType != NULL) &&
+                                                                   CFArrayContainsValue(vpnTypes, range, childType)) {
+                                                                       // filter out VPN service
+                                                                       (void) SCNetworkServiceRemove(service);
+                                                               } else {
+                                                                       // mark all other VPN services "enabled"
+                                                                       (void) SCNetworkServiceSetEnabled(service, TRUE);
+                                                               }
                                                        }
                                                }
                                                        }
                                                }
-                                       }
 
 
-                                       CFRelease(services);
+                                               CFRelease(services);
+                                       }
                                }
 
                                switch (c) {
                                }
 
                                switch (c) {
@@ -1227,14 +1289,14 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t
                }
        }
 
                }
        }
 
-       if (prefsData != NULL) {
-               if (prefsPrivate->prefs != NULL) {
-                       CFRelease(prefsPrivate->prefs);
-               }
-               prefsPrivate->prefs    = CFDictionaryCreateMutableCopy(NULL, 0, prefsData);
-               prefsPrivate->accessed = TRUE;
-               prefsPrivate->changed  = TRUE;
+       if (prefsPrivate->prefs != NULL) {
+               CFRelease(prefsPrivate->prefs);
        }
        }
+       prefsPrivate->prefs    = CFDictionaryCreateMutableCopy(NULL, 0, prefsData);
+       prefsPrivate->accessed = TRUE;
+       prefsPrivate->changed  = TRUE;
+
+    commit :
 
        ok = SCPreferencesCommitChanges(prefs);
        if (ok) {
 
        ok = SCPreferencesCommitChanges(prefs);
        if (ok) {
@@ -1364,6 +1426,24 @@ sessionName(SCHelperSessionRef session)
 }
 
 
 }
 
 
+static CFStringRef
+sessionPrefsID(SCHelperSessionRef session)
+{
+       CFStringRef                     prefsID;
+       SCPreferencesPrivateRef         prefsPrivate;
+       SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
+
+       prefsPrivate = (SCPreferencesPrivateRef)sessionPrivate->prefs;
+       if ((prefsPrivate != NULL) && (prefsPrivate->prefsID != NULL)) {
+               prefsID  = prefsPrivate->prefsID;
+       } else {
+               prefsID = PREFS_DEFAULT_CONFIG;
+       }
+
+       return prefsID;
+}
+
+
 static CFTypeRef
 copyEntitlement(SCHelperSessionRef session, CFStringRef entitlement)
 {
 static CFTypeRef
 copyEntitlement(SCHelperSessionRef session, CFStringRef entitlement)
 {
@@ -1405,34 +1485,173 @@ copyEntitlement(SCHelperSessionRef session, CFStringRef entitlement)
 }
 
 
 }
 
 
+#if    !TARGET_OS_IPHONE
+static Boolean
+isSetChange(SCHelperSessionRef session)
+{
+       SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
+
+       if (sessionPrivate->isSetChange == UNKNOWN) {
+               CFBooleanRef                    bVal            = NULL;
+               CFStringRef                     prefsID;
+               SCPreferencesPrivateRef         prefsPrivate    = (SCPreferencesPrivateRef)sessionPrivate->prefs;
+               Boolean                         setFilter       = FALSE;
+
+               prefsID = sessionPrefsID(session);
+               if (CFEqual(prefsID, PREFS_DEFAULT_CONFIG) &&
+                   isA_CFDictionary(prefsPrivate->options) &&
+                   CFDictionaryGetValueIfPresent(prefsPrivate->options,
+                                                 kSCPreferencesOptionChangeNetworkSet,
+                                                 (const void **)&bVal) &&
+                   isA_CFBoolean(bVal) &&
+                   CFBooleanGetValue(bVal)) {
+                       setFilter = TRUE;
+               }
+
+               // establish network set (location) filter
+               __SCHelperSessionSetNetworkSetFilter(session, setFilter);
+       }
+
+       return (sessionPrivate->isSetChange == YES) ? TRUE : FALSE;
+}
+#endif // !TARGET_OS_IPHONE
+
+
 static Boolean
 static Boolean
-hasAuthorization(SCHelperSessionRef session)
+isVPNChange(SCHelperSessionRef session)
 {
 {
-       AuthorizationRef                authorization   = __SCHelperSessionGetAuthorization(session);
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
+       if (sessionPrivate->isVPNChange == UNKNOWN) {
+               CFArrayRef      entitlement;
+               Boolean         vpnChange       = FALSE;
+               CFArrayRef      vpnTypes        = NULL;
+
+               entitlement = copyEntitlement(session, kSCVPNFilterEntitlementName);
+               if (entitlement != NULL) {
+                       if (isA_CFArray(entitlement)) {
+                               CFStringRef     prefsID;
+
+                               prefsID = sessionPrefsID(session);
+                               if (CFEqual(prefsID, PREFS_DEFAULT_CONFIG)) {
+                                       // save the VPN type identifiers
+                                       vpnTypes = CFRetain(entitlement);
+
+                                       // grant an exception
+                                       vpnChange = TRUE;
+                               } else if (CFStringHasPrefix(prefsID, CFSTR("VPN-")) &&
+                                          CFStringHasSuffix(prefsID, CFSTR(".plist"))) {
+                                       CFRange         range;
+                                       CFStringRef     vpnID;
+
+                                       range.location = sizeof("VPN-") - 1;
+                                       range.length   = CFStringGetLength(prefsID)
+                                                        - (sizeof("VPN-") - 1)         // trim VPN-
+                                                        - (sizeof(".plist") - 1);      // trim .plist
+                                       vpnID = CFStringCreateWithSubstring(NULL, prefsID, range);
+                                       if (CFArrayContainsValue(entitlement,
+                                                                CFRangeMake(0, CFArrayGetCount(entitlement)),
+                                                                vpnID)) {
+                                               // grant an exception
+                                               vpnChange = TRUE;
+                                       }
+                                       CFRelease(vpnID);
+                               }
+                       }
+
+                       CFRelease(entitlement);
+               }
+
+               __SCHelperSessionSetVPNFilter(session, vpnChange, vpnTypes);
+               if (vpnTypes != NULL) {
+                       CFRelease(vpnTypes);
+               }
+       }
+
+       return (sessionPrivate->isVPNChange == YES) ? TRUE : FALSE;
+}
+
+
+static Boolean
+checkEntitlement(SCHelperSessionRef session, CFStringRef prefsID, CFStringRef entitlement_name)
+{
+       CFArrayRef                      entitlement;
+       Boolean                         hasEntitlement  = FALSE;
+
+       entitlement = copyEntitlement(session, entitlement_name);
+       if (entitlement != NULL) {
+               if (isA_CFArray(entitlement)) {
+                       if (CFArrayContainsValue(entitlement,
+                                                CFRangeMake(0, CFArrayGetCount(entitlement)),
+                                                prefsID)) {
+                               // if client DOES have entitlement
+                               hasEntitlement = TRUE;
+                       }
+               } else {
+                       SCLog(TRUE, LOG_ERR,
+                             CFSTR("hasAuthorization() entitlement=%@: not valid"),
+                             entitlement_name,
+                             sessionName(session));
+               }
+
+               CFRelease(entitlement);
+       }
+
+#if    TARGET_OS_IPHONE
+       // make an exception for VPN configuration management
+       if (!hasEntitlement) {
+               if (isVPNChange(session)) {
+                       // grant a "filtered" exception
+                       hasEntitlement = TRUE;
+               }
+       }
+#endif // TARGET_OS_IPHONE
+
+       return hasEntitlement;
+}
+
+
+static Boolean
+hasAuthorization(SCHelperSessionRef session, Boolean needWrite)
+{
+       AuthorizationRef                authorization           = __SCHelperSessionGetAuthorization(session);
+       CFStringRef                     prefsID;
+       SCHelperSessionPrivateRef       sessionPrivate          = (SCHelperSessionPrivateRef)session;
+
        if (authorization == NULL) {
                return FALSE;
        }
 
        if (authorization == NULL) {
                return FALSE;
        }
 
-#if !TARGET_OS_IPHONE
+#if    !TARGET_OS_IPHONE
        if (!__SCHelperSessionUseEntitlement(session)) {
                AuthorizationFlags      flags;
                AuthorizationItem       items[1];
                AuthorizationRights     rights;
                OSStatus                status;
 
        if (!__SCHelperSessionUseEntitlement(session)) {
                AuthorizationFlags      flags;
                AuthorizationItem       items[1];
                AuthorizationRights     rights;
                OSStatus                status;
 
-               items[0].name        = kSCPreferencesWriteAuthorizationRight;
-               items[0].value       = NULL;
-               items[0].valueLength = 0;
-               items[0].flags       = 0;
+               if (isSetChange(session)) {
+                       items[0].name        = kSCPreferencesAuthorizationRight_network_set;
+                       items[0].value       = NULL;
+                       items[0].valueLength = 0;
+                       items[0].flags       = 0;
+               } else if (isVPNChange(session)) {
+                       items[0].name        = kSCPreferencesAuthorizationRight_write;
+                       items[0].value       = NULL;
+                       items[0].valueLength = 0;
+                       items[0].flags       = 0;
+               } else {
+                       items[0].name        = kSCPreferencesAuthorizationRight_write;
+                       items[0].value       = NULL;
+                       items[0].valueLength = 0;
+                       items[0].flags       = 0;
+               }
 
                rights.count = sizeof(items) / sizeof(items[0]);
                rights.items = items;
 
                flags = kAuthorizationFlagDefaults;
 
                rights.count = sizeof(items) / sizeof(items[0]);
                rights.items = items;
 
                flags = kAuthorizationFlagDefaults;
-               flags |= kAuthorizationFlagExtendRights;
                flags |= kAuthorizationFlagInteractionAllowed;
                flags |= kAuthorizationFlagInteractionAllowed;
+               flags |= kAuthorizationFlagExtendRights;
 //             flags |= kAuthorizationFlagPartialRights;
 //             flags |= kAuthorizationFlagPreAuthorize;
 
 //             flags |= kAuthorizationFlagPartialRights;
 //             flags |= kAuthorizationFlagPreAuthorize;
 
@@ -1447,81 +1666,48 @@ hasAuthorization(SCHelperSessionRef session)
 
                return TRUE;
        }
 
                return TRUE;
        }
-#endif // !TARGET_OS_IPHONE
-
-       if (sessionPrivate->callerWriteAccess == UNKNOWN) {
-               CFArrayRef              entitlement;
-               CFStringRef             prefsID;
-               SCPreferencesPrivateRef prefsPrivate;
-
-               // assume that the client DOES NOT have the entitlement
-               sessionPrivate->callerWriteAccess = NO;
-
-               prefsPrivate = (SCPreferencesPrivateRef)sessionPrivate->prefs;
-               prefsID      = (prefsPrivate->prefsID != NULL) ? prefsPrivate->prefsID : PREFS_DEFAULT_CONFIG;
-
-               entitlement = copyEntitlement(session, kSCWriteEntitlementName);
-               if (entitlement != NULL) {
-                       if (isA_CFArray(entitlement)) {
-                               if (CFArrayContainsValue(entitlement,
-                                                        CFRangeMake(0, CFArrayGetCount(entitlement)),
-                                                        prefsID)) {
-                                       // if client DOES have entitlement
-                                       sessionPrivate->callerWriteAccess = YES;
-                               }
-                       } else {
-                               SCLog(TRUE, LOG_ERR,
-                                     CFSTR("hasAuthorization: entitlement not valid: %@"),
-                                     sessionName(session));
-                       }
-
-                       CFRelease(entitlement);
-               }
+#endif // !TARGET_OS_IPHONE
 
 
-               // make an exception for VPN configuration management
-               if (sessionPrivate->callerWriteAccess != YES) {
-                       entitlement = copyEntitlement(session, kSCVPNFilterEntitlementName);
-                       if (entitlement != NULL) {
-                               if (isA_CFArray(entitlement)) {
-                                       if (CFEqual(prefsID, PREFS_DEFAULT_CONFIG)) {
-                                               // save the VPN bundle identifiers
-                                               __SCHelperSessionSetVPNFilter(session, entitlement);
-
-                                               // and grant a "filtered" exception
-                                               sessionPrivate->callerWriteAccess = YES;
-                                       } else if (CFStringHasPrefix(prefsID, CFSTR("VPN-")) &&
-                                                  CFStringHasSuffix(prefsID, CFSTR(".plist"))) {
-                                               CFRange         range;
-                                               CFStringRef     vpnID;
-
-                                               range.location = sizeof("VPN-") - 1;
-                                               range.length   = CFStringGetLength(prefsID)
-                                                                - (sizeof("VPN-") - 1)         // trim VPN-
-                                                                - (sizeof(".plist") - 1);      // trim .plist
-                                               vpnID = CFStringCreateWithSubstring(NULL, prefsID, range);
-                                               if (CFArrayContainsValue(entitlement,
-                                                                        CFRangeMake(0, CFArrayGetCount(entitlement)),
-                                                                        vpnID)) {
-                                                       // grant an exception
-                                                       sessionPrivate->callerWriteAccess = YES;
-                                               }
-                                               CFRelease(vpnID);
-                                       }
-                               }
+       prefsID = sessionPrefsID(session);
 
 
-                               CFRelease(entitlement);
-                       }
+       if (sessionPrivate->callerWriteAccess == UNKNOWN) {
+               if (checkEntitlement(session, prefsID, kSCWriteEntitlementName)) {
+                       sessionPrivate->callerWriteAccess = YES;
+                       sessionPrivate->callerReadAccess  = YES;        // implied
+               } else {
+                       sessionPrivate->callerWriteAccess = NO;
                }
                }
+       }
 
 
-               if (sessionPrivate->callerWriteAccess != YES) {
+       if (needWrite) {
+               if (sessionPrivate->callerWriteAccess == YES) {
+                       return TRUE;
+               } else {
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("SCPreferences write access to \"%@\" denied, no entitlement for \"%@\""),
                              prefsID,
                              sessionName(session));
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("SCPreferences write access to \"%@\" denied, no entitlement for \"%@\""),
                              prefsID,
                              sessionName(session));
+                       return FALSE;
+               }
+       }
+
+       if (sessionPrivate->callerReadAccess == UNKNOWN) {
+               if (checkEntitlement(session, prefsID, kSCReadEntitlementName)) {
+                       sessionPrivate->callerReadAccess  = YES;
+               } else {
+                       sessionPrivate->callerWriteAccess = NO;
                }
        }
 
                }
        }
 
-       return (sessionPrivate->callerWriteAccess == YES) ? TRUE : FALSE;
+       if (sessionPrivate->callerReadAccess == YES) {
+               return TRUE;
+       }
+
+       SCLog(TRUE, LOG_ERR,
+             CFSTR("SCPreferences access to \"%@\" denied, no entitlement for \"%@\""),
+             prefsID,
+             sessionName(session));
+       return FALSE;
 }
 
 
 }
 
 
@@ -1536,31 +1722,32 @@ static const struct helper {
        int             command;
        const char      *commandName;
        Boolean         needsAuthorization;
        int             command;
        const char      *commandName;
        Boolean         needsAuthorization;
+       Boolean         needsWrite;
        helperFunction  func;
        void            *info;
 } helpers[] = {
        helperFunction  func;
        void            *info;
 } helpers[] = {
-       { SCHELPER_MSG_AUTH,                    "AUTH",                 FALSE,  do_Auth                 , NULL          },
+       { SCHELPER_MSG_AUTH,                    "AUTH",                 FALSE,  FALSE,  do_Auth                 , NULL          },
 
 
-       { SCHELPER_MSG_PREFS_OPEN,              "PREFS open",           FALSE,  do_prefs_Open           , NULL          },
-       { SCHELPER_MSG_PREFS_ACCESS,            "PREFS access",         TRUE,   do_prefs_Access         , NULL          },
-       { SCHELPER_MSG_PREFS_LOCK,              "PREFS lock",           TRUE,   do_prefs_Lock           , (void *)FALSE },
-       { SCHELPER_MSG_PREFS_LOCKWAIT,          "PREFS lock/wait",      TRUE,   do_prefs_Lock           , (void *)TRUE  },
-       { SCHELPER_MSG_PREFS_COMMIT,            "PREFS commit",         TRUE,   do_prefs_Commit         , NULL          },
-       { SCHELPER_MSG_PREFS_APPLY,             "PREFS apply",          TRUE,   do_prefs_Apply          , NULL          },
-       { SCHELPER_MSG_PREFS_UNLOCK,            "PREFS unlock",         FALSE,  do_prefs_Unlock         , NULL          },
-       { SCHELPER_MSG_PREFS_CLOSE,             "PREFS close",          FALSE,  do_prefs_Close          , NULL          },
-       { SCHELPER_MSG_PREFS_SYNCHRONIZE,       "PREFS synchronize",    FALSE,  do_prefs_Synchronize    , NULL          },
+       { SCHELPER_MSG_PREFS_OPEN,              "PREFS open",           FALSE,  FALSE,  do_prefs_Open           , NULL          },
+       { SCHELPER_MSG_PREFS_ACCESS,            "PREFS access",         TRUE,   FALSE,  do_prefs_Access         , NULL          },
+       { SCHELPER_MSG_PREFS_LOCK,              "PREFS lock",           TRUE,   TRUE,   do_prefs_Lock           , (void *)FALSE },
+       { SCHELPER_MSG_PREFS_LOCKWAIT,          "PREFS lock/wait",      TRUE,   TRUE,   do_prefs_Lock           , (void *)TRUE  },
+       { SCHELPER_MSG_PREFS_COMMIT,            "PREFS commit",         TRUE,   TRUE,   do_prefs_Commit         , NULL          },
+       { SCHELPER_MSG_PREFS_APPLY,             "PREFS apply",          TRUE,   TRUE,   do_prefs_Apply          , NULL          },
+       { SCHELPER_MSG_PREFS_UNLOCK,            "PREFS unlock",         FALSE,  TRUE,   do_prefs_Unlock         , NULL          },
+       { SCHELPER_MSG_PREFS_CLOSE,             "PREFS close",          FALSE,  FALSE,  do_prefs_Close          , NULL          },
+       { SCHELPER_MSG_PREFS_SYNCHRONIZE,       "PREFS synchronize",    FALSE,  FALSE,  do_prefs_Synchronize    , NULL          },
 
 
-       { SCHELPER_MSG_INTERFACE_REFRESH,       "INTERFACE refresh",    TRUE,   do_interface_refresh    , NULL          },
+       { SCHELPER_MSG_INTERFACE_REFRESH,       "INTERFACE refresh",    TRUE,   TRUE,   do_interface_refresh    , NULL          },
 
 #if    !TARGET_OS_IPHONE
 
 #if    !TARGET_OS_IPHONE
-       { SCHELPER_MSG_KEYCHAIN_COPY,           "KEYCHAIN copy",        TRUE,   do_keychain_copy        , NULL          },
-       { SCHELPER_MSG_KEYCHAIN_EXISTS,         "KEYCHAIN exists",      TRUE,   do_keychain_exists      , NULL          },
-       { SCHELPER_MSG_KEYCHAIN_REMOVE,         "KEYCHAIN remove",      TRUE,   do_keychain_remove      , NULL          },
-       { SCHELPER_MSG_KEYCHAIN_SET,            "KEYCHAIN set",         TRUE,   do_keychain_set         , NULL          },
+       { SCHELPER_MSG_KEYCHAIN_COPY,           "KEYCHAIN copy",        TRUE,   FALSE,  do_keychain_copy        , NULL          },
+       { SCHELPER_MSG_KEYCHAIN_EXISTS,         "KEYCHAIN exists",      TRUE,   FALSE,  do_keychain_exists      , NULL          },
+       { SCHELPER_MSG_KEYCHAIN_REMOVE,         "KEYCHAIN remove",      TRUE,   TRUE,   do_keychain_remove      , NULL          },
+       { SCHELPER_MSG_KEYCHAIN_SET,            "KEYCHAIN set",         TRUE,   TRUE,   do_keychain_set         , NULL          },
 #endif // !TARGET_OS_IPHONE
 
 #endif // !TARGET_OS_IPHONE
 
-       { SCHELPER_MSG_EXIT,                    "EXIT",                 FALSE,  do_Exit                 , NULL          }
+       { SCHELPER_MSG_EXIT,                    "EXIT",                 FALSE,  FALSE,  do_Exit                 , NULL          }
 };
 #define nHELPERS (sizeof(helpers)/sizeof(struct helper))
 
 };
 #define nHELPERS (sizeof(helpers)/sizeof(struct helper))
 
@@ -1587,6 +1774,9 @@ newHelper(void *arg)
        SCHelperSessionRef              session         = (SCHelperSessionRef)arg;
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
        SCHelperSessionRef              session         = (SCHelperSessionRef)arg;
        SCHelperSessionPrivateRef       sessionPrivate  = (SCHelperSessionPrivateRef)session;
 
+       assert(session != NULL);
+       assert(sessionPrivate->mp != NULL);
+
        __SCHelperSessionSetThreadName(session);
 
        rls = CFMachPortCreateRunLoopSource(NULL, sessionPrivate->mp, 0);
        __SCHelperSessionSetThreadName(session);
 
        rls = CFMachPortCreateRunLoopSource(NULL, sessionPrivate->mp, 0);
@@ -1726,6 +1916,10 @@ helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
        static CFIndex          bufSize         = 0;
        mach_msg_return_t       mr;
        int                     options;
        static CFIndex          bufSize         = 0;
        mach_msg_return_t       mr;
        int                     options;
+       int                     ret             = 0;
+       uint64_t                token;
+
+       ret = proc_importance_assertion_begin_with_msg(&bufRequest->Head, NULL, &token);
 
        if (bufSize == 0) {
                // get max size for MiG reply buffers
 
        if (bufSize == 0) {
                // get max size for MiG reply buffers
@@ -1800,7 +1994,11 @@ helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
                mach_msg_destroy(&bufReply->Head);
        }
 
                mach_msg_destroy(&bufReply->Head);
        }
 
-       done :
+    done :
+
+       if (ret == 0) {
+               proc_importance_assertion_complete(token);
+       }
 
        if (bufReply != (mig_reply_error_t *)bufReply_q)
                CFAllocatorDeallocate(NULL, bufReply);
 
        if (bufReply != (mig_reply_error_t *)bufReply_q)
                CFAllocatorDeallocate(NULL, bufReply);
@@ -1845,6 +2043,7 @@ _helperinit(mach_port_t                   server,
        }
 
        session = __SCHelperSessionCreate(NULL);
        }
 
        session = __SCHelperSessionCreate(NULL);
+       assert(session != NULL);
        sessionPrivate = (SCHelperSessionPrivateRef)session;
 
        // create per-session port
        sessionPrivate = (SCHelperSessionPrivateRef)session;
 
        // create per-session port
@@ -1853,6 +2052,12 @@ _helperinit(mach_port_t                  server,
                                  &sessionPrivate->port);
        *newSession = sessionPrivate->port;
 
                                  &sessionPrivate->port);
        *newSession = sessionPrivate->port;
 
+       (void) mach_port_set_attributes(mach_task_self(),
+                                       *newSession,
+                                       MACH_PORT_IMPORTANCE_RECEIVER,
+                                       NULL,
+                                       0);
+
        //
        // Note: we create the CFMachPort *before* we insert a send
        //       right present to ensure that CF does not establish
        //
        // Note: we create the CFMachPort *before* we insert a send
        //       right present to ensure that CF does not establish
@@ -1978,7 +2183,8 @@ _helperexec(mach_port_t                   server,
              helpers[i].commandName,
              (data != NULL) ? " w/data" : "");
 
              helpers[i].commandName,
              (data != NULL) ? " w/data" : "");
 
-       if (helpers[i].needsAuthorization && !hasAuthorization(session)) {
+       if (helpers[i].needsAuthorization &&
+           !hasAuthorization(session, helpers[i].needsWrite)) {
                SCLog(debug, LOG_DEBUG,
                      CFSTR("%p : command \"%s\" : not authorized"),
                      session,
                SCLog(debug, LOG_DEBUG,
                      CFSTR("%p : command \"%s\" : not authorized"),
                      session,
index abf809552cd0d578fa4c357805df8a93fcb24db2..bafb82f9210b45ac57b9c6bce2f91d0d70331f94 100644 (file)
@@ -11,5 +11,7 @@
                <key>com.apple.SystemConfiguration.helper</key>
                <true/>
        </dict>
                <key>com.apple.SystemConfiguration.helper</key>
                <true/>
        </dict>
+       <key>POSIXSpawnType</key>
+       <string>Adaptive</string>
 </dict>
 </plist>
 </dict>
 </plist>
index ee55286d4bf9be294fed1beac06965d635fb9ba3..b6612a4f89b5ab0d3fb512f4988d2208febcb4a0 100644 (file)
@@ -5,11 +5,13 @@
        <key>Label</key>
        <string>com.apple.SCHelper</string>
        <key>Program</key>
        <key>Label</key>
        <string>com.apple.SCHelper</string>
        <key>Program</key>
-       <string>/System/Library/Frameworks/SystemConfiguration.framework/Resources/SCHelper</string>
+       <string>/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/Helpers/SCHelper</string>
        <key>MachServices</key>
        <dict>
                <key>com.apple.SystemConfiguration.helper</key>
                <true/>
        </dict>
        <key>MachServices</key>
        <dict>
                <key>com.apple.SystemConfiguration.helper</key>
                <true/>
        </dict>
+       <key>POSIXSpawnType</key>
+       <string>Adaptive</string>
 </dict>
 </plist>
 </dict>
 </plist>
index 09c0ea64dab65b3451d11ee0e71762ae48eeff28..13196ea568d20d6d87184dfca19ccd412a2fe695 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 #include <xpc/xpc.h>
 #include <xpc/private.h>
 
 #include <xpc/xpc.h>
 #include <xpc/private.h>
-
-#include "rb.h"
+#include <sys/rbtree.h>
 
 
 #pragma mark -
 #pragma mark Globals
 
 
 
 
 #pragma mark -
 #pragma mark Globals
 
 
-static const struct addrinfo   hints0  = {
-#ifdef  AI_PARALLEL
-       .ai_flags       = AI_PARALLEL | AI_ADDRCONFIG
-#else  // AI_PARALLEL
-       .ai_flags       = AI_ADDRCONFIG
-#endif  // AI_PARALLEL
-};
-
-
 static Boolean                 serverAvailable = TRUE;
 
 
 static Boolean                 serverAvailable = TRUE;
 
 
@@ -70,50 +60,48 @@ log_xpc_object(const char *msg, xpc_object_t obj)
 
 
 typedef struct {
 
 
 typedef struct {
-       struct rb_node                  rbn;
+       rb_node_t                       rbn;
        SCNetworkReachabilityRef        target;
 } reach_request_t;
 
 
        SCNetworkReachabilityRef        target;
 } reach_request_t;
 
 
-#define RBNODE_TO_REACH_REQUEST(node) \
-       ((reach_request_t *)((uintptr_t)node - offsetof(reach_request_t, rbn)))
-
-
 static int
 static int
-_rbt_compare_transaction_nodes(const struct rb_node *n1, const struct rb_node *n2)
+_rbt_compare_transaction_nodes(void *context, const void *n1, const void *n2)
 {
 {
-       uint64_t        a = (uintptr_t)(RBNODE_TO_REACH_REQUEST(n1)->target);
-       uint64_t        b = (uintptr_t)(RBNODE_TO_REACH_REQUEST(n2)->target);
+       uint64_t        a = (uintptr_t)(((reach_request_t *)n1)->target);
+       uint64_t        b = (uintptr_t)(((reach_request_t *)n2)->target);
 
        return (a - b);
 }
 
 
 static int
 
        return (a - b);
 }
 
 
 static int
-_rbt_compare_transaction_key(const struct rb_node *n1, const void *key)
+_rbt_compare_transaction_key(void *context, const void *n1, const void *key)
 {
 {
-       uint64_t        a = (uintptr_t)(RBNODE_TO_REACH_REQUEST(n1)->target);
+       uint64_t        a = (uintptr_t)(((reach_request_t *)n1)->target);
        uint64_t        b = *(uint64_t *)key;
 
        return (a - b);
 }
 
 
        uint64_t        b = *(uint64_t *)key;
 
        return (a - b);
 }
 
 
-static struct rb_tree *
+static rb_tree_t *
 _reach_requests_rbt()
 {
        static dispatch_once_t          once;
 _reach_requests_rbt()
 {
        static dispatch_once_t          once;
-       static const struct rb_tree_ops ops = {
+       static const rb_tree_ops_t      ops = {
                .rbto_compare_nodes     = _rbt_compare_transaction_nodes,
                .rbto_compare_key       = _rbt_compare_transaction_key,
                .rbto_compare_nodes     = _rbt_compare_transaction_nodes,
                .rbto_compare_key       = _rbt_compare_transaction_key,
+               .rbto_node_offset       = offsetof(reach_request_t, rbn),
+               .rbto_context           = NULL
        };
        };
-       static struct rb_tree           rbtree;
+       static rb_tree_t                rbt;
 
        dispatch_once(&once, ^{
 
        dispatch_once(&once, ^{
-               rb_tree_init(&rbtree, &ops);
+               rb_tree_init(&rbt, &ops);
        });
 
        });
 
-       return &rbtree;
+       return &rbt;
 }
 
 
 }
 
 
@@ -124,7 +112,7 @@ _reach_requests_rbt_queue()
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
-               q = dispatch_queue_create(REACH_SERVICE_NAME ".rbt", NULL);
+               q = dispatch_queue_create(REACH_SERVICE_NAME ".requests.rbt", NULL);
        });
 
        return q;
        });
 
        return q;
@@ -161,14 +149,13 @@ _reach_request_add(SCNetworkReachabilityRef target)
        uint64_t        target_id       = (uintptr_t)target;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{
        uint64_t        target_id       = (uintptr_t)target;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{
-               struct rb_node          *rbn;
-
-               rbn = rb_tree_find_node(_reach_requests_rbt(), &target_id);
-               if (rbn == NULL) {
-                       reach_request_t *request;
+               rb_tree_t       *rbt    = _reach_requests_rbt();
+               reach_request_t *request;
 
 
+               request = rb_tree_find_node(rbt, &target_id);
+               if (request == NULL) {
                        request = _reach_request_create(target);
                        request = _reach_request_create(target);
-                       if (request == NULL || !rb_tree_insert_node(_reach_requests_rbt(), &request->rbn)) {
+                       if (request == NULL || !rb_tree_insert_node(rbt, request)) {
                                __builtin_trap();
                        }
                }
                                __builtin_trap();
                        }
                }
@@ -184,17 +171,17 @@ _reach_request_remove(SCNetworkReachabilityRef target)
        uint64_t        target_id       = (uintptr_t)target;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{           // FIXME ?? use dispatch_async?
        uint64_t        target_id       = (uintptr_t)target;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{           // FIXME ?? use dispatch_async?
-               struct rb_node          *rbn;
-               struct rb_tree          *rbtree = _reach_requests_rbt();
-
-               rbn = rb_tree_find_node(rbtree, &target_id);
-               if (rbn != NULL) {
-                       reach_request_t *request        = RBNODE_TO_REACH_REQUEST(rbn);
+               rb_tree_t       *rbt    = _reach_requests_rbt();
+               reach_request_t *request;
 
 
-                       rb_tree_remove_node(rbtree, rbn);
+               request = rb_tree_find_node(rbt, &target_id);
+               if (request != NULL) {
+                       rb_tree_remove_node(rbt, request);
                        _reach_request_release(request);
                }
        });
                        _reach_request_release(request);
                }
        });
+
+       return;
 }
 
 
 }
 
 
@@ -204,12 +191,12 @@ _reach_request_copy_target(uint64_t target_id)
        __block SCNetworkReachabilityRef        target  = NULL;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{
        __block SCNetworkReachabilityRef        target  = NULL;
 
        dispatch_sync(_reach_requests_rbt_queue(), ^{
-               struct rb_node  *rbn;
+               rb_tree_t       *rbt    = _reach_requests_rbt();
+               reach_request_t *request;
 
 
-               rbn = rb_tree_find_node(_reach_requests_rbt(), &target_id);
-               if (rbn != NULL) {
-                       // handle the [async] reply
-                       target = (SCNetworkReachabilityRef)(uintptr_t)target_id;
+               request = rb_tree_find_node(rbt, &target_id);
+               if (request != NULL) {
+                       target = request->target;
                        CFRetain(target);
                }
        });
                        CFRetain(target);
                }
        });
@@ -233,7 +220,7 @@ handle_reachability_status(SCNetworkReachabilityRef target, xpc_object_t dict)
 //             log_xpc_object("  status", dict);
        }
 
 //             log_xpc_object("  status", dict);
        }
 
-       __SCNetworkReachabilityPerformNoLock(target);
+       __SCNetworkReachabilityPerformConcurrent(target);
 
        return;
 }
 
        return;
 }
@@ -284,6 +271,11 @@ static xpc_connection_t
 _reach_connection_create()
 {
        xpc_connection_t                c;
 _reach_connection_create()
 {
        xpc_connection_t                c;
+#if    !TARGET_IPHONE_SIMULATOR
+       const uint64_t          flags   =       XPC_CONNECTION_MACH_SERVICE_PRIVILEGED;
+#else  // !TARGET_IPHONE_SIMULATOR
+       const uint64_t          flags   =       0;
+#endif // !TARGET_IPHONE_SIMULATOR
        const char                      *name;
        dispatch_queue_t                q       = _reach_xpc_queue();
 
        const char                      *name;
        dispatch_queue_t                q       = _reach_xpc_queue();
 
@@ -293,9 +285,7 @@ _reach_connection_create()
                name = REACH_SERVICE_NAME;
        }
 
                name = REACH_SERVICE_NAME;
        }
 
-       c = xpc_connection_create_mach_service(name,
-                                              q,
-                                              XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
+       c = xpc_connection_create_mach_service(name, q, flags);
 
        xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) {
                xpc_type_t      type;
 
        xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) {
                xpc_type_t      type;
@@ -316,14 +306,18 @@ _reach_connection_create()
 
                        target = _reach_request_copy_target(target_id);
                        if (target == NULL) {
 
                        target = _reach_request_copy_target(target_id);
                        if (target == NULL) {
-                               SCLog(TRUE, LOG_ERR,
-                                     CFSTR("received unexpected target [ID] from SCNetworkReachability server"));
-                               log_xpc_object("  reply", xobj);
+//                             SCLog(TRUE, LOG_ERR,
+//                                   CFSTR("received unexpected target [ID] from SCNetworkReachability server"));
+//                             log_xpc_object("  reply", xobj);
                                return;
                        }
 
                                return;
                        }
 
-                       handle_async_notification(target, xobj);
-                       CFRelease(target);
+                       xpc_retain(xobj);
+                       dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{
+                               handle_async_notification(target, xobj);
+                               CFRelease(target);
+                               xpc_release(xobj);
+                       });
 
                } else if (type == XPC_TYPE_ERROR) {
                        if (xobj == XPC_ERROR_CONNECTION_INVALID) {
 
                } else if (type == XPC_TYPE_ERROR) {
                        if (xobj == XPC_ERROR_CONNECTION_INVALID) {
@@ -403,7 +397,7 @@ add_proc_name(xpc_object_t reqdict)
 
 
 static void
 
 
 static void
-_reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilityRef target);
+_reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilityRef target, Boolean disconnect);
 
 
 static Boolean
 
 
 static Boolean
@@ -427,11 +421,6 @@ _reach_server_target_add(xpc_connection_t connection, SCNetworkReachabilityRef t
                                          REACH_TARGET_NAME,
                                          targetPrivate->name);
        }
                                          REACH_TARGET_NAME,
                                          targetPrivate->name);
        }
-       if (targetPrivate->serv != NULL) {
-               xpc_dictionary_set_string(reqdict,
-                                         REACH_TARGET_SERV,
-                                         targetPrivate->serv);
-       }
        if (targetPrivate->localAddress != NULL) {
                xpc_dictionary_set_data(reqdict,
                                        REACH_TARGET_LOCAL_ADDR,
        if (targetPrivate->localAddress != NULL) {
                xpc_dictionary_set_data(reqdict,
                                        REACH_TARGET_LOCAL_ADDR,
@@ -444,12 +433,6 @@ _reach_server_target_add(xpc_connection_t connection, SCNetworkReachabilityRef t
                                        targetPrivate->remoteAddress,
                                        targetPrivate->remoteAddress->sa_len);
        }
                                        targetPrivate->remoteAddress,
                                        targetPrivate->remoteAddress->sa_len);
        }
-       if (bcmp(&targetPrivate->hints, &hints0, sizeof(struct addrinfo)) != 0) {
-               xpc_dictionary_set_data(reqdict,
-                                       REACH_TARGET_HINTS,
-                                       &targetPrivate->hints,
-                                       sizeof(targetPrivate->hints));
-       }
        if (targetPrivate->if_index != 0) {
                xpc_dictionary_set_int64(reqdict,
                                         REACH_TARGET_IF_INDEX,
        if (targetPrivate->if_index != 0) {
                xpc_dictionary_set_int64(reqdict,
                                         REACH_TARGET_IF_INDEX,
@@ -470,6 +453,7 @@ _reach_server_target_add(xpc_connection_t connection, SCNetworkReachabilityRef t
        }
 
 
        }
 
 
+
        // add the target [ID]
        xpc_dictionary_set_uint64(reqdict, REACH_CLIENT_TARGET_ID, (uintptr_t)target);
 
        // add the target [ID]
        xpc_dictionary_set_uint64(reqdict, REACH_CLIENT_TARGET_ID, (uintptr_t)target);
 
@@ -549,9 +533,9 @@ _reach_server_target_remove(xpc_connection_t connection, SCNetworkReachabilityRe
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
-                                       SCLog(TRUE, LOG_DEBUG,
-                                             CFSTR("reach target %p: SCNetworkReachability server failure, no need to remove"),
-                                             target);
+                                       // target not known by the server (most likely due to a
+                                       // SCNetworkReachability server failure), no need to
+                                       // remove.
                                        ok = TRUE;
                                        break;
                                default : {
                                        ok = TRUE;
                                        break;
                                default : {
@@ -619,9 +603,9 @@ _reach_server_target_schedule(xpc_connection_t connection, SCNetworkReachability
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
-                                       SCLog(TRUE, LOG_DEBUG,
-                                             CFSTR("reach target %p: SCNetworkReachability server failure, retry schedule"),
-                                             target);
+                                       // target not known by the server (most likely due to a
+                                       // SCNetworkReachability server failure), re-establish
+                                       // and retry scheduling.
                                        retry = TRUE;
                                        break;
                                default : {
                                        retry = TRUE;
                                        break;
                                default : {
@@ -655,7 +639,7 @@ _reach_server_target_schedule(xpc_connection_t connection, SCNetworkReachability
 
        if (retry) {
                // reconnect
 
        if (retry) {
                // reconnect
-               _reach_server_target_reconnect(connection, target);
+               _reach_server_target_reconnect(connection, target, FALSE);
 
                // and retry
                retry = FALSE;
 
                // and retry
                retry = FALSE;
@@ -671,8 +655,9 @@ static void
 _reach_reply_set_reachability(SCNetworkReachabilityRef target,
                              xpc_object_t              reply)
 {
 _reach_reply_set_reachability(SCNetworkReachabilityRef target,
                              xpc_object_t              reply)
 {
-       char                            *if_name;
-       size_t                          len             = 0;
+       char    *if_name;
+       size_t  len             = 0;
+
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        targetPrivate->serverInfo.cycle = xpc_dictionary_get_uint64(reply,
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        targetPrivate->serverInfo.cycle = xpc_dictionary_get_uint64(reply,
@@ -702,20 +687,20 @@ _reach_reply_set_reachability(SCNetworkReachabilityRef    target,
        if (targetPrivate->type == reachabilityTypeName) {
                xpc_object_t            addresses;
 
        if (targetPrivate->type == reachabilityTypeName) {
                xpc_object_t            addresses;
 
-               if (targetPrivate->resolvedAddress != NULL) {
-                       CFRelease(targetPrivate->resolvedAddress);
-                       targetPrivate->resolvedAddress = NULL;
+               if (targetPrivate->resolvedAddresses != NULL) {
+                       CFRelease(targetPrivate->resolvedAddresses);
+                       targetPrivate->resolvedAddresses = NULL;
                }
 
                }
 
-               targetPrivate->resolvedAddressError = xpc_dictionary_get_int64(reply,
-                                                                              REACH_STATUS_RESOLVED_ADDRESS_ERROR);
+               targetPrivate->resolvedError = xpc_dictionary_get_int64(reply,
+                                                                       REACH_STATUS_RESOLVED_ERROR);
 
 
-               addresses = xpc_dictionary_get_value(reply, REACH_STATUS_RESOLVED_ADDRESS);
+               addresses = xpc_dictionary_get_value(reply, REACH_STATUS_RESOLVED_ADDRESSES);
                if ((addresses != NULL) && (xpc_get_type(addresses) != XPC_TYPE_ARRAY)) {
                        addresses = NULL;
                }
 
                if ((addresses != NULL) && (xpc_get_type(addresses) != XPC_TYPE_ARRAY)) {
                        addresses = NULL;
                }
 
-               if ((targetPrivate->resolvedAddressError == 0) && (addresses != NULL)) {
+               if ((targetPrivate->resolvedError == NETDB_SUCCESS) && (addresses != NULL)) {
                        int                     i;
                        int                     n;
                        CFMutableArrayRef       newAddresses;
                        int                     i;
                        int                     n;
                        CFMutableArrayRef       newAddresses;
@@ -734,10 +719,10 @@ _reach_reply_set_reachability(SCNetworkReachabilityRef    target,
                                CFRelease(newAddress);
                        }
 
                                CFRelease(newAddress);
                        }
 
-                       targetPrivate->resolvedAddress = newAddresses;
+                       targetPrivate->resolvedAddresses = newAddresses;
                } else {
                        /* save the error associated with the attempt to resolve the name */
                } else {
                        /* save the error associated with the attempt to resolve the name */
-                       targetPrivate->resolvedAddress = CFRetain(kCFNull);
+                       targetPrivate->resolvedAddresses = CFRetain(kCFNull);
                }
                targetPrivate->needResolve = FALSE;
        }
                }
                targetPrivate->needResolve = FALSE;
        }
@@ -746,8 +731,7 @@ _reach_reply_set_reachability(SCNetworkReachabilityRef      target,
 }
 
 
 }
 
 
-__private_extern__
-Boolean
+static Boolean
 _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRef target)
 {
        Boolean                         ok              = FALSE;
 _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRef target)
 {
        Boolean                         ok              = FALSE;
@@ -791,9 +775,9 @@ _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRe
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
-                                       SCLog(TRUE, LOG_DEBUG,
-                                             CFSTR("reach target %p: SCNetworkReachability server failure, retry status"),
-                                             target);
+                                       // target not known by the server (most likely due to a
+                                       // SCNetworkReachability server failure), re-establish
+                                       // and retry status.
                                        retry = TRUE;
                                        break;
                                default :
                                        retry = TRUE;
                                        break;
                                default :
@@ -844,7 +828,7 @@ _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRe
 
        if (retry) {
                // reconnect
 
        if (retry) {
                // reconnect
-               _reach_server_target_reconnect(connection, target);
+               _reach_server_target_reconnect(connection, target, FALSE);
 
                // and retry
                retry = FALSE;
 
                // and retry
                retry = FALSE;
@@ -862,6 +846,7 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili
        Boolean                         ok              = FALSE;
        xpc_object_t                    reply;
        xpc_object_t                    reqdict;
        Boolean                         ok              = FALSE;
        xpc_object_t                    reply;
        xpc_object_t                    reqdict;
+       Boolean                         retry           = FALSE;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        // create message
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
        // create message
@@ -887,19 +872,16 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
                                        ok = TRUE;
                                        break;
                                case REACH_REQUEST_REPLY_UNKNOWN :
-                                       SCLog(TRUE, LOG_DEBUG,
-                                             CFSTR("reach target %p: SCNetworkReachability server failure, no need to unschedule"),
-                                             target);
+                                       // target not known by the server (most likely due to a
+                                       // SCNetworkReachability server failure), re-establish
+                                       // but no need to unschedule.
+                                       retry = TRUE;
                                        break;
                                default :
                                        SCLog(TRUE, LOG_INFO, CFSTR("%s  target unschedule failed"),
                                              targetPrivate->log_prefix);
                                        log_xpc_object("  reply", reply);
                        }
                                        break;
                                default :
                                        SCLog(TRUE, LOG_INFO, CFSTR("%s  target unschedule failed"),
                                              targetPrivate->log_prefix);
                                        log_xpc_object("  reply", reply);
                        }
-
-                       if (ok) {
-                               CFRelease(target);
-                       }
                } else if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INVALID)) {
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("SCNetworkReachability server not available"));
                } else if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INVALID)) {
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("SCNetworkReachability server not available"));
@@ -907,9 +889,9 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili
                        ok = TRUE;
                } else if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INTERRUPTED)) {
                        SCLog(TRUE, LOG_DEBUG,
                        ok = TRUE;
                } else if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INTERRUPTED)) {
                        SCLog(TRUE, LOG_DEBUG,
-                             CFSTR("reach target %p: SCNetworkReachability server failure, no need to unschedule"),
+                             CFSTR("reach target %p: SCNetworkReachability server failure, re-establish (but do not re-schedule)"),
                              target);
                              target);
-                       ok = TRUE;
+                       retry = TRUE;
                } else {
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("reach target %p: _targetUnschedule with unexpected reply"),
                } else {
                        SCLog(TRUE, LOG_ERR,
                              CFSTR("reach target %p: _targetUnschedule with unexpected reply"),
@@ -920,6 +902,17 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili
                xpc_release(reply);
        }
 
                xpc_release(reply);
        }
 
+       if (retry) {
+               // reconnect
+               targetPrivate->serverScheduled = FALSE;
+               _reach_server_target_reconnect(connection, target, FALSE);
+               ok = TRUE;
+       }
+
+       if (ok) {
+               CFRelease(target);
+       }
+
        xpc_release(reqdict);
        return ok;
 }
        xpc_release(reqdict);
        return ok;
 }
@@ -930,7 +923,7 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili
 
 
 static void
 
 
 static void
-_reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilityRef target)
+_reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilityRef target, Boolean disconnect)
 {
        Boolean                         ok;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 {
        Boolean                         ok;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
@@ -940,8 +933,17 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit
                return;
        }
 
                return;
        }
 
-       // server has been restarted
-       targetPrivate->cycle = 0;
+       if (disconnect) {
+               // if we should first disconnect (unschedule, remove)
+               if (targetPrivate->serverScheduled) {
+                       (void) _reach_server_target_unschedule(connection, target);
+               }
+
+               (void) _reach_server_target_remove(connection, target);
+       } else {
+               // server has been restarted
+               targetPrivate->cycle = 0;
+       }
 
        // re-associate with server
        ok = _reach_server_target_add(connection, target);
 
        // re-associate with server
        ok = _reach_server_target_add(connection, target);
@@ -962,8 +964,11 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit
                return;
        }
 
                return;
        }
 
-       // .. and update our status
-       __SCNetworkReachabilityPerformNoLock(target);
+       // For addresses, update our status now.  For names, queries will
+       // be updated with a callback
+       if (targetPrivate->type != reachabilityTypeName) {
+               __SCNetworkReachabilityPerform(target);
+       }
 
        return;
 }
 
        return;
 }
@@ -972,26 +977,20 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit
 static void
 _reach_connection_reconnect(xpc_connection_t connection)
 {
 static void
 _reach_connection_reconnect(xpc_connection_t connection)
 {
-       dispatch_queue_t        q;
-
-       q = _reach_requests_rbt_queue();
-       dispatch_sync(q, ^{
-               struct rb_node          *rbn;
-               struct rb_tree          *rbt;
+       dispatch_sync(_reach_requests_rbt_queue(), ^{
+               rb_tree_t       *rbt    = _reach_requests_rbt();
+               reach_request_t *request;
 
 
-               rbt = _reach_requests_rbt();
-               rbn = rb_tree_iterate(rbt, NULL, RB_DIR_RIGHT);
-               for ( ; rbn != NULL ; rbn = rb_tree_iterate(rbt, rbn, RB_DIR_LEFT)) {
-                       reach_request_t                 *rbt_request;
+               RB_TREE_FOREACH(request, rbt) {
                        SCNetworkReachabilityRef        target;
 
                        SCNetworkReachabilityRef        target;
 
-                       rbt_request = RBNODE_TO_REACH_REQUEST(rbn);
-
-                       target = rbt_request->target;
+                       xpc_retain(connection);
+                       target = request->target;
                        CFRetain(target);
                        dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{
                        CFRetain(target);
                        dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{
-                               _reach_server_target_reconnect(connection, target);
+                               _reach_server_target_reconnect(connection, target, FALSE);
                                CFRelease(target);
                                CFRelease(target);
+                               xpc_release(connection);
                        });
                }
        });
                        });
                }
        });
@@ -1183,4 +1182,6 @@ __SCNetworkReachabilityServer_targetUnschedule(SCNetworkReachabilityRef target)
        return ok;
 }
 
        return ok;
 }
 
+
+
 #endif // HAVE_REACHABILITY_SERVER
 #endif // HAVE_REACHABILITY_SERVER
index d9dfe2cdd36cec6897980e2bd8b1796819e4d981..8527f32f1a235dc57937637947aeb05995b46a80 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,8 +35,7 @@
 #include <dispatch/private.h>
 #include <xpc/xpc.h>
 #include <xpc/private.h>
 #include <dispatch/private.h>
 #include <xpc/xpc.h>
 #include <xpc/private.h>
-
-#include "rb.h"
+#include <sys/rbtree.h>
 
 
 #pragma mark -
 
 
 #pragma mark -
@@ -264,18 +263,18 @@ _target_reply_add_reachability(SCNetworkReachabilityRef target,
                                  REACH_STATUS_SLEEPING,
                                  targetPrivate->info.sleeping);
        if (targetPrivate->type == reachabilityTypeName) {
                                  REACH_STATUS_SLEEPING,
                                  targetPrivate->info.sleeping);
        if (targetPrivate->type == reachabilityTypeName) {
-               if (isA_CFArray(targetPrivate->resolvedAddress)) {
+               if (isA_CFArray(targetPrivate->resolvedAddresses)) {
                        xpc_object_t    addresses;
                        CFIndex         i;
                        CFIndex         n;
 
                        addresses = xpc_array_create(NULL, 0);
 
                        xpc_object_t    addresses;
                        CFIndex         i;
                        CFIndex         n;
 
                        addresses = xpc_array_create(NULL, 0);
 
-                       n = CFArrayGetCount(targetPrivate->resolvedAddress);
+                       n = CFArrayGetCount(targetPrivate->resolvedAddresses);
                        for (i = 0; i < n; i++) {
                                CFDataRef       address;
 
                        for (i = 0; i < n; i++) {
                                CFDataRef       address;
 
-                               address = CFArrayGetValueAtIndex(targetPrivate->resolvedAddress, i);
+                               address = CFArrayGetValueAtIndex(targetPrivate->resolvedAddresses, i);
                                xpc_array_set_data(addresses,
                                                   XPC_ARRAY_APPEND,
                                                   CFDataGetBytePtr(address),
                                xpc_array_set_data(addresses,
                                                   XPC_ARRAY_APPEND,
                                                   CFDataGetBytePtr(address),
@@ -283,13 +282,13 @@ _target_reply_add_reachability(SCNetworkReachabilityRef target,
                        }
 
                        xpc_dictionary_set_value(reply,
                        }
 
                        xpc_dictionary_set_value(reply,
-                                                REACH_STATUS_RESOLVED_ADDRESS,
+                                                REACH_STATUS_RESOLVED_ADDRESSES,
                                                 addresses);
                        xpc_release(addresses);
                }
                xpc_dictionary_set_int64(reply,
                                                 addresses);
                        xpc_release(addresses);
                }
                xpc_dictionary_set_int64(reply,
-                                        REACH_STATUS_RESOLVED_ADDRESS_ERROR,
-                                        targetPrivate->resolvedAddressError);
+                                        REACH_STATUS_RESOLVED_ERROR,
+                                        targetPrivate->resolvedError);
        }
 
        MUTEX_UNLOCK(&targetPrivate->lock);
        }
 
        MUTEX_UNLOCK(&targetPrivate->lock);
@@ -458,6 +457,7 @@ _target_watcher_remove(SCNetworkReachabilityRef     target,
                              connection,
                              target,
                              target_id);
                              connection,
                              target,
                              target_id);
+                       ok = FALSE;
                        return;
                }
 
                        return;
                }
 
@@ -469,11 +469,11 @@ _target_watcher_remove(SCNetworkReachabilityRef   target,
                              target,
                              target_id);
                        CFRelease(key);
                              target,
                              target_id);
                        CFRelease(key);
+                       ok = FALSE;
                        return;
                }
 
                CFDictionaryRemoveValue(targetPrivate->serverWatchers, key);
                        return;
                }
 
                CFDictionaryRemoveValue(targetPrivate->serverWatchers, key);
-               xpc_release(connection);
                CFRelease(key);
 
                n = CFDictionaryGetCount(targetPrivate->serverWatchers);
                CFRelease(key);
 
                n = CFDictionaryGetCount(targetPrivate->serverWatchers);
@@ -502,8 +502,15 @@ _target_watcher_remove(SCNetworkReachabilityRef    target,
                        }
 
                        // no more watchers, flags are no longer valid
                        }
 
                        // no more watchers, flags are no longer valid
-                       (void) _SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, TRUE, FALSE);
+                       if (_SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, TRUE, FALSE)) {
+                               if (S_debug) {
+                                       SCLog(TRUE, LOG_INFO, CFSTR("%s  flags are no longer \"valid\""),
+                                             targetPrivate->log_prefix);
+                               }
+                       }
                }
                }
+
+               xpc_release(connection);
        });
 
        return ok;
        });
 
        return ok;
@@ -515,7 +522,7 @@ _target_watcher_remove(SCNetworkReachabilityRef     target,
 
 
 typedef struct {
 
 
 typedef struct {
-       struct rb_node          rbn;
+       rb_node_t               rbn;
        xpc_connection_t        connection;
        pid_t                   pid;
        const char              *proc_name;
        xpc_connection_t        connection;
        pid_t                   pid;
        const char              *proc_name;
@@ -523,56 +530,54 @@ typedef struct {
 } reach_client_t;
 
 
 } reach_client_t;
 
 
-#define RBNODE_TO_REACH_CLIENT(node) \
-       ((reach_client_t *)((uintptr_t)node - offsetof(reach_client_t, rbn)))
-
-
 static int
 static int
-_rbt_compare_transaction_nodes(const struct rb_node *n1, const struct rb_node *n2)
+_rbt_compare_transaction_nodes(void *context, const void *n1, const void *n2)
 {
 {
-       uint64_t        a = (uintptr_t)RBNODE_TO_REACH_CLIENT(n1)->connection;
-       uint64_t        b = (uintptr_t)RBNODE_TO_REACH_CLIENT(n2)->connection;
+       uint64_t        a = (uintptr_t)((reach_client_t *)n1)->connection;
+       uint64_t        b = (uintptr_t)((reach_client_t *)n2)->connection;
 
        return (a - b);
 }
 
 
 static int
 
        return (a - b);
 }
 
 
 static int
-_rbt_compare_transaction_key(const struct rb_node *n1, const void *key)
+_rbt_compare_transaction_key(void *context, const void *n1, const void *key)
 {
 {
-       uint64_t        a = (uintptr_t)RBNODE_TO_REACH_CLIENT(n1)->connection;
+       uint64_t        a = (uintptr_t)((reach_client_t *)n1)->connection;
        uint64_t        b = *(uintptr_t *)key;
 
        return (a - b);
 }
 
 
        uint64_t        b = *(uintptr_t *)key;
 
        return (a - b);
 }
 
 
-static struct rb_tree *
+static rb_tree_t *
 _reach_clients_rbt()
 {
        static dispatch_once_t          once;
 _reach_clients_rbt()
 {
        static dispatch_once_t          once;
-       static const struct rb_tree_ops ops = {
+       static const rb_tree_ops_t      ops = {
                .rbto_compare_nodes     = _rbt_compare_transaction_nodes,
                .rbto_compare_key       = _rbt_compare_transaction_key,
                .rbto_compare_nodes     = _rbt_compare_transaction_nodes,
                .rbto_compare_key       = _rbt_compare_transaction_key,
+               .rbto_node_offset       = offsetof(reach_client_t, rbn),
+               .rbto_context           = NULL
        };
        };
-       static struct rb_tree           rbtree;
+       static rb_tree_t                rbt;
 
        dispatch_once(&once, ^{
 
        dispatch_once(&once, ^{
-               rb_tree_init(&rbtree, &ops);
+               rb_tree_init(&rbt, &ops);
        });
 
        });
 
-       return &rbtree;
+       return &rbt;
 }
 
 
 static dispatch_queue_t
 }
 
 
 static dispatch_queue_t
-_reach_connection_queue()
+_reach_clients_rbt_queue()
 {
        static dispatch_once_t  once;
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
 {
        static dispatch_once_t  once;
        static dispatch_queue_t q;
 
        dispatch_once(&once, ^{
-               q = dispatch_queue_create(REACH_SERVICE_NAME ".connection", NULL);
+               q = dispatch_queue_create(REACH_SERVICE_NAME ".clients.rbt", NULL);
        });
 
        return q;
        });
 
        return q;
@@ -623,13 +628,16 @@ _reach_client_remove_target(const void *key, const void *value, void *context)
                n = CFDictionaryGetCount(targetPrivate->serverWatchers);
                if (n > 0) {
                        CFIndex         i;
                n = CFDictionaryGetCount(targetPrivate->serverWatchers);
                if (n > 0) {
                        CFIndex         i;
+                       CFDictionaryRef serverWatchers;
                        const void *    watchers_q[32];
                        const void **   watchers        = watchers_q;
 
                        const void *    watchers_q[32];
                        const void **   watchers        = watchers_q;
 
+                       serverWatchers = CFDictionaryCreateCopy(NULL, targetPrivate->serverWatchers);
+
                        if (n > sizeof(watchers_q)/sizeof(watchers[0])) {
                                watchers = CFAllocatorAllocate(NULL, n * sizeof(CFDataRef), 0);
                        }
                        if (n > sizeof(watchers_q)/sizeof(watchers[0])) {
                                watchers = CFAllocatorAllocate(NULL, n * sizeof(CFDataRef), 0);
                        }
-                       CFDictionaryGetKeysAndValues(targetPrivate->serverWatchers, watchers, NULL);
+                       CFDictionaryGetKeysAndValues(serverWatchers, watchers, NULL);
 
                        for (i = 0; i < n; i++) {
                                CFDataRef               key;
 
                        for (i = 0; i < n; i++) {
                                CFDataRef               key;
@@ -649,6 +657,8 @@ _reach_client_remove_target(const void *key, const void *value, void *context)
                        if (watchers != watchers_q) {
                                CFAllocatorDeallocate(NULL, watchers);
                        }
                        if (watchers != watchers_q) {
                                CFAllocatorDeallocate(NULL, watchers);
                        }
+
+                       CFRelease(serverWatchers);
                }
        }
 
                }
        }
 
@@ -664,27 +674,27 @@ _reach_client_remove_target(const void *key, const void *value, void *context)
 static void
 _reach_client_remove(xpc_connection_t connection)
 {
 static void
 _reach_client_remove(xpc_connection_t connection)
 {
-       struct rb_tree  *rbtree = _reach_clients_rbt();
-       struct rb_node  *rbn;
+       uint64_t        connection_id   = (uintptr_t)connection;
 
 
-       rbn = rb_tree_find_node(rbtree, &connection);
-       if (rbn != NULL) {
+       dispatch_sync(_reach_clients_rbt_queue(), ^{
                reach_client_t  *client;
                reach_client_t  *client;
+               rb_tree_t       *rbt    = _reach_clients_rbt();
 
 
-               client = RBNODE_TO_REACH_CLIENT(rbn);
-
-               // remove any remaining target references (for this client)
-               my_CFDictionaryApplyFunction(client->targets,
-                                            _reach_client_remove_target,
-                                            (void *)connection);
+               client = rb_tree_find_node(rbt, &connection_id);
+               if (client != NULL) {
+                       // remove any remaining target references (for this client)
+                       my_CFDictionaryApplyFunction(client->targets,
+                                                    _reach_client_remove_target,
+                                                    (void *)connection);
 
 
-               rb_tree_remove_node(rbtree, rbn);
-               _reach_client_release(client);
-       } else {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("<%p> _reach_client_remove: unexpected client"),
-                     connection);
-       }
+                       rb_tree_remove_node(rbt, client);
+                       _reach_client_release(client);
+               } else {
+                       SCLog(TRUE, LOG_ERR,
+                             CFSTR("<%p> _reach_client_remove: unexpected client"),
+                             connection);
+               }
+       });
 
        return;
 }
 
        return;
 }
@@ -751,6 +761,21 @@ _client_target_remove(reach_client_t *client, uint64_t target_id)
 #pragma mark -
 #pragma mark Reachability [XPC] server functions
 
 #pragma mark -
 #pragma mark Reachability [XPC] server functions
 
+
+static dispatch_queue_t
+_reach_server_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(REACH_SERVICE_NAME, NULL);
+       });
+
+       return q;
+}
+
+
 /*
  * _reach_changed
  *
 /*
  * _reach_changed
  *
@@ -791,7 +816,8 @@ _reach_changed(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags
         */
        if (_SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, FALSE, TRUE)) {
                if (S_debug) {
         */
        if (_SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, FALSE, TRUE)) {
                if (S_debug) {
-                       SCLog(TRUE, LOG_INFO, CFSTR("  flags are now \"valid\""));
+                       SCLog(TRUE, LOG_INFO, CFSTR("%s  flags are now \"valid\""),
+                             targetPrivate->log_prefix);
                }
        }
 
                }
        }
 
@@ -828,7 +854,7 @@ _reach_changed(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags
 
                connection = xpc_retain(watcher_key->connection);
                target_id  = watcher_key->target_id;
 
                connection = xpc_retain(watcher_key->connection);
                target_id  = watcher_key->target_id;
-               dispatch_async(_reach_connection_queue(), ^{
+               dispatch_async(_reach_server_queue(), ^{
                        xpc_object_t    reply;
 
                        // create our [async] notification
                        xpc_object_t    reply;
 
                        // create our [async] notification
@@ -903,12 +929,10 @@ static void
 target_add(reach_client_t *client, xpc_object_t request)
 {
        const char                              *name;
 target_add(reach_client_t *client, xpc_object_t request)
 {
        const char                              *name;
-       const char                              *serv;
        const struct sockaddr                   *localAddress;
        struct sockaddr_storage                 localAddress0;
        const struct sockaddr                   *remoteAddress;
        struct sockaddr_storage                 remoteAddress0;
        const struct sockaddr                   *localAddress;
        struct sockaddr_storage                 localAddress0;
        const struct sockaddr                   *remoteAddress;
        struct sockaddr_storage                 remoteAddress0;
-       const struct addrinfo                   *hints;
        int64_t                                 if_index;
        const char                              *if_name        = NULL;
        bool                                    onDemandBypass  = FALSE;
        int64_t                                 if_index;
        const char                              *if_name        = NULL;
        bool                                    onDemandBypass  = FALSE;
@@ -962,12 +986,6 @@ target_add(reach_client_t *client, xpc_object_t request)
                CC_SHA1_Update(&ctx, name, strlen(name));
        }
 
                CC_SHA1_Update(&ctx, name, strlen(name));
        }
 
-       serv = xpc_dictionary_get_string(request, REACH_TARGET_SERV);
-       if (serv != NULL) {
-               CC_SHA1_Update(&ctx, REACH_TARGET_SERV, sizeof(REACH_TARGET_SERV));
-               CC_SHA1_Update(&ctx, serv, strlen(serv));
-       }
-
        localAddress = xpc_dictionary_get_data(request, REACH_TARGET_LOCAL_ADDR, &len);
        if (localAddress != NULL) {
                if ((len == localAddress->sa_len) && (len <= sizeof(struct sockaddr_storage))) {
        localAddress = xpc_dictionary_get_data(request, REACH_TARGET_LOCAL_ADDR, &len);
        if (localAddress != NULL) {
                if ((len == localAddress->sa_len) && (len <= sizeof(struct sockaddr_storage))) {
@@ -996,19 +1014,6 @@ target_add(reach_client_t *client, xpc_object_t request)
                }
        }
 
                }
        }
 
-       hints = xpc_dictionary_get_data(request, REACH_TARGET_HINTS, &len);
-       if (hints != NULL) {
-               if (len == sizeof(struct addrinfo)) {
-                       CC_SHA1_Update(&ctx, REACH_TARGET_HINTS, sizeof(REACH_TARGET_HINTS));
-                       CC_SHA1_Update(&ctx, hints, len);
-               } else {
-                       xpc_dictionary_set_string(reply,
-                                                 REACH_REQUEST_REPLY_DETAIL,
-                                                 "hints: size error");
-                       goto done;
-               }
-       }
-
        if_index = xpc_dictionary_get_int64(request, REACH_TARGET_IF_INDEX);
        if (if_index != 0) {
                if_name = xpc_dictionary_get_string(request, REACH_TARGET_IF_NAME);
        if_index = xpc_dictionary_get_int64(request, REACH_TARGET_IF_INDEX);
        if (if_index != 0) {
                if_name = xpc_dictionary_get_string(request, REACH_TARGET_IF_NAME);
@@ -1018,6 +1023,7 @@ target_add(reach_client_t *client, xpc_object_t request)
                }
        }
 
                }
        }
 
+
        onDemandBypass = xpc_dictionary_get_bool(request, REACH_TARGET_ONDEMAND_BYPASS);
        if (onDemandBypass) {
                CC_SHA1_Update(&ctx, REACH_TARGET_ONDEMAND_BYPASS, sizeof(REACH_TARGET_ONDEMAND_BYPASS));
        onDemandBypass = xpc_dictionary_get_bool(request, REACH_TARGET_ONDEMAND_BYPASS);
        if (onDemandBypass) {
                CC_SHA1_Update(&ctx, REACH_TARGET_ONDEMAND_BYPASS, sizeof(REACH_TARGET_ONDEMAND_BYPASS));
@@ -1057,11 +1063,6 @@ target_add(reach_client_t *client, xpc_object_t request)
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, str);
                                CFRelease(str);
                        }
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, str);
                                CFRelease(str);
                        }
-                       if (serv != NULL) {
-                               str = CFStringCreateWithCString(NULL, serv, kCFStringEncodingUTF8);
-                               CFDictionarySetValue(options, kSCNetworkReachabilityOptionServName, str);
-                               CFRelease(str);
-                       }
                        if (localAddress != NULL) {
                                data = CFDataCreate(NULL, (const UInt8 *)&localAddress0, localAddress0.ss_len);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionLocalAddress, data);
                        if (localAddress != NULL) {
                                data = CFDataCreate(NULL, (const UInt8 *)&localAddress0, localAddress0.ss_len);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionLocalAddress, data);
@@ -1072,11 +1073,6 @@ target_add(reach_client_t *client, xpc_object_t request)
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionRemoteAddress, data);
                                CFRelease(data);
                        }
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionRemoteAddress, data);
                                CFRelease(data);
                        }
-                       if (hints != NULL) {
-                               data = CFDataCreate(NULL, (const UInt8 *)hints, sizeof(struct addrinfo));
-                               CFDictionarySetValue(options, kSCNetworkReachabilityOptionHints, data);
-                               CFRelease(data);
-                       }
                        if (onDemandBypass) {
                                CFDictionarySetValue(options,
                                                     kSCNetworkReachabilityOptionConnectionOnDemandBypass,
                        if (onDemandBypass) {
                                CFDictionarySetValue(options,
                                                     kSCNetworkReachabilityOptionConnectionOnDemandBypass,
@@ -1269,10 +1265,15 @@ target_schedule(reach_client_t *client, xpc_object_t request)
 
        // enable monitoring
        ok = _target_watcher_add(target, client->connection, target_id);
 
        // enable monitoring
        ok = _target_watcher_add(target, client->connection, target_id);
-       if (ok) {
-               status = REACH_REQUEST_REPLY_OK;
+       if (!ok) {
+               xpc_dictionary_set_string(reply,
+                                         REACH_REQUEST_REPLY_DETAIL,
+                                         "could not add watcher");
+               goto done;
        }
 
        }
 
+       status = REACH_REQUEST_REPLY_OK;
+
     done :
 
        xpc_dictionary_set_int64(reply, REACH_REQUEST_REPLY, status);
     done :
 
        xpc_dictionary_set_int64(reply, REACH_REQUEST_REPLY, status);
@@ -1353,19 +1354,33 @@ target_status(reach_client_t *client, xpc_object_t request)
                if (scheduled) {
                        /*
                         * The client "scheduled" this target.  As such, we
                if (scheduled) {
                        /*
                         * The client "scheduled" this target.  As such, we
-                        * know that this an async query and that we only
+                        * know that this is an async query and that we only
                         * need to return the "last known" flags.
                         */
                        _target_reply_add_reachability(target, reply);
 //                     log_xpc_object("  reply [scheduled]", reply);
 
                         * need to return the "last known" flags.
                         */
                        _target_reply_add_reachability(target, reply);
 //                     log_xpc_object("  reply [scheduled]", reply);
 
+                       /*
+                        * ... and if it's not a "name" query then we can mark the
+                        * flags as valid.
+                        */
+                       if (targetPrivate->type != reachabilityTypeName) {
+                               if (_SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, FALSE, TRUE)) {
+                                       if (S_debug) {
+                                               SCLog(TRUE, LOG_INFO, CFSTR("%s  flags are now \"valid\"."),
+                                                     targetPrivate->log_prefix);
+                                       }
+                               }
+                       }
+
                        if (S_debug) {
                                CFStringRef     str;
 
                                str = _SCNetworkReachabilityCopyTargetFlags(target);
                                SCLog(TRUE, LOG_INFO,
                        if (S_debug) {
                                CFStringRef     str;
 
                                str = _SCNetworkReachabilityCopyTargetFlags(target);
                                SCLog(TRUE, LOG_INFO,
-                                     CFSTR("<%p>   reply [scheduled], %@"),
+                                     CFSTR("<%p>   reply [scheduled%s], %@"),
                                      client->connection,
                                      client->connection,
+                                     targetPrivate->serverInfoValid ? "/valid" : "",
                                      str);
                                CFRelease(str);
                        }
                                      str);
                                CFRelease(str);
                        }
@@ -1373,7 +1388,7 @@ target_status(reach_client_t *client, xpc_object_t request)
                        /*
                         * The client has NOT "scheduled" this target.  As
                         * such, we know that this is a sync query and that
                        /*
                         * The client has NOT "scheduled" this target.  As
                         * such, we know that this is a sync query and that
-                        * must return "current" flags.
+                        * we must return "current" flags.
                         */
                        if (targetPrivate->scheduled && targetPrivate->serverInfoValid) {
                                /*
                         */
                        if (targetPrivate->scheduled && targetPrivate->serverInfoValid) {
                                /*
@@ -1397,7 +1412,7 @@ target_status(reach_client_t *client, xpc_object_t request)
                                dispatch_group_t        group;
 
                                /*
                                dispatch_group_t        group;
 
                                /*
-                                * The server target has NOT been "scheduled" (or
+                                * The server target has NOT been "scheduled" or
                                 * we do not have "current" flags.  This means that
                                 * we must query for the current information and
                                 * return the flags to the client when they are
                                 * we do not have "current" flags.  This means that
                                 * we must query for the current information and
                                 * return the flags to the client when they are
@@ -1407,7 +1422,7 @@ target_status(reach_client_t *client, xpc_object_t request)
                                reply_now = FALSE;
 
                                group = _target_group(target);
                                reply_now = FALSE;
 
                                group = _target_group(target);
-                               if (_SC_ATOMIC_INC(&targetPrivate->serverQueryActive) == 0) {
+                               if (_SC_ATOMIC_INC(&targetPrivate->serverSyncQueryActive) == 0) {
                                        CFRetain(target);
                                        dispatch_group_async(group, _server_concurrent_queue(), ^{
                                                SCNetworkReachabilityFlags      flags;
                                        CFRetain(target);
                                        dispatch_group_async(group, _server_concurrent_queue(), ^{
                                                SCNetworkReachabilityFlags      flags;
@@ -1426,8 +1441,24 @@ target_status(reach_client_t *client, xpc_object_t request)
                                                              SCErrorString(SCError()));
                                                }
 
                                                              SCErrorString(SCError()));
                                                }
 
-                                               // flags are now available
-                                               n = _SC_ATOMIC_ZERO(&targetPrivate->serverQueryActive);
+                                               /*
+                                                * if we have current flags, if the target has since been
+                                                * scheduled, and this is not a "name" query, then mark as
+                                                * valid.
+                                                */
+                                               if (ok &&
+                                                   targetPrivate->scheduled &&
+                                                   targetPrivate->type != reachabilityTypeName) {
+                                                       if (_SC_ATOMIC_CMPXCHG(&targetPrivate->serverInfoValid, FALSE, TRUE)) {
+                                                               if (S_debug) {
+                                                                       SCLog(TRUE, LOG_INFO, CFSTR("%s  flags are now \"valid\"!"),
+                                                                             targetPrivate->log_prefix);
+                                                               }
+                                                       }
+                                               }
+
+                                               // sync query complete
+                                               n = _SC_ATOMIC_ZERO(&targetPrivate->serverSyncQueryActive);
                                                if (S_debug) {
                                                        SCLog(TRUE, LOG_INFO,
                                                              CFSTR("%sSCNetworkReachabilityGetFlags() [sync query] complete, n = %d"),
                                                if (S_debug) {
                                                        SCLog(TRUE, LOG_INFO,
                                                              CFSTR("%sSCNetworkReachabilityGetFlags() [sync query] complete, n = %d"),
@@ -1504,7 +1535,6 @@ target_status(reach_client_t *client, xpc_object_t request)
 static void
 target_unschedule(reach_client_t *client, xpc_object_t request)
 {
 static void
 target_unschedule(reach_client_t *client, xpc_object_t request)
 {
-       Boolean                         ok;
        xpc_connection_t                remote;
        xpc_object_t                    reply;
        uint64_t                        status          = REACH_REQUEST_REPLY_FAILED;
        xpc_connection_t                remote;
        xpc_object_t                    reply;
        uint64_t                        status          = REACH_REQUEST_REPLY_FAILED;
@@ -1545,10 +1575,9 @@ target_unschedule(reach_client_t *client, xpc_object_t request)
        }
 
        // disable monitoring
        }
 
        // disable monitoring
-       ok = _target_watcher_remove(target, client->connection, target_id);
-       if (ok) {
-               status = REACH_REQUEST_REPLY_OK;
-       }
+       _target_watcher_remove(target, client->connection, target_id);
+
+       status = REACH_REQUEST_REPLY_OK;
 
     done :
 
 
     done :
 
@@ -1568,33 +1597,35 @@ target_unschedule(reach_client_t *client, xpc_object_t request)
 static void
 _snapshot_digest_watcher(const void *key, const void *value, void *context)
 {
 static void
 _snapshot_digest_watcher(const void *key, const void *value, void *context)
 {
-       FILE                            *f              = (FILE *)context;
-       static reach_client_t           no_client       = {
+       __block reach_client_t  *client         = NULL;
+       FILE                    *f              = (FILE *)context;
+       static reach_client_t   no_client       = {
                .pid = 0,
                .proc_name = "?",
        };
                .pid = 0,
                .proc_name = "?",
        };
-       struct rb_node                  *rbn;
-       reach_client_t                  *rbt_client;
-       reach_watcher_key_t             *watcher_key;
-       reach_watcher_val_t             *watcher_val;
+       reach_watcher_key_t     *watcher_key;
+       reach_watcher_val_t     *watcher_val;
 
        /* ALIGN: CF aligns to >8 byte boundries */
        watcher_key = (reach_watcher_key_t *)(void *)CFDataGetBytePtr(key);
        watcher_val = (reach_watcher_val_t *)(void *)CFDataGetBytePtr(value);
 
 
        /* ALIGN: CF aligns to >8 byte boundries */
        watcher_key = (reach_watcher_key_t *)(void *)CFDataGetBytePtr(key);
        watcher_val = (reach_watcher_val_t *)(void *)CFDataGetBytePtr(value);
 
-       rbn = rb_tree_find_node(_reach_clients_rbt(), &watcher_key->connection);
-       if (rbn == NULL) {
-               rbn = &no_client.rbn;
-       }
+       dispatch_sync(_reach_clients_rbt_queue(), ^{
+               uint64_t        connection_id   = (uintptr_t)watcher_key->connection;
+               rb_tree_t       *rbt            = _reach_clients_rbt();
 
 
-       rbt_client = RBNODE_TO_REACH_CLIENT(rbn);
+               client = rb_tree_find_node(rbt, &connection_id);
+               if (client == NULL) {
+                       client = &no_client;
+               }
+       });
 
        SCPrint(TRUE, f,
                CFSTR("      connection = %p, target(c) = 0x%0llx, command = %s, pid = %d, changes = %u\n"),
                watcher_key->connection,
                watcher_key->target_id,
 
        SCPrint(TRUE, f,
                CFSTR("      connection = %p, target(c) = 0x%0llx, command = %s, pid = %d, changes = %u\n"),
                watcher_key->connection,
                watcher_key->target_id,
-               rbt_client->proc_name,
-               rbt_client->pid,
+               client->proc_name,
+               client->pid,
                watcher_val->n_changes);
 
        return;
                watcher_val->n_changes);
 
        return;
@@ -1612,11 +1643,18 @@ _snapshot_digest(const void *key, const void *value, void *context)
 
        q = _target_queue(target);
        dispatch_sync(q, ^{
 
        q = _target_queue(target);
        dispatch_sync(q, ^{
+               CFIndex         nWatchers       = 0;
+
+               if (targetPrivate->serverWatchers != NULL) {
+                       nWatchers = CFDictionaryGetCount(targetPrivate->serverWatchers);
+               }
+
                SCPrint(TRUE, f, CFSTR("\n  digest : %@\n"), digest);
                SCPrint(TRUE, f, CFSTR("    %@\n"), target);
                SCPrint(TRUE, f, CFSTR("\n  digest : %@\n"), digest);
                SCPrint(TRUE, f, CFSTR("    %@\n"), target);
-               SCPrint(TRUE, f, CFSTR("    valid = %s, active = %u, refs = %u\n"),
+               SCPrint(TRUE, f, CFSTR("    valid = %s, async watchers = %u, sync queries = %u, refs = %u\n"),
                        targetPrivate->serverInfoValid ? "Y" : "N",
                        targetPrivate->serverInfoValid ? "Y" : "N",
-                       targetPrivate->serverQueryActive,
+                       nWatchers,
+                       targetPrivate->serverSyncQueryActive,
                        targetPrivate->serverReferences);
 
                SCPrint(TRUE, f, CFSTR("    network %d.%3.3d"),
                        targetPrivate->serverReferences);
 
                SCPrint(TRUE, f, CFSTR("    network %d.%3.3d"),
@@ -1651,7 +1689,7 @@ _snapshot_digest(const void *key, const void *value, void *context)
                }
                SCPrint(TRUE, f, CFSTR("\n"));
 
                }
                SCPrint(TRUE, f, CFSTR("\n"));
 
-               if (targetPrivate->serverWatchers != NULL) {
+               if (nWatchers > 0) {
                        CFDictionaryApplyFunction(targetPrivate->serverWatchers,
                                                  _snapshot_digest_watcher,
                                                  f);
                        CFDictionaryApplyFunction(targetPrivate->serverWatchers,
                                                  _snapshot_digest_watcher,
                                                  f);
@@ -1689,8 +1727,6 @@ _snapshot(reach_client_t *client, xpc_object_t request)
        FILE                    *f;
        int                     fd;
        Boolean                 ok      = FALSE;
        FILE                    *f;
        int                     fd;
        Boolean                 ok      = FALSE;
-       struct rb_node          *rbn;
-       struct rb_tree          *rbt;
        xpc_connection_t        remote;
        xpc_object_t            reply;
 
        xpc_connection_t        remote;
        xpc_object_t            reply;
 
@@ -1738,30 +1774,31 @@ _snapshot(reach_client_t *client, xpc_object_t request)
 
        // provide connection/client info
 
 
        // provide connection/client info
 
-       SCPrint(TRUE, f, CFSTR("Clients :\n"));
-       rbt = _reach_clients_rbt();
-       rbn = rb_tree_iterate(rbt, NULL, RB_DIR_RIGHT);
-       if (rbn != NULL) {
-               while (rbn != NULL) {
-                       reach_client_t  *rbt_client;
-
-                       rbt_client = RBNODE_TO_REACH_CLIENT(rbn);
-                       SCPrint(TRUE, f,
-                               CFSTR("\n  connection = %p, client = %p, command = %s, pid = %d\n"),
-                               rbt_client->connection,
-                               rbt_client,
-                               rbt_client->proc_name != NULL ? rbt_client->proc_name : "?",
-                               rbt_client->pid);
-                       my_CFDictionaryApplyFunction(rbt_client->targets,
-                                                    _snapshot_target,
-                                                    f);
-
-                       rbn = rb_tree_iterate(rbt, rbn, RB_DIR_LEFT);
+       dispatch_sync(_reach_clients_rbt_queue(), ^{
+               rb_tree_t       *rbt    = _reach_clients_rbt();
+
+               SCPrint(TRUE, f, CFSTR("Clients :\n"));
+
+               if (rb_tree_count(rbt) > 0) {
+                       reach_client_t  *client;
+
+                       RB_TREE_FOREACH(client, rbt) {
+                               SCPrint(TRUE, f,
+                                       CFSTR("\n  connection = %p, client = %p, command = %s, pid = %d\n"),
+                                       client->connection,
+                                       client,
+                                       client->proc_name != NULL ? client->proc_name : "?",
+                                       client->pid);
+                               my_CFDictionaryApplyFunction(client->targets,
+                                                            _snapshot_target,
+                                                            f);
+                       }
+               } else {
+                       SCPrint(TRUE, f, CFSTR("  None.\n"));
                }
                }
-       } else {
-               SCPrint(TRUE, f, CFSTR("  None.\n"));
-       }
-       SCPrint(TRUE, f, CFSTR("\n"));
+
+               SCPrint(TRUE, f, CFSTR("\n"));
+       });
 
        // provide "digest" info
 
 
        // provide "digest" info
 
@@ -1850,53 +1887,58 @@ process_request(reach_client_t *client, xpc_object_t request)
 static void
 process_new_connection(xpc_connection_t connection)
 {
 static void
 process_new_connection(xpc_connection_t connection)
 {
+       reach_client_t  *client;
+
        if (S_debug) {
                SCLog(TRUE, LOG_INFO, CFSTR("<%p> new reach client, pid=%d"),
                      connection,
                      xpc_connection_get_pid(connection));
        }
 
        if (S_debug) {
                SCLog(TRUE, LOG_INFO, CFSTR("<%p> new reach client, pid=%d"),
                      connection,
                      xpc_connection_get_pid(connection));
        }
 
-       dispatch_sync(_reach_connection_queue(), ^{
-               reach_client_t  *client;
+       client = _reach_client_create(connection);
+       assert(client != NULL);
 
 
-               client = _reach_client_create(connection);
-               if (client == NULL || !rb_tree_insert_node(_reach_clients_rbt(), &client->rbn)) {
-                       __builtin_trap();
-               }
+       dispatch_sync(_reach_clients_rbt_queue(), ^{
+               rb_tree_t       *rbt    = _reach_clients_rbt();
+
+               rb_tree_insert_node(rbt, client);
        });
 
        });
 
+       xpc_connection_set_target_queue(connection, _reach_server_queue());
+
        xpc_connection_set_event_handler(connection, ^(xpc_object_t xobj) {
                xpc_type_t      type;
 
                type = xpc_get_type(xobj);
                if (type == XPC_TYPE_DICTIONARY) {
        xpc_connection_set_event_handler(connection, ^(xpc_object_t xobj) {
                xpc_type_t      type;
 
                type = xpc_get_type(xobj);
                if (type == XPC_TYPE_DICTIONARY) {
-                       dispatch_sync(_reach_connection_queue(), ^{
-                               struct rb_node  *rbn;
+                       __block reach_client_t  *client = NULL;
 
 
-                               rbn = rb_tree_find_node(_reach_clients_rbt(), &connection);
-                               if (rbn != NULL) {
-                                       reach_client_t  *client;
+                       dispatch_sync(_reach_clients_rbt_queue(), ^{
+                               uint64_t        connection_id   = (uintptr_t)connection;
+                               rb_tree_t       *rbt            = _reach_clients_rbt();
 
 
-                                       // process the request
-                                       client = RBNODE_TO_REACH_CLIENT(rbn);
-                                       process_request(client, xobj);
-                               } else {
-                                       char            *desc;
+                               client = rb_tree_find_node(rbt, &connection_id);
+                       });
 
 
-                                       SCLog(TRUE, LOG_ERR,
-                                             CFSTR("<%p:%d> unexpected SCNetworkReachability request"),
-                                             connection,
-                                             xpc_connection_get_pid(connection));
+                       if (client != NULL) {
+                               // process the request
+                               process_request(client, xobj);
+                       } else {
+                               char            *desc;
 
 
-                                       desc = xpc_copy_description(xobj);
-                                       SCLog(TRUE, LOG_ERR,
-                                             CFSTR("  request = %s"),
-                                             desc);
-                                       free(desc);
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("<%p:%d> unexpected SCNetworkReachability request"),
+                                     connection,
+                                     xpc_connection_get_pid(connection));
 
 
-                                       xpc_connection_cancel(connection);
-                               }
-                       });
+                               desc = xpc_copy_description(xobj);
+                               SCLog(TRUE, LOG_ERR,
+                                     CFSTR("  request = %s"),
+                                     desc);
+                               free(desc);
+
+                               xpc_connection_cancel(connection);
+                       }
 
                } else if (type == XPC_TYPE_ERROR) {
                        const char      *desc;
 
                } else if (type == XPC_TYPE_ERROR) {
                        const char      *desc;
@@ -1911,11 +1953,7 @@ process_new_connection(xpc_connection_t connection)
                                              desc);
                                }
 
                                              desc);
                                }
 
-                               xpc_retain(connection);
-                               dispatch_async(_reach_connection_queue(), ^{
-                                       _reach_client_remove(connection);
-                                       xpc_release(connection);
-                               });
+                               _reach_client_remove(connection);
 
                        } else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
                                SCLog(TRUE, LOG_ERR,
 
                        } else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
                                SCLog(TRUE, LOG_ERR,
@@ -1958,7 +1996,6 @@ load_SCNetworkReachability(CFBundleRef bundle, Boolean bundleVerbose)
 {
        xpc_connection_t        connection;
        const char              *name;
 {
        xpc_connection_t        connection;
        const char              *name;
-       dispatch_queue_t        reach_server_q;
 
        S_debug = bundleVerbose;
 
 
        S_debug = bundleVerbose;
 
@@ -1971,19 +2008,13 @@ load_SCNetworkReachability(CFBundleRef bundle, Boolean bundleVerbose)
                                                     &kCFTypeDictionaryKeyCallBacks,
                                                     &kCFTypeDictionaryValueCallBacks);
 
                                                     &kCFTypeDictionaryKeyCallBacks,
                                                     &kCFTypeDictionaryValueCallBacks);
 
-       /*
-        * create dispatch queue for processing SCNetworkReachability
-        * service requests
-        */
-       reach_server_q = dispatch_queue_create(REACH_SERVICE_NAME, NULL);
-
        // create XPC listener
        name = getenv("REACH_SERVER");
        if (name == NULL) {
                name = REACH_SERVICE_NAME;
        }
        connection = xpc_connection_create_mach_service(name,
        // create XPC listener
        name = getenv("REACH_SERVER");
        if (name == NULL) {
                name = REACH_SERVICE_NAME;
        }
        connection = xpc_connection_create_mach_service(name,
-                                                       reach_server_q,
+                                                       _reach_server_queue(),
                                                        XPC_CONNECTION_MACH_SERVICE_LISTENER);
 
        xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
                                                        XPC_CONNECTION_MACH_SERVICE_LISTENER);
 
        xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
diff --git a/SystemConfiguration.fproj/reachability/rb.c b/SystemConfiguration.fproj/reachability/rb.c
deleted file mode 100644 (file)
index 21205db..0000000
+++ /dev/null
@@ -1,1323 +0,0 @@
-/* $NetBSD: rb.c,v 1.4 2009/05/19 22:48:19 yamt Exp $ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas <matt@3am-software.com>.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if !defined(_KERNEL) && !defined(_STANDALONE)
-#include <sys/types.h>
-#include <stddef.h>
-#include <assert.h>
-#include <stdbool.h>
-#ifdef RBDEBUG
-#define        KASSERT(s)      assert(s)
-#else
-#define KASSERT(s)     do { } while (/*CONSTCOND*/ 0)
-#endif
-#else
-#include <lib/libkern/libkern.h>
-#endif
-
-#ifdef _LIBC
-__weak_alias(rb_tree_init, _rb_tree_init)
-__weak_alias(rb_tree_find_node, _rb_tree_find_node)
-__weak_alias(rb_tree_find_node_geq, _rb_tree_find_node_geq)
-__weak_alias(rb_tree_find_node_leq, _rb_tree_find_node_leq)
-__weak_alias(rb_tree_insert_node, _rb_tree_insert_node)
-__weak_alias(rb_tree_remove_node, _rb_tree_remove_node)
-__weak_alias(rb_tree_iterate, _rb_tree_iterate)
-#ifdef RBDEBUG
-__weak_alias(rb_tree_check, _rb_tree_check)
-__weak_alias(rb_tree_depths, _rb_tree_depths)
-#endif
-
-#define        rb_tree_init            _rb_tree_init
-#define        rb_tree_find_node       _rb_tree_find_node
-#define        rb_tree_find_node_geq   _rb_tree_find_node_geq
-#define        rb_tree_find_node_leq   _rb_tree_find_node_leq
-#define        rb_tree_insert_node     _rb_tree_insert_node
-#define        rb_tree_remove_node     _rb_tree_remove_node
-#define        rb_tree_iterate         _rb_tree_iterate
-#ifdef RBDEBUG
-#define        rb_tree_check           _rb_tree_check
-#define        rb_tree_depths          _rb_tree_depths
-#endif
-#endif
-
-#if defined(RBTEST) || defined(__APPLE__)
-#include "rb.h"
-#else
-#include <sys/rb.h>
-#endif
-
-#ifdef __APPLE__
-#define __predict_true(exp)     __builtin_expect((exp), 1)
-#define __predict_false(exp)    __builtin_expect((exp), 0)
-#endif
-
-static void rb_tree_insert_rebalance(struct rb_tree *, struct rb_node *);
-static void rb_tree_removal_rebalance(struct rb_tree *, struct rb_node *,
-       unsigned int);
-#ifdef RBDEBUG
-static const struct rb_node *rb_tree_iterate_const(const struct rb_tree *,
-       const struct rb_node *, const unsigned int);
-static bool rb_tree_check_node(const struct rb_tree *, const struct rb_node *,
-       const struct rb_node *, bool);
-#else
-#define        rb_tree_check_node(a, b, c, d)  true
-#endif
-
-#define        RB_SENTINEL_NODE        NULL
-
-void
-rb_tree_init(struct rb_tree *rbt, const struct rb_tree_ops *ops)
-{
-       rbt->rbt_ops = ops;
-       *((const struct rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
-       RB_TAILQ_INIT(&rbt->rbt_nodes);
-#ifndef RBSMALL
-       rbt->rbt_minmax[RB_DIR_LEFT] = rbt->rbt_root;   /* minimum node */
-       rbt->rbt_minmax[RB_DIR_RIGHT] = rbt->rbt_root;  /* maximum node */
-#endif
-       rbt->rbt_count = 0;
-#ifdef RBSTATS
-       rbt->rbt_insertions = 0;
-       rbt->rbt_removals = 0;
-       rbt->rbt_insertion_rebalance_calls = 0;
-       rbt->rbt_insertion_rebalance_passes = 0;
-       rbt->rbt_removal_rebalance_calls = 0;
-       rbt->rbt_removal_rebalance_passes = 0;
-#endif
-}
-
-struct rb_node *
-rb_tree_find_node(struct rb_tree *rbt, const void *key)
-{
-       rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
-       struct rb_node *parent = rbt->rbt_root;
-
-       while (!RB_SENTINEL_P(parent)) {
-               const signed int diff = (*compare_key)(parent, key);
-               if (diff == 0)
-                       return parent;
-               parent = parent->rb_nodes[diff > 0];
-       }
-
-       return NULL;
-}
-
-struct rb_node *
-rb_tree_find_node_geq(struct rb_tree *rbt, const void *key)
-{
-       rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
-       struct rb_node *parent = rbt->rbt_root;
-       struct rb_node *last = NULL;
-
-       while (!RB_SENTINEL_P(parent)) {
-               const signed int diff = (*compare_key)(parent, key);
-               if (diff == 0)
-                       return parent;
-               if (diff < 0)
-                       last = parent;
-               parent = parent->rb_nodes[diff > 0];
-       }
-
-       return last;
-}
-
-struct rb_node *
-rb_tree_find_node_leq(struct rb_tree *rbt, const void *key)
-{
-       rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
-       struct rb_node *parent = rbt->rbt_root;
-       struct rb_node *last = NULL;
-
-       while (!RB_SENTINEL_P(parent)) {
-               const signed int diff = (*compare_key)(parent, key);
-               if (diff == 0)
-                       return parent;
-               if (diff > 0)
-                       last = parent;
-               parent = parent->rb_nodes[diff > 0];
-       }
-
-       return last;
-}
-\f
-bool
-rb_tree_insert_node(struct rb_tree *rbt, struct rb_node *self)
-{
-       rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
-       struct rb_node *parent, *tmp;
-       unsigned int position;
-       bool rebalance;
-
-       RBSTAT_INC(rbt->rbt_insertions);
-
-       tmp = rbt->rbt_root;
-       /*
-        * This is a hack.  Because rbt->rbt_root is just a struct rb_node *,
-        * just like rb_node->rb_nodes[RB_DIR_LEFT], we can use this fact to
-        * avoid a lot of tests for root and know that even at root,
-        * updating RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
-        * update rbt->rbt_root.
-        */
-       parent = (struct rb_node *)(void *)&rbt->rbt_root;
-       position = RB_DIR_LEFT;
-
-       /*
-        * Find out where to place this new leaf.
-        */
-       while (!RB_SENTINEL_P(tmp)) {
-               const signed int diff = (*compare_nodes)(tmp, self);
-               if (__predict_false(diff == 0)) {
-                       /*
-                        * Node already exists; don't insert.
-                        */
-                       return false;
-               }
-               parent = tmp;
-               position = (diff > 0);
-               tmp = parent->rb_nodes[position];
-       }
-
-#ifdef RBDEBUG
-       {
-               struct rb_node *prev = NULL, *next = NULL;
-
-               if (position == RB_DIR_RIGHT)
-                       prev = parent;
-               else if (tmp != rbt->rbt_root)
-                       next = parent;
-
-               /*
-                * Verify our sequential position
-                */
-               KASSERT(prev == NULL || !RB_SENTINEL_P(prev));
-               KASSERT(next == NULL || !RB_SENTINEL_P(next));
-               if (prev != NULL && next == NULL)
-                       next = TAILQ_NEXT(prev, rb_link);
-               if (prev == NULL && next != NULL)
-                       prev = TAILQ_PREV(next, rb_node_qh, rb_link);
-               KASSERT(prev == NULL || !RB_SENTINEL_P(prev));
-               KASSERT(next == NULL || !RB_SENTINEL_P(next));
-               KASSERT(prev == NULL || (*compare_nodes)(prev, self) > 0);
-               KASSERT(next == NULL || (*compare_nodes)(self, next) > 0);
-       }
-#endif
-
-       /*
-        * Initialize the node and insert as a leaf into the tree.
-        */
-       RB_SET_FATHER(self, parent);
-       RB_SET_POSITION(self, position);
-       if (__predict_false(parent == (struct rb_node *)(void *)&rbt->rbt_root)) {
-               RB_MARK_BLACK(self);            /* root is always black */
-#ifndef RBSMALL
-               rbt->rbt_minmax[RB_DIR_LEFT] = self;
-               rbt->rbt_minmax[RB_DIR_RIGHT] = self;
-#endif
-               rebalance = false;
-       } else {
-               KASSERT(position == RB_DIR_LEFT || position == RB_DIR_RIGHT);
-#ifndef RBSMALL
-               /*
-                * Keep track of the minimum and maximum nodes.  If our
-                * parent is a minmax node and we on their min/max side,
-                * we must be the new min/max node.
-                */
-               if (parent == rbt->rbt_minmax[position])
-                       rbt->rbt_minmax[position] = self;
-#endif /* !RBSMALL */
-               /*
-                * All new nodes are colored red.  We only need to rebalance
-                * if our parent is also red.
-                */
-               RB_MARK_RED(self);
-               rebalance = RB_RED_P(parent);
-       }
-       KASSERT(RB_SENTINEL_P(parent->rb_nodes[position]));
-       self->rb_left = parent->rb_nodes[position];
-       self->rb_right = parent->rb_nodes[position];
-       parent->rb_nodes[position] = self;
-       KASSERT(RB_CHILDLESS_P(self));
-
-       /*
-        * Insert the new node into a sorted list for easy sequential access
-        */
-       rbt->rbt_count++;
-#ifdef RBDEBUG
-       if (RB_ROOT_P(rbt, self)) {
-               RB_TAILQ_INSERT_HEAD(&rbt->rbt_nodes, self, rb_link);
-       } else if (position == RB_DIR_LEFT) {
-               KASSERT((*compare_nodes)(self, RB_FATHER(self)) > 0);
-               RB_TAILQ_INSERT_BEFORE(RB_FATHER(self), self, rb_link);
-       } else {
-               KASSERT((*compare_nodes)(RB_FATHER(self), self) > 0);
-               RB_TAILQ_INSERT_AFTER(&rbt->rbt_nodes, RB_FATHER(self),
-                   self, rb_link);
-       }
-#endif
-       KASSERT(rb_tree_check_node(rbt, self, NULL, !rebalance));
-
-       /*
-        * Rebalance tree after insertion
-        */
-       if (rebalance) {
-               rb_tree_insert_rebalance(rbt, self);
-               KASSERT(rb_tree_check_node(rbt, self, NULL, true));
-       }
-
-       return true;
-}
-\f
-/*
- * Swap the location and colors of 'self' and its child @ which.  The child
- * can not be a sentinel node.  This is our rotation function.  However,
- * since it preserves coloring, it great simplifies both insertion and
- * removal since rotation almost always involves the exchanging of colors
- * as a separate step.
- */
-/*ARGSUSED*/
-static void
-rb_tree_reparent_nodes(struct rb_tree *rbt, struct rb_node *old_father,
-       const unsigned int which)
-{
-       const unsigned int other = which ^ RB_DIR_OTHER;
-       struct rb_node * const grandpa = RB_FATHER(old_father);
-       struct rb_node * const old_child = old_father->rb_nodes[which];
-       struct rb_node * const new_father = old_child;
-       struct rb_node * const new_child = old_father;
-
-       KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
-
-       KASSERT(!RB_SENTINEL_P(old_child));
-       KASSERT(RB_FATHER(old_child) == old_father);
-
-       KASSERT(rb_tree_check_node(rbt, old_father, NULL, false));
-       KASSERT(rb_tree_check_node(rbt, old_child, NULL, false));
-       KASSERT(RB_ROOT_P(rbt, old_father) || rb_tree_check_node(rbt, grandpa, NULL, false));
-
-       /*
-        * Exchange descendant linkages.
-        */
-       grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
-       new_child->rb_nodes[which] = old_child->rb_nodes[other];
-       new_father->rb_nodes[other] = new_child;
-
-       /*
-        * Update ancestor linkages
-        */
-       RB_SET_FATHER(new_father, grandpa);
-       RB_SET_FATHER(new_child, new_father);
-
-       /*
-        * Exchange properties between new_father and new_child.  The only
-        * change is that new_child's position is now on the other side.
-        */
-#if 0
-       {
-               struct rb_node tmp;
-               tmp.rb_info = 0;
-               RB_COPY_PROPERTIES(&tmp, old_child);
-               RB_COPY_PROPERTIES(new_father, old_father);
-               RB_COPY_PROPERTIES(new_child, &tmp);
-       }
-#else
-       RB_SWAP_PROPERTIES(new_father, new_child);
-#endif
-       RB_SET_POSITION(new_child, other);
-
-       /*
-        * Make sure to reparent the new child to ourself.
-        */
-       if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
-               RB_SET_FATHER(new_child->rb_nodes[which], new_child);
-               RB_SET_POSITION(new_child->rb_nodes[which], which);
-       }
-
-       KASSERT(rb_tree_check_node(rbt, new_father, NULL, false));
-       KASSERT(rb_tree_check_node(rbt, new_child, NULL, false));
-       KASSERT(RB_ROOT_P(rbt, new_father) || rb_tree_check_node(rbt, grandpa, NULL, false));
-}
-\f
-static void
-rb_tree_insert_rebalance(struct rb_tree *rbt, struct rb_node *self)
-{
-       struct rb_node * father = RB_FATHER(self);
-       struct rb_node * grandpa;
-       struct rb_node * uncle;
-       unsigned int which;
-       unsigned int other;
-
-       KASSERT(!RB_ROOT_P(rbt, self));
-       KASSERT(RB_RED_P(self));
-       KASSERT(RB_RED_P(father));
-       RBSTAT_INC(rbt->rbt_insertion_rebalance_calls);
-
-       for (;;) {
-               KASSERT(!RB_SENTINEL_P(self));
-
-               KASSERT(RB_RED_P(self));
-               KASSERT(RB_RED_P(father));
-               /*
-                * We are red and our parent is red, therefore we must have a
-                * grandfather and he must be black.
-                */
-               grandpa = RB_FATHER(father);
-               KASSERT(RB_BLACK_P(grandpa));
-               KASSERT(RB_DIR_RIGHT == 1 && RB_DIR_LEFT == 0);
-               which = (father == grandpa->rb_right);
-               other = which ^ RB_DIR_OTHER;
-               uncle = grandpa->rb_nodes[other];
-
-               if (RB_BLACK_P(uncle))
-                       break;
-
-               RBSTAT_INC(rbt->rbt_insertion_rebalance_passes);
-               /*
-                * Case 1: our uncle is red
-                *   Simply invert the colors of our parent and
-                *   uncle and make our grandparent red.  And
-                *   then solve the problem up at his level.
-                */
-               RB_MARK_BLACK(uncle);
-               RB_MARK_BLACK(father);
-               if (__predict_false(RB_ROOT_P(rbt, grandpa))) {
-                       /*
-                        * If our grandpa is root, don't bother
-                        * setting him to red, just return.
-                        */
-                       KASSERT(RB_BLACK_P(grandpa));
-                       return;
-               }
-               RB_MARK_RED(grandpa);
-               self = grandpa;
-               father = RB_FATHER(self);
-               KASSERT(RB_RED_P(self));
-               if (RB_BLACK_P(father)) {
-                       /*
-                        * If our greatgrandpa is black, we're done.
-                        */
-                       KASSERT(RB_BLACK_P(rbt->rbt_root));
-                       return;
-               }
-       }
-
-       KASSERT(!RB_ROOT_P(rbt, self));
-       KASSERT(RB_RED_P(self));
-       KASSERT(RB_RED_P(father));
-       KASSERT(RB_BLACK_P(uncle));
-       KASSERT(RB_BLACK_P(grandpa));
-       /*
-        * Case 2&3: our uncle is black.
-        */
-       if (self == father->rb_nodes[other]) {
-               /*
-                * Case 2: we are on the same side as our uncle
-                *   Swap ourselves with our parent so this case
-                *   becomes case 3.  Basically our parent becomes our
-                *   child.
-                */
-               rb_tree_reparent_nodes(rbt, father, other);
-               KASSERT(RB_FATHER(father) == self);
-               KASSERT(self->rb_nodes[which] == father);
-               KASSERT(RB_FATHER(self) == grandpa);
-#ifdef RBDEBUG
-               // only read when RBDEBUG is enabled with KASSERT
-               self = father;
-               father = RB_FATHER(self);
-#endif
-       }
-       KASSERT(RB_RED_P(self) && RB_RED_P(father));
-       KASSERT(grandpa->rb_nodes[which] == father);
-       /*
-        * Case 3: we are opposite a child of a black uncle.
-        *   Swap our parent and grandparent.  Since our grandfather
-        *   is black, our father will become black and our new sibling
-        *   (former grandparent) will become red.
-        */
-       rb_tree_reparent_nodes(rbt, grandpa, which);
-       KASSERT(RB_FATHER(self) == father);
-       KASSERT(RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER] == grandpa);
-       KASSERT(RB_RED_P(self));
-       KASSERT(RB_BLACK_P(father));
-       KASSERT(RB_RED_P(grandpa));
-
-       /*
-        * Final step: Set the root to black.
-        */
-       RB_MARK_BLACK(rbt->rbt_root);
-}
-\f
-static void
-rb_tree_prune_node(struct rb_tree *rbt, struct rb_node *self, bool rebalance)
-{
-       const unsigned int which = RB_POSITION(self);
-       struct rb_node *father = RB_FATHER(self);
-       const bool was_root = RB_ROOT_P(rbt, self);
-
-       KASSERT(rebalance || (RB_ROOT_P(rbt, self) || RB_RED_P(self)));
-       KASSERT(!rebalance || RB_BLACK_P(self));
-       KASSERT(RB_CHILDLESS_P(self));
-       KASSERT(rb_tree_check_node(rbt, self, NULL, false));
-
-       /*
-        * Since we are childless, we know that self->rb_left is pointing
-        * to the sentinel node.
-        */
-       father->rb_nodes[which] = self->rb_left;
-
-       /*
-        * Remove ourselves from the node list, decrement the count,
-        * and update min/max.
-        */
-       RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
-       rbt->rbt_count--;
-#ifndef RBSMALL
-       if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self)) {
-               rbt->rbt_minmax[RB_POSITION(self)] = father;
-               /*
-                * When removing the root, rbt->rbt_minmax[RB_DIR_LEFT] is
-                * updated automatically, but we also need to update
-                * rbt->rbt_minmax[RB_DIR_RIGHT];
-                */
-               if (__predict_false(was_root)) {
-                       rbt->rbt_minmax[RB_DIR_RIGHT] = father;
-               }
-       }
-       RB_SET_FATHER(self, NULL);
-#endif
-
-       /*
-        * Rebalance if requested.
-        */
-       if (rebalance)
-               rb_tree_removal_rebalance(rbt, father, which);
-       KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true));
-}
-\f
-/*
- * When deleting an interior node
- */
-static void
-rb_tree_swap_prune_and_rebalance(struct rb_tree *rbt, struct rb_node *self,
-       struct rb_node *standin)
-{
-       const unsigned int standin_which = RB_POSITION(standin);
-       unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
-       struct rb_node *standin_son;
-       struct rb_node *standin_father = RB_FATHER(standin);
-       bool rebalance = RB_BLACK_P(standin);
-
-       if (standin_father == self) {
-               /*
-                * As a child of self, any childen would be opposite of
-                * our parent.
-                */
-               KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other]));
-               standin_son = standin->rb_nodes[standin_which];
-       } else {
-               /*
-                * Since we aren't a child of self, any childen would be
-                * on the same side as our parent.
-                */
-               KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_which]));
-               standin_son = standin->rb_nodes[standin_other];
-       }
-
-       /*
-        * the node we are removing must have two children.
-        */
-       KASSERT(RB_TWOCHILDREN_P(self));
-       /*
-        * If standin has a child, it must be red.
-        */
-       KASSERT(RB_SENTINEL_P(standin_son) || RB_RED_P(standin_son));
-
-       /*
-        * Verify things are sane.
-        */
-       KASSERT(rb_tree_check_node(rbt, self, NULL, false));
-       KASSERT(rb_tree_check_node(rbt, standin, NULL, false));
-
-       if (__predict_false(RB_RED_P(standin_son))) {
-               /*
-                * We know we have a red child so if we flip it to black
-                * we don't have to rebalance.
-                */
-               KASSERT(rb_tree_check_node(rbt, standin_son, NULL, true));
-               RB_MARK_BLACK(standin_son);
-               rebalance = false;
-
-               if (standin_father == self) {
-                       KASSERT(RB_POSITION(standin_son) == standin_which);
-               } else {
-                       KASSERT(RB_POSITION(standin_son) == standin_other);
-                       /*
-                        * Change the son's parentage to point to his grandpa.
-                        */
-                       RB_SET_FATHER(standin_son, standin_father);
-                       RB_SET_POSITION(standin_son, standin_which);
-               }
-       }
-
-       if (standin_father == self) {
-               /*
-                * If we are about to delete the standin's father, then when
-                * we call rebalance, we need to use ourselves as our father.
-                * Otherwise remember our original father.  Also, sincef we are
-                * our standin's father we only need to reparent the standin's
-                * brother.
-                *
-                * |    R      -->     S    |
-                * |  Q   S    -->   Q   T  |
-                * |        t  -->          |
-                */
-               KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other]));
-               KASSERT(!RB_SENTINEL_P(self->rb_nodes[standin_other]));
-               KASSERT(self->rb_nodes[standin_which] == standin);
-               /*
-                * Have our son/standin adopt his brother as his new son.
-                */
-               standin_father = standin;
-       } else {
-               /*
-                * |    R          -->    S       .  |
-                * |   / \  |   T  -->   / \  |  /   |
-                * |  ..... | S    -->  ..... | T    |
-                *
-                * Sever standin's connection to his father.
-                */
-               standin_father->rb_nodes[standin_which] = standin_son;
-               /*
-                * Adopt the far son.
-                */
-               standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
-               RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
-               KASSERT(RB_POSITION(self->rb_nodes[standin_other]) == standin_other);
-               /*
-                * Use standin_other because we need to preserve standin_which
-                * for the removal_rebalance.
-                */
-               standin_other = standin_which;
-       }
-
-       /*
-        * Move the only remaining son to our standin.  If our standin is our
-        * son, this will be the only son needed to be moved.
-        */
-       KASSERT(standin->rb_nodes[standin_other] != self->rb_nodes[standin_other]);
-       standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
-       RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
-
-       /*
-        * Now copy the result of self to standin and then replace
-        * self with standin in the tree.
-        */
-       RB_COPY_PROPERTIES(standin, self);
-       RB_SET_FATHER(standin, RB_FATHER(self));
-       RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
-
-       /*
-        * Remove ourselves from the node list, decrement the count,
-        * and update min/max.
-        */
-       RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
-       rbt->rbt_count--;
-#ifndef RBSMALL
-       if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self))
-               rbt->rbt_minmax[RB_POSITION(self)] = RB_FATHER(self);
-       RB_SET_FATHER(self, NULL);
-#endif
-
-       KASSERT(rb_tree_check_node(rbt, standin, NULL, false));
-       KASSERT(RB_FATHER_SENTINEL_P(standin)
-               || rb_tree_check_node(rbt, standin_father, NULL, false));
-       KASSERT(RB_LEFT_SENTINEL_P(standin)
-               || rb_tree_check_node(rbt, standin->rb_left, NULL, false));
-       KASSERT(RB_RIGHT_SENTINEL_P(standin)
-               || rb_tree_check_node(rbt, standin->rb_right, NULL, false));
-
-       if (!rebalance)
-               return;
-
-       rb_tree_removal_rebalance(rbt, standin_father, standin_which);
-       KASSERT(rb_tree_check_node(rbt, standin, NULL, true));
-}
-
-/*
- * We could do this by doing
- *     rb_tree_node_swap(rbt, self, which);
- *     rb_tree_prune_node(rbt, self, false);
- *
- * But it's more efficient to just evalate and recolor the child.
- */
-static void
-rb_tree_prune_blackred_branch(struct rb_tree *rbt, struct rb_node *self,
-       unsigned int which)
-{
-       struct rb_node *father = RB_FATHER(self);
-       struct rb_node *son = self->rb_nodes[which];
-       const bool was_root = RB_ROOT_P(rbt, self);
-
-       KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
-       KASSERT(RB_BLACK_P(self) && RB_RED_P(son));
-       KASSERT(!RB_TWOCHILDREN_P(son));
-       KASSERT(RB_CHILDLESS_P(son));
-       KASSERT(rb_tree_check_node(rbt, self, NULL, false));
-       KASSERT(rb_tree_check_node(rbt, son, NULL, false));
-
-       /*
-        * Remove ourselves from the tree and give our former child our
-        * properties (position, color, root).
-        */
-       RB_COPY_PROPERTIES(son, self);
-       father->rb_nodes[RB_POSITION(son)] = son;
-       RB_SET_FATHER(son, father);
-
-       /*
-        * Remove ourselves from the node list, decrement the count,
-        * and update minmax.
-        */
-       RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
-       rbt->rbt_count--;
-#ifndef RBSMALL
-       if (__predict_false(was_root)) {
-               KASSERT(rbt->rbt_minmax[which] == son);
-               rbt->rbt_minmax[which ^ RB_DIR_OTHER] = son;
-       } else if (rbt->rbt_minmax[RB_POSITION(self)] == self) {
-               rbt->rbt_minmax[RB_POSITION(self)] = son;
-       }
-       RB_SET_FATHER(self, NULL);
-#endif
-
-       KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true));
-       KASSERT(rb_tree_check_node(rbt, son, NULL, true));
-}
-/*
- *
- */
-void
-rb_tree_remove_node(struct rb_tree *rbt, struct rb_node *self)
-{
-       struct rb_node *standin;
-       unsigned int which;
-
-       KASSERT(!RB_SENTINEL_P(self));
-       RBSTAT_INC(rbt->rbt_removals);
-
-       /*
-        * In the following diagrams, we (the node to be removed) are S.  Red
-        * nodes are lowercase.  T could be either red or black.
-        *
-        * Remember the major axiom of the red-black tree: the number of
-        * black nodes from the root to each leaf is constant across all
-        * leaves, only the number of red nodes varies.
-        *
-        * Thus removing a red leaf doesn't require any other changes to a
-        * red-black tree.  So if we must remove a node, attempt to rearrange
-        * the tree so we can remove a red node.
-        *
-        * The simpliest case is a childless red node or a childless root node:
-        *
-        * |    T  -->    T  |    or    |  R  -->  *  |
-        * |  s    -->  *    |
-        */
-       if (RB_CHILDLESS_P(self)) {
-               const bool rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
-               rb_tree_prune_node(rbt, self, rebalance);
-               return;
-       }
-       KASSERT(!RB_CHILDLESS_P(self));
-       if (!RB_TWOCHILDREN_P(self)) {
-               /*
-                * The next simpliest case is the node we are deleting is
-                * black and has one red child.
-                *
-                * |      T  -->      T  -->      T  |
-                * |    S    -->  R      -->  R      |
-                * |  r      -->    s    -->    *    |
-                */
-               which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
-               KASSERT(RB_BLACK_P(self));
-               KASSERT(RB_RED_P(self->rb_nodes[which]));
-               KASSERT(RB_CHILDLESS_P(self->rb_nodes[which]));
-               rb_tree_prune_blackred_branch(rbt, self, which);
-               return;
-       }
-       KASSERT(RB_TWOCHILDREN_P(self));
-
-       /*
-        * We invert these because we prefer to remove from the inside of
-        * the tree.
-        */
-       which = RB_POSITION(self) ^ RB_DIR_OTHER;
-
-       /*
-        * Let's find the node closes to us opposite of our parent
-        * Now swap it with ourself, "prune" it, and rebalance, if needed.
-        */
-       standin = rb_tree_iterate(rbt, self, which);
-       rb_tree_swap_prune_and_rebalance(rbt, self, standin);
-}
-
-static void
-rb_tree_removal_rebalance(struct rb_tree *rbt, struct rb_node *parent,
-       unsigned int which)
-{
-       KASSERT(!RB_SENTINEL_P(parent));
-       KASSERT(RB_SENTINEL_P(parent->rb_nodes[which]));
-       KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
-       RBSTAT_INC(rbt->rbt_removal_rebalance_calls);
-
-       while (RB_BLACK_P(parent->rb_nodes[which])) {
-               unsigned int other = which ^ RB_DIR_OTHER;
-               struct rb_node *brother = parent->rb_nodes[other];
-
-               RBSTAT_INC(rbt->rbt_removal_rebalance_passes);
-
-               KASSERT(!RB_SENTINEL_P(brother));
-               /*
-                * For cases 1, 2a, and 2b, our brother's children must
-                * be black and our father must be black
-                */
-               if (RB_BLACK_P(parent)
-                   && RB_BLACK_P(brother->rb_left)
-                   && RB_BLACK_P(brother->rb_right)) {
-                       if (RB_RED_P(brother)) {
-                               /*
-                                * Case 1: Our brother is red, swap its
-                                * position (and colors) with our parent.
-                                * This should now be case 2b (unless C or E
-                                * has a red child which is case 3; thus no
-                                * explicit branch to case 2b).
-                                *
-                                *    B         ->        D
-                                *  A     d     ->    b     E
-                                *      C   E   ->  A   C
-                                */
-                               KASSERT(RB_BLACK_P(parent));
-                               rb_tree_reparent_nodes(rbt, parent, other);
-                               brother = parent->rb_nodes[other];
-                               KASSERT(!RB_SENTINEL_P(brother));
-                               KASSERT(RB_RED_P(parent));
-                               KASSERT(RB_BLACK_P(brother));
-                               KASSERT(rb_tree_check_node(rbt, brother, NULL, false));
-                               KASSERT(rb_tree_check_node(rbt, parent, NULL, false));
-                       } else {
-                               /*
-                                * Both our parent and brother are black.
-                                * Change our brother to red, advance up rank
-                                * and go through the loop again.
-                                *
-                                *    B         ->   *B
-                                * *A     D     ->  A     d
-                                *      C   E   ->      C   E
-                                */
-                               RB_MARK_RED(brother);
-                               KASSERT(RB_BLACK_P(brother->rb_left));
-                               KASSERT(RB_BLACK_P(brother->rb_right));
-                               if (RB_ROOT_P(rbt, parent))
-                                       return; /* root == parent == black */
-                               KASSERT(rb_tree_check_node(rbt, brother, NULL, false));
-                               KASSERT(rb_tree_check_node(rbt, parent, NULL, false));
-                               if (parent != NULL) {
-                                       which = RB_POSITION(parent);
-                                       parent = RB_FATHER(parent);
-                               }
-                               continue;
-                       }
-               }
-               /*
-                * Avoid an else here so that case 2a above can hit either
-                * case 2b, 3, or 4.
-                */
-               if (RB_RED_P(parent)
-                       && (RB_SENTINEL_P(brother)
-                               || (RB_BLACK_P(brother)
-                                       && RB_BLACK_P(brother->rb_left)
-                                       && RB_BLACK_P(brother->rb_right)))) {
-                       KASSERT(RB_RED_P(parent));
-                       KASSERT(RB_BLACK_P(brother));
-                       KASSERT(RB_BLACK_P(brother->rb_left));
-                       KASSERT(RB_BLACK_P(brother->rb_right));
-                       /*
-                        * We are black, our father is red, our brother and
-                        * both nephews are black.  Simply invert/exchange the
-                        * colors of our father and brother (to black and red
-                        * respectively).
-                        *
-                        *      |    f        -->    F        |
-                        *      |  *     B    -->  *     b    |
-                        *      |      N   N  -->      N   N  |
-                        */
-                       RB_MARK_BLACK(parent);
-                       if (!RB_SENTINEL_P(brother)) {
-                               RB_MARK_RED(brother);
-                       }
-                       KASSERT(rb_tree_check_node(rbt, brother, NULL, true));
-                       break;          /* We're done! */
-               } else {
-                       /*
-                        * Our brother must be black and have at least one
-                        * red child (it may have two).
-                        */
-                       KASSERT(RB_BLACK_P(brother));
-                       KASSERT(RB_RED_P(brother->rb_nodes[which]) ||
-                               RB_RED_P(brother->rb_nodes[other]));
-                       if (RB_BLACK_P(brother->rb_nodes[other])) {
-                               /*
-                                * Case 3: our brother is black, our near
-                                * nephew is red, and our far nephew is black.
-                                * Swap our brother with our near nephew.
-                                * This result in a tree that matches case 4.
-                                * (Our father could be red or black).
-                                *
-                                *      |    F      -->    F      |
-                                *      |  x     B  -->  x   B    |
-                                *      |      n    -->        n  |
-                                */
-                               KASSERT(RB_RED_P(brother->rb_nodes[which]));
-                               rb_tree_reparent_nodes(rbt, brother, which);
-                               KASSERT(RB_FATHER(brother) == parent->rb_nodes[other]);
-                               brother = parent->rb_nodes[other];
-                               KASSERT(RB_RED_P(brother->rb_nodes[other]));
-                       }
-                       /*
-                        * Case 4: our brother is black and our far nephew
-                        * is red.  Swap our father and brother locations and
-                        * change our far nephew to black.  (these can be
-                        * done in either order so we change the color first).
-                        * The result is a valid red-black tree and is a
-                        * terminal case.  (again we don't care about the
-                        * father's color)
-                        *
-                        * If the father is red, we will get a red-black-black
-                        * tree:
-                        *      |  f      ->  f      -->    b    |
-                        *      |    B    ->    B    -->  F   N  |
-                        *      |      n  ->      N  -->         |
-                        *
-                        * If the father is black, we will get an all black
-                        * tree:
-                        *      |  F      ->  F      -->    B    |
-                        *      |    B    ->    B    -->  F   N  |
-                        *      |      n  ->      N  -->         |
-                        *
-                        * If we had two red nephews, then after the swap,
-                        * our former father would have a red grandson.
-                        */
-                       KASSERT(RB_BLACK_P(brother));
-                       KASSERT(RB_RED_P(brother->rb_nodes[other]));
-                       RB_MARK_BLACK(brother->rb_nodes[other]);
-                       rb_tree_reparent_nodes(rbt, parent, other);
-                       break;          /* We're done! */
-               }
-       }
-       KASSERT(rb_tree_check_node(rbt, parent, NULL, true));
-}
-
-struct rb_node *
-rb_tree_iterate(struct rb_tree *rbt, struct rb_node *self,
-       const unsigned int direction)
-{
-       const unsigned int other = direction ^ RB_DIR_OTHER;
-       KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT);
-
-       if (self == NULL) {
-#ifndef RBSMALL
-               if (RB_SENTINEL_P(rbt->rbt_root))
-                       return NULL;
-               return rbt->rbt_minmax[direction];
-#else
-               self = rbt->rbt_root;
-               if (RB_SENTINEL_P(self))
-                       return NULL;
-               while (!RB_SENTINEL_P(self->rb_nodes[other]))
-                       self = self->rb_nodes[other];
-               return self;
-#endif /* !RBSMALL */
-       }
-       KASSERT(!RB_SENTINEL_P(self));
-       /*
-        * We can't go any further in this direction.  We proceed up in the
-        * opposite direction until our parent is in direction we want to go.
-        */
-       if (RB_SENTINEL_P(self->rb_nodes[direction])) {
-               while (!RB_ROOT_P(rbt, self)) {
-                       if (other == RB_POSITION(self))
-                               return RB_FATHER(self);
-                       self = RB_FATHER(self);
-               }
-               return NULL;
-       }
-
-       /*
-        * Advance down one in current direction and go down as far as possible
-        * in the opposite direction.
-        */
-       self = self->rb_nodes[direction];
-       KASSERT(!RB_SENTINEL_P(self));
-       while (!RB_SENTINEL_P(self->rb_nodes[other]))
-               self = self->rb_nodes[other];
-       return self;
-}
-
-#ifdef RBDEBUG
-static const struct rb_node *
-rb_tree_iterate_const(const struct rb_tree *rbt, const struct rb_node *self,
-       const unsigned int direction)
-{
-       const unsigned int other = direction ^ RB_DIR_OTHER;
-       KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT);
-
-       if (self == NULL) {
-#ifndef RBSMALL
-               if (RB_SENTINEL_P(rbt->rbt_root))
-                       return NULL;
-               return rbt->rbt_minmax[direction];
-#else
-               self = rbt->rbt_root;
-               if (RB_SENTINEL_P(self))
-                       return NULL;
-               while (!RB_SENTINEL_P(self->rb_nodes[other]))
-                       self = self->rb_nodes[other];
-               return self;
-#endif /* !RBSMALL */
-       }
-       KASSERT(!RB_SENTINEL_P(self));
-       /*
-        * We can't go any further in this direction.  We proceed up in the
-        * opposite direction until our parent is in direction we want to go.
-        */
-       if (RB_SENTINEL_P(self->rb_nodes[direction])) {
-               while (!RB_ROOT_P(rbt, self)) {
-                       if (other == RB_POSITION(self))
-                               return RB_FATHER(self);
-                       self = RB_FATHER(self);
-               }
-               return NULL;
-       }
-
-       /*
-        * Advance down one in current direction and go down as far as possible
-        * in the opposite direction.
-        */
-       self = self->rb_nodes[direction];
-       KASSERT(!RB_SENTINEL_P(self));
-       while (!RB_SENTINEL_P(self->rb_nodes[other]))
-               self = self->rb_nodes[other];
-       return self;
-}
-
-static unsigned int
-rb_tree_count_black(const struct rb_node *self)
-{
-       unsigned int left, right;
-
-       if (RB_SENTINEL_P(self))
-               return 0;
-
-       left = rb_tree_count_black(self->rb_left);
-       right = rb_tree_count_black(self->rb_right);
-
-       KASSERT(left == right);
-
-       return left + RB_BLACK_P(self);
-}
-
-static bool
-rb_tree_check_node(const struct rb_tree *rbt, const struct rb_node *self,
-       const struct rb_node *prev, bool red_check)
-{
-       rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
-
-       KASSERT(!RB_SENTINEL_P(self));
-       KASSERT(prev == NULL || (*compare_nodes)(prev, self) > 0);
-
-       /*
-        * Verify our relationship to our parent.
-        */
-       if (RB_ROOT_P(rbt, self)) {
-               KASSERT(self == rbt->rbt_root);
-               KASSERT(RB_POSITION(self) == RB_DIR_LEFT);
-               KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self);
-               KASSERT(RB_FATHER(self) == (const struct rb_node *) &rbt->rbt_root);
-       } else {
-               KASSERT(self != rbt->rbt_root);
-               KASSERT(!RB_FATHER_SENTINEL_P(self));
-               if (RB_POSITION(self) == RB_DIR_LEFT) {
-                       KASSERT((*compare_nodes)(self, RB_FATHER(self)) > 0);
-                       KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self);
-               } else {
-                       KASSERT((*compare_nodes)(self, RB_FATHER(self)) < 0);
-                       KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_RIGHT] == self);
-               }
-       }
-
-       /*
-        * Verify our position in the linked list against the tree itself.
-        */
-       {
-               const struct rb_node *prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT);
-               const struct rb_node *next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT);
-               KASSERT(prev0 == TAILQ_PREV(self, rb_node_qh, rb_link));
-               KASSERT(next0 == TAILQ_NEXT(self, rb_link));
-#ifndef RBSMALL
-               KASSERT(prev0 != NULL || self == rbt->rbt_minmax[RB_DIR_LEFT]);
-               KASSERT(next0 != NULL || self == rbt->rbt_minmax[RB_DIR_RIGHT]);
-#endif
-       }
-
-       /*
-        * The root must be black.
-        * There can never be two adjacent red nodes.
-        */
-       if (red_check) {
-               KASSERT(!RB_ROOT_P(rbt, self) || RB_BLACK_P(self));
-               (void) rb_tree_count_black(self);
-               if (RB_RED_P(self)) {
-                       const struct rb_node *brother;
-                       KASSERT(!RB_ROOT_P(rbt, self));
-                       brother = RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER];
-                       KASSERT(RB_BLACK_P(RB_FATHER(self)));
-                       /*
-                        * I'm red and have no children, then I must either
-                        * have no brother or my brother also be red and
-                        * also have no children.  (black count == 0)
-                        */
-                       KASSERT(!RB_CHILDLESS_P(self)
-                               || RB_SENTINEL_P(brother)
-                               || RB_RED_P(brother)
-                               || RB_CHILDLESS_P(brother));
-                       /*
-                        * If I'm not childless, I must have two children
-                        * and they must be both be black.
-                        */
-                       KASSERT(RB_CHILDLESS_P(self)
-                               || (RB_TWOCHILDREN_P(self)
-                                   && RB_BLACK_P(self->rb_left)
-                                   && RB_BLACK_P(self->rb_right)));
-                       /*
-                        * If I'm not childless, thus I have black children,
-                        * then my brother must either be black or have two
-                        * black children.
-                        */
-                       KASSERT(RB_CHILDLESS_P(self)
-                               || RB_BLACK_P(brother)
-                               || (RB_TWOCHILDREN_P(brother)
-                                   && RB_BLACK_P(brother->rb_left)
-                                   && RB_BLACK_P(brother->rb_right)));
-               } else {
-                       /*
-                        * If I'm black and have one child, that child must
-                        * be red and childless.
-                        */
-                       KASSERT(RB_CHILDLESS_P(self)
-                               || RB_TWOCHILDREN_P(self)
-                               || (!RB_LEFT_SENTINEL_P(self)
-                                   && RB_RIGHT_SENTINEL_P(self)
-                                   && RB_RED_P(self->rb_left)
-                                   && RB_CHILDLESS_P(self->rb_left))
-                               || (!RB_RIGHT_SENTINEL_P(self)
-                                   && RB_LEFT_SENTINEL_P(self)
-                                   && RB_RED_P(self->rb_right)
-                                   && RB_CHILDLESS_P(self->rb_right)));
-
-                       /*
-                        * If I'm a childless black node and my parent is
-                        * black, my 2nd closet relative away from my parent
-                        * is either red or has a red parent or red children.
-                        */
-                       if (!RB_ROOT_P(rbt, self)
-                           && RB_CHILDLESS_P(self)
-                           && RB_BLACK_P(RB_FATHER(self))) {
-                               const unsigned int which = RB_POSITION(self);
-                               const unsigned int other = which ^ RB_DIR_OTHER;
-                               const struct rb_node *relative0, *relative;
-
-                               relative0 = rb_tree_iterate_const(rbt,
-                                   self, other);
-                               KASSERT(relative0 != NULL);
-                               relative = rb_tree_iterate_const(rbt,
-                                   relative0, other);
-                               KASSERT(relative != NULL);
-                               KASSERT(RB_SENTINEL_P(relative->rb_nodes[which]));
-#if 0
-                               KASSERT(RB_RED_P(relative)
-                                       || RB_RED_P(relative->rb_left)
-                                       || RB_RED_P(relative->rb_right)
-                                       || RB_RED_P(RB_FATHER(relative)));
-#endif
-                       }
-               }
-               /*
-                * A grandparent's children must be real nodes and not
-                * sentinels.  First check out grandparent.
-                */
-               KASSERT(RB_ROOT_P(rbt, self)
-                       || RB_ROOT_P(rbt, RB_FATHER(self))
-                       || RB_TWOCHILDREN_P(RB_FATHER(RB_FATHER(self))));
-               /*
-                * If we are have grandchildren on our left, then
-                * we must have a child on our right.
-                */
-               KASSERT(RB_LEFT_SENTINEL_P(self)
-                       || RB_CHILDLESS_P(self->rb_left)
-                       || !RB_RIGHT_SENTINEL_P(self));
-               /*
-                * If we are have grandchildren on our right, then
-                * we must have a child on our left.
-                */
-               KASSERT(RB_RIGHT_SENTINEL_P(self)
-                       || RB_CHILDLESS_P(self->rb_right)
-                       || !RB_LEFT_SENTINEL_P(self));
-
-               /*
-                * If we have a child on the left and it doesn't have two
-                * children make sure we don't have great-great-grandchildren on
-                * the right.
-                */
-               KASSERT(RB_TWOCHILDREN_P(self->rb_left)
-                       || RB_CHILDLESS_P(self->rb_right)
-                       || RB_CHILDLESS_P(self->rb_right->rb_left)
-                       || RB_CHILDLESS_P(self->rb_right->rb_left->rb_left)
-                       || RB_CHILDLESS_P(self->rb_right->rb_left->rb_right)
-                       || RB_CHILDLESS_P(self->rb_right->rb_right)
-                       || RB_CHILDLESS_P(self->rb_right->rb_right->rb_left)
-                       || RB_CHILDLESS_P(self->rb_right->rb_right->rb_right));
-
-               /*
-                * If we have a child on the right and it doesn't have two
-                * children make sure we don't have great-great-grandchildren on
-                * the left.
-                */
-               KASSERT(RB_TWOCHILDREN_P(self->rb_right)
-                       || RB_CHILDLESS_P(self->rb_left)
-                       || RB_CHILDLESS_P(self->rb_left->rb_left)
-                       || RB_CHILDLESS_P(self->rb_left->rb_left->rb_left)
-                       || RB_CHILDLESS_P(self->rb_left->rb_left->rb_right)
-                       || RB_CHILDLESS_P(self->rb_left->rb_right)
-                       || RB_CHILDLESS_P(self->rb_left->rb_right->rb_left)
-                       || RB_CHILDLESS_P(self->rb_left->rb_right->rb_right));
-
-               /*
-                * If we are fully interior node, then our predecessors and
-                * successors must have no children in our direction.
-                */
-               if (RB_TWOCHILDREN_P(self)) {
-                       const struct rb_node *prev0;
-                       const struct rb_node *next0;
-
-                       prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT);
-                       KASSERT(prev0 != NULL);
-                       KASSERT(RB_RIGHT_SENTINEL_P(prev0));
-
-                       next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT);
-                       KASSERT(next0 != NULL);
-                       KASSERT(RB_LEFT_SENTINEL_P(next0));
-               }
-       }
-
-       return true;
-}
-
-void
-rb_tree_check(const struct rb_tree *rbt, bool red_check)
-{
-       const struct rb_node *self;
-       const struct rb_node *prev;
-#ifdef RBSTATS
-       unsigned int count = 0;
-#endif
-
-       KASSERT(rbt->rbt_root != NULL);
-       KASSERT(RB_LEFT_P(rbt->rbt_root));
-
-#if defined(RBSTATS) && !defined(RBSMALL)
-       KASSERT(rbt->rbt_count > 1
-           || rbt->rbt_minmax[RB_DIR_LEFT] == rbt->rbt_minmax[RB_DIR_RIGHT]);
-#endif
-
-       prev = NULL;
-       TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) {
-               rb_tree_check_node(rbt, self, prev, false);
-#ifdef RBSTATS
-               count++;
-#endif
-       }
-#ifdef RBSTATS
-       KASSERT(rbt->rbt_count == count);
-#endif
-       if (red_check) {
-               KASSERT(RB_BLACK_P(rbt->rbt_root));
-               KASSERT(RB_SENTINEL_P(rbt->rbt_root)
-                       || rb_tree_count_black(rbt->rbt_root));
-
-               /*
-                * The root must be black.
-                * There can never be two adjacent red nodes.
-                */
-               TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) {
-                       rb_tree_check_node(rbt, self, NULL, true);
-               }
-       }
-}
-#endif /* RBDEBUG */
-
-#ifdef RBSTATS
-static void
-rb_tree_mark_depth(const struct rb_tree *rbt, const struct rb_node *self,
-       size_t *depths, size_t depth)
-{
-       if (RB_SENTINEL_P(self))
-               return;
-
-       if (RB_TWOCHILDREN_P(self)) {
-               rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1);
-               rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1);
-               return;
-       }
-       depths[depth]++;
-       if (!RB_LEFT_SENTINEL_P(self)) {
-               rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1);
-       }
-       if (!RB_RIGHT_SENTINEL_P(self)) {
-               rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1);
-       }
-}
-
-void
-rb_tree_depths(const struct rb_tree *rbt, size_t *depths)
-{
-       rb_tree_mark_depth(rbt, rbt->rbt_root, depths, 1);
-}
-#endif /* RBSTATS */
diff --git a/SystemConfiguration.fproj/reachability/rb.h b/SystemConfiguration.fproj/reachability/rb.h
deleted file mode 100644 (file)
index 56f910d..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp $ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas <matt@3am-software.com>.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef _SYS_RB_H_
-#define        _SYS_RB_H_
-
-#if defined(_KERNEL) || defined(_STANDALONE)
-#include <sys/types.h>
-#else
-#include <stdbool.h>
-#include <inttypes.h>
-#endif
-#include <sys/queue.h>
-#ifndef __APPLE__
-#include <sys/endian.h>
-#endif
-
-struct rb_node {
-       struct rb_node *rb_nodes[2];
-#define        RB_DIR_LEFT             0
-#define        RB_DIR_RIGHT            1
-#define        RB_DIR_OTHER            1
-#define        rb_left                 rb_nodes[RB_DIR_LEFT]
-#define        rb_right                rb_nodes[RB_DIR_RIGHT]
-
-       /*
-        * rb_info contains the two flags and the parent back pointer.
-        * We put the two flags in the low two bits since we know that
-        * rb_node will have an alignment of 4 or 8 bytes.
-        */
-       uintptr_t rb_info;
-#define        RB_FLAG_POSITION        0x2
-#define        RB_FLAG_RED             0x1
-#define        RB_FLAG_MASK            (RB_FLAG_POSITION|RB_FLAG_RED)
-#define        RB_FATHER(rb) \
-    ((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
-#define        RB_SET_FATHER(rb, father) \
-    ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
-
-#define        RB_SENTINEL_P(rb)       ((rb) == NULL)
-#define        RB_LEFT_SENTINEL_P(rb)  RB_SENTINEL_P((rb)->rb_left)
-#define        RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
-#define        RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
-#define        RB_CHILDLESS_P(rb) \
-    (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
-#define        RB_TWOCHILDREN_P(rb) \
-    (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
-
-#define        RB_POSITION(rb) \
-    (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
-#define        RB_RIGHT_P(rb)          (RB_POSITION(rb) == RB_DIR_RIGHT)
-#define        RB_LEFT_P(rb)           (RB_POSITION(rb) == RB_DIR_LEFT)
-#define        RB_RED_P(rb)            (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
-#define        RB_BLACK_P(rb)          (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
-#define        RB_MARK_RED(rb)         ((void)((rb)->rb_info |= RB_FLAG_RED))
-#define        RB_MARK_BLACK(rb)       ((void)((rb)->rb_info &= ~RB_FLAG_RED))
-#define        RB_INVERT_COLOR(rb)     ((void)((rb)->rb_info ^= RB_FLAG_RED))
-#define        RB_ROOT_P(rbt, rb)      ((rbt)->rbt_root == (rb))
-#define        RB_SET_POSITION(rb, position) \
-    ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
-    ((rb)->rb_info &= ~RB_FLAG_POSITION)))
-#define        RB_ZERO_PROPERTIES(rb)  ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
-#define        RB_COPY_PROPERTIES(dst, src) \
-    ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
-#define RB_SWAP_PROPERTIES(a, b) do { \
-    uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
-    (a)->rb_info ^= xorinfo; \
-    (b)->rb_info ^= xorinfo; \
-  } while (/*CONSTCOND*/ 0)
-#ifdef RBDEBUG
-       TAILQ_ENTRY(rb_node) rb_link;
-#endif
-};
-
-#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT)
-#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT)
-#define RB_TREE_FOREACH(N, T) \
-    for ((N) = RB_TREE_MIN(T); (N); \
-       (N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT))
-#define RB_TREE_FOREACH_REVERSE(N, T) \
-    for ((N) = RB_TREE_MAX(T); (N); \
-       (N) = rb_tree_iterate((T), (N), RB_DIR_LEFT))
-
-#ifdef RBDEBUG
-TAILQ_HEAD(rb_node_qh, rb_node);
-
-#define        RB_TAILQ_REMOVE(a, b, c)                TAILQ_REMOVE(a, b, c)
-#define        RB_TAILQ_INIT(a)                        TAILQ_INIT(a)
-#define        RB_TAILQ_INSERT_HEAD(a, b, c)           TAILQ_INSERT_HEAD(a, b, c)
-#define        RB_TAILQ_INSERT_BEFORE(a, b, c)         TAILQ_INSERT_BEFORE(a, b, c)
-#define        RB_TAILQ_INSERT_AFTER(a, b, c, d)       TAILQ_INSERT_AFTER(a, b, c, d)
-#else
-#define        RB_TAILQ_REMOVE(a, b, c)                do { } while (/*CONSTCOND*/0)
-#define        RB_TAILQ_INIT(a)                        do { } while (/*CONSTCOND*/0)
-#define        RB_TAILQ_INSERT_HEAD(a, b, c)           do { } while (/*CONSTCOND*/0)
-#define        RB_TAILQ_INSERT_BEFORE(a, b, c)         do { } while (/*CONSTCOND*/0)
-#define        RB_TAILQ_INSERT_AFTER(a, b, c, d)       do { } while (/*CONSTCOND*/0)
-#endif /* RBDEBUG */
-
-/*
- * rbto_compare_nodes_fn:
- *     return a positive value if the first node < the second node.
- *     return a negative value if the first node > the second node.
- *     return 0 if they are considered same.
- *
- * rbto_compare_key_fn:
- *     return a positive value if the node < the key.
- *     return a negative value if the node > the key.
- *     return 0 if they are considered same.
- */
-
-typedef signed int (*const rbto_compare_nodes_fn)(const struct rb_node *,
-    const struct rb_node *);
-typedef signed int (*const rbto_compare_key_fn)(const struct rb_node *,
-    const void *);
-
-struct rb_tree_ops {
-       rbto_compare_nodes_fn rbto_compare_nodes;
-       rbto_compare_key_fn rbto_compare_key;
-};
-
-struct rb_tree {
-       struct rb_node *rbt_root;
-       const struct rb_tree_ops *rbt_ops;
-       struct rb_node *rbt_minmax[2];
-#ifdef RBDEBUG
-       struct rb_node_qh rbt_nodes;
-#endif
-       unsigned int rbt_count;
-#ifdef RBSTATS
-       unsigned int rbt_insertions;
-       unsigned int rbt_removals;
-       unsigned int rbt_insertion_rebalance_calls;
-       unsigned int rbt_insertion_rebalance_passes;
-       unsigned int rbt_removal_rebalance_calls;
-       unsigned int rbt_removal_rebalance_passes;
-#endif
-};
-
-#ifdef RBSTATS
-#define        RBSTAT_INC(v)   ((void)((v)++))
-#define        RBSTAT_DEC(v)   ((void)((v)--))
-#else
-#define        RBSTAT_INC(v)   do { } while (/*CONSTCOND*/0)
-#define        RBSTAT_DEC(v)   do { } while (/*CONSTCOND*/0)
-#endif
-
-void   rb_tree_init(struct rb_tree *, const struct rb_tree_ops *);
-bool   rb_tree_insert_node(struct rb_tree *, struct rb_node *);
-struct rb_node *
-       rb_tree_find_node(struct rb_tree *, const void *);
-struct rb_node *
-       rb_tree_find_node_geq(struct rb_tree *, const void *);
-struct rb_node *
-       rb_tree_find_node_leq(struct rb_tree *, const void *);
-void   rb_tree_remove_node(struct rb_tree *, struct rb_node *);
-struct rb_node *
-       rb_tree_iterate(struct rb_tree *, struct rb_node *, const unsigned int);
-#ifdef RBDEBUG
-void   rb_tree_check(const struct rb_tree *, bool);
-#endif
-#ifdef RBSTATS
-void   rb_tree_depths(const struct rb_tree *, size_t *);
-#endif
-
-#endif /* _SYS_RB_H_*/
diff --git a/SystemConfiguration.fproj/scprefs_observer.c b/SystemConfiguration.fproj/scprefs_observer.c
new file mode 100644 (file)
index 0000000..6d9a074
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2012, 2013 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 <CommonCrypto/CommonDigest.h>
+#include <dirent.h>
+#include <notify.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/scprefs_observer.h>
+
+#pragma mark -
+#pragma mark Utils
+
+static void
+iterate_dir(const char *d_name, const char *f_name,
+           CC_SHA1_CTX *ctxP, Boolean *found)
+{
+       DIR *dir;
+       struct dirent * dp;
+
+       dir = opendir(d_name);
+
+       if (dir == NULL) {
+               /* if directory path does not exist */
+               return;
+       }
+
+       while ((dp = readdir(dir)) != NULL) {
+               char            full_path[MAXPATHLEN];
+               struct stat     s;
+
+               if ((strcmp(dp->d_name, ".") == 0) ||
+                   (strcmp(dp->d_name, "..") == 0)) {
+                       continue;
+               }
+
+               /* check path */
+               snprintf(full_path, sizeof(full_path), "%s/%s", d_name, dp->d_name);
+               if (stat(full_path, &s) == 0) {
+                       if (S_ISDIR(s.st_mode)) {
+                               // if sub-directory, iterate
+                               iterate_dir(full_path, f_name, ctxP, found);
+                       } else if (strcmp(f_name, dp->d_name) == 0) {
+                               /*
+                                * if this is the requested file, include
+                                * the path and last modification time in
+                                * the digest
+                               */
+                               CC_SHA1_Update(ctxP, full_path, strlen(full_path));
+                               CC_SHA1_Update(ctxP,
+                                              (void *)&s.st_mtimespec.tv_sec,
+                                              sizeof(s.st_mtimespec.tv_sec));
+                               *found = TRUE;
+                       }
+               }
+       }
+       closedir(dir);
+       return;
+}
+
+static CFDataRef
+build_digest(const char *top_dir, const char *file)
+{
+       unsigned char   bytes[CC_SHA1_DIGEST_LENGTH];
+       CC_SHA1_CTX     ctx;
+       CFDataRef       digest = NULL;
+       Boolean         found = FALSE;
+
+       CC_SHA1_Init(&ctx);
+       iterate_dir(top_dir, file, &ctx, &found);
+       CC_SHA1_Final(bytes, &ctx);
+       if (found == TRUE) {
+               digest = CFDataCreate(NULL, bytes, sizeof(bytes));
+       }
+       return (digest);
+}
+
+#pragma mark -
+#pragma mark perfs_observer Private
+
+struct _scprefs_observer_t {
+       _scprefs_observer_type                  type;
+       dispatch_block_t                        block;
+       CFDataRef                               digest;
+       SLIST_ENTRY(_scprefs_observer_t)        next;
+       dispatch_queue_t                        queue;
+       char                                    file[0];
+};
+
+#define MOBILE_PREFERENCES_PATH "/var/mobile/Library/Preferences"
+static const char *
+prefs_observer_get_prefs_path(scprefs_observer_t observer)
+{
+       switch (observer->type) {
+#if    !TARGET_OS_IPHONE
+       case scprefs_observer_type_mcx:
+               return ("/Library/Managed Preferences");
+#else  // !TARGET_OS_IPHONE
+       case scprefs_observer_type_global:
+               return ("/Library/Managed Preferences");
+       case scprefs_observer_type_profile:
+               return MOBILE_PREFERENCES_PATH;
+#endif // !TARGET_OS_IPHONE
+       default:
+               return (NULL);
+       }
+}
+
+/*
+ * Iterate through all of the directories and subdirectories.
+ * If the file within those directories has changed,
+ * then generate the notification.
+ */
+static Boolean
+has_changed(scprefs_observer_t  observer) {
+       Boolean         changed;
+       CFDataRef       digest = NULL;
+       const char *    starting_path;
+
+       starting_path = prefs_observer_get_prefs_path(observer);
+
+       digest = build_digest(starting_path, observer->file);
+
+       /* compare old vs. new digest */
+       changed = _SC_CFEqual(digest, observer->digest)?FALSE:TRUE;
+
+       /* save the digest */
+       if (observer->digest != NULL) {
+               CFRelease(observer->digest);
+       }
+
+       observer->digest = digest;
+
+       SCLog(_sc_verbose, LOG_NOTICE, CFSTR("The following file: %s, %s \n"),
+             observer->file, (changed)?"has changed":"has not changed");
+       return (changed);
+}
+
+static dispatch_queue_t
+prefs_observer_queue;
+
+/* This holds the list of the observers */
+static SLIST_HEAD(mylist, _scprefs_observer_t) head;
+
+static void
+prefs_observer_release(scprefs_observer_t observer)
+{
+       SLIST_REMOVE(&head, observer, _scprefs_observer_t, next);
+
+       /* Now free the observer */
+       if (observer->digest != NULL) {
+               CFRelease(observer->digest);
+       }
+
+       free(observer);
+}
+
+static void
+prefs_observer_handle_notifications()
+{
+       scprefs_observer_t observer;
+
+       SCLog(_sc_verbose, LOG_NOTICE, CFSTR("PrefsObserver Notification received \n"));
+
+       SLIST_FOREACH(observer, &head, next) {
+               /* if the preferences plist has changed,
+                * called the block */
+               if (has_changed(observer)) {
+                       dispatch_async(observer->queue, observer->block);
+               }
+       }
+}
+
+#define PREFS_OBSERVER_KEY "com.apple.ManagedConfiguration.profileListChanged"
+static void
+_prefs_observer_init()
+{
+       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(); });
+}
+
+static scprefs_observer_t
+prefs_observer_priv_create(_scprefs_observer_type type,
+                          const char *plist_name,
+                          dispatch_queue_t queue,
+                          dispatch_block_t block)
+{
+       scprefs_observer_t observer;
+       int path_buflen;
+
+       path_buflen = strlen(plist_name) + 1;
+
+       observer = (scprefs_observer_t)malloc(sizeof(struct _scprefs_observer_t) + path_buflen);
+       bzero((void *)observer, sizeof(struct _scprefs_observer_t));
+
+       /* Create the observer */
+       observer->type = type;
+       strlcpy(observer->file, plist_name, path_buflen);
+
+       observer->queue = queue;
+       observer->block = Block_copy(block);
+
+       return (observer);
+}
+
+#pragma mark -
+#pragma mark perfs_observer Public SPI
+scprefs_observer_t
+_scprefs_observer_watch(_scprefs_observer_type type, const char *plist_name,
+                          dispatch_queue_t queue, dispatch_block_t block)
+{
+       scprefs_observer_t elem;
+       static dispatch_once_t initialized;
+
+       dispatch_once(&initialized, ^{ _prefs_observer_init(); } );
+
+       elem = prefs_observer_priv_create(type, plist_name, queue, block);
+       SCLog(_sc_verbose, LOG_NOTICE, CFSTR("Created a new element to watch for %s \n"),
+             elem->file);
+
+       dispatch_sync(prefs_observer_queue,
+                     ^{
+                         /* Enqueue the request */
+                         SLIST_INSERT_HEAD(&head, elem, next);
+                     });
+       return (elem);
+}
+
+/* This will cancel/deregister the given watcher.  This will be synchronized on the
+ * internally created queue. */
+void
+_scprefs_observer_cancel(scprefs_observer_t observer)
+{
+       dispatch_sync(prefs_observer_queue,
+                     ^{ prefs_observer_release((scprefs_observer_t)observer); });
+
+}
+
+#pragma mark -
+
+#ifdef TEST_MAIN
+int main()
+{
+       int random = 1;
+
+       _sc_verbose = 1;
+
+       dispatch_queue_t q = dispatch_queue_create("com.apple.SystemConfiguration.PrefsObserver.mainQ", NULL);
+
+       dispatch_queue_t q1 = dispatch_queue_create("com.apple.SystemConfiguration.PrefsObserver.testQ1", NULL);
+
+       dispatch_block_t b1 = ^{
+       printf("Block 1 executed \n");
+       };
+
+       dispatch_queue_t q2 = dispatch_queue_create("com.apple.SystemConfiguration.PrefsObserver.testQ2", NULL);
+       dispatch_block_t b2  = ^{
+       printf("Block 2 executed \n");
+       };
+
+       dispatch_queue_t q3 =  dispatch_queue_create("com.apple.SystemConfiguration.PrefsObserver.testQ2", NULL);
+
+       dispatch_block_t b3 = ^{
+       printf("Block 3 executed \n");
+       };
+
+       __block scprefs_observer_t observer1 = _scprefs_observer_watch(scprefs_observer_type_mcx, "com.apple.SystemConfiguration", q1, b1);
+
+       __block scprefs_observer_t observer2 = _scprefs_observer_watch(scprefs_observer_type_mcx, "foo", q2, b2);
+
+       __block scprefs_observer_t observer3 = _scprefs_observer_watch(scprefs_observer_type_mcx, "bar", q3, b3);
+
+       __block scprefs_observer_t observer = NULL;
+
+       while (1) {
+       switch (random % 3)
+       {
+           case 0:
+               dispatch_async(q, ^{ _SC_prefs_observer_cancel(observer1);
+                                    observer1 = NULL; });
+               dispatch_async(q, ^{ if (observer != NULL)  _SC_prefs_observer_cancel(observer);
+                                    observer = _SC_prefs_observer_watch(SC_prefs_observer_type_mcx,
+                                                                        "test", q2, b2); } );
+               dispatch_sync( q, ^{observer1 = observer; });
+               sleep(random);
+               break;
+           case 1:
+               dispatch_async(q, ^{ _SC_prefs_observer_cancel(observer2); });
+               dispatch_async(q, ^{ if (observer != NULL)  _SC_prefs_observer_cancel(observer); });
+               dispatch_sync( q, ^{observer = _SC_prefs_observer_watch(SC_prefs_observer_type_mcx,
+                                                                       "test", q2, b2); } );
+               sleep(random);
+               break;
+           case 2:
+               sleep (random);
+           default:
+               break;
+       }
+       random++;
+       }
+       dispatch_main();
+}
+#endif
diff --git a/SystemConfiguration.fproj/scprefs_observer.h b/SystemConfiguration.fproj/scprefs_observer.h
new file mode 100644 (file)
index 0000000..a80ef47
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2013 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 _SCPREFS_OBSERVER_H
+#define _SCPREFS_OBSERVER_H
+
+typedef enum {
+#if    !TARGET_OS_IPHONE
+               scprefs_observer_type_mcx       = 1,
+#else  // !TARGET_OS_IPHONE
+               scprefs_observer_type_global    = 2,
+               scprefs_observer_type_profile   = 3,
+#endif // !TARGET_OS_IPHONE
+} _scprefs_observer_type;
+
+typedef struct _scprefs_observer_t * scprefs_observer_t;
+
+/*!
+ @function prefs_observer_watch
+ @discussion Sends a notification to interested configuration agents
+ when a particular preference file has changed.
+ @param type - the type of preference (MCX on OSX, Global/Profiles on iOS) to watch.
+ @param plist - the name of the plist file to watch.
+ @param queue - the queue to be called back on.
+ @param block - the block to be called back on.
+ @result Returns the created preferences observer
+ */
+scprefs_observer_t
+_scprefs_observer_watch(_scprefs_observer_type type, const char *plist_name,
+                       dispatch_queue_t queue, dispatch_block_t block);
+
+/*!
+ @function prefs_observer_watch
+ @discussion Cancells/deregisters the given preferences watcher.
+ @param observer - the watcher to be cancelled.
+ */
+void
+_scprefs_observer_cancel(scprefs_observer_t observer);
+
+#endif /* _SCPREFS_OBSERVER_H */
index 862125b9468b5e484ca033bb6ddd32ca97a38699..c1c1104fd1855926aec455ad0e72f9654ee08906 100755 (executable)
@@ -24,6 +24,7 @@ sub clean_API {
 
        $api_new = $DO_SPLIT ? $api : clean_INC($api);
        $api_new =~ s/(__MAC)_\w+\/\*SPI\*\//\1_NA/g;
 
        $api_new = $DO_SPLIT ? $api : clean_INC($api);
        $api_new =~ s/(__MAC)_\w+\/\*SPI\*\//\1_NA/g;
+       $api_new =~ s/#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*\/\*SPI\*\/\n//;
        $api_new =~ s/(__IPHONE)_\w+\/\*SPI\*\//\1_NA/g;
 
        return $api_new;
        $api_new =~ s/(__IPHONE)_\w+\/\*SPI\*\//\1_NA/g;
 
        return $api_new;
@@ -35,6 +36,7 @@ sub clean_SPI {
 
        $spi_new = clean_INC($spi);
        $spi_new =~ s/(__MAC_\w+)\/\*SPI\*\//\1/g;
 
        $spi_new = clean_INC($spi);
        $spi_new =~ s/(__MAC_\w+)\/\*SPI\*\//\1/g;
+       $spi_new =~ s/(#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*)\/\*SPI\*\//\1/;
        $spi_new =~ s/(__IPHONE_\w+)\/\*SPI\*\//\1/g;
 
        return $spi_new;
        $spi_new =~ s/(__IPHONE_\w+)\/\*SPI\*\//\1/g;
 
        return $spi_new;
index bb6449735f6e517f474c85d453ea26773458772e..c54f4ba4c05782b9a4441de5f88fb67559a2814b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2009, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -232,21 +232,26 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 }
 
 
 }
 
 
+#define N_QUICK        64
+
+
 __private_extern__
 void
 pushNotifications(FILE *_configd_trace)
 {
 __private_extern__
 void
 pushNotifications(FILE *_configd_trace)
 {
-       const void                      **sessionsToNotify;
        CFIndex                         notifyCnt;
        int                             server;
        CFIndex                         notifyCnt;
        int                             server;
-       serverSessionRef                theSession;
+       const void *                    sessionsToNotify_q[N_QUICK];
+       const void **                   sessionsToNotify        = sessionsToNotify_q;
        SCDynamicStorePrivateRef        storePrivate;
        SCDynamicStorePrivateRef        storePrivate;
+       serverSessionRef                theSession;
 
        if (needsNotification == NULL)
                return;         /* if no sessions need to be kicked */
 
        notifyCnt = CFSetGetCount(needsNotification);
 
        if (needsNotification == NULL)
                return;         /* if no sessions need to be kicked */
 
        notifyCnt = CFSetGetCount(needsNotification);
-       sessionsToNotify = malloc(notifyCnt * sizeof(CFNumberRef));
+       if (notifyCnt > (CFIndex)(sizeof(sessionsToNotify_q) / sizeof(CFNumberRef)))
+               sessionsToNotify = CFAllocatorAllocate(NULL, notifyCnt * sizeof(CFNumberRef), 0);
        CFSetGetValues(needsNotification, sessionsToNotify);
        while (--notifyCnt >= 0) {
                (void) CFNumberGetValue(sessionsToNotify[notifyCnt],
        CFSetGetValues(needsNotification, sessionsToNotify);
        while (--notifyCnt >= 0) {
                (void) CFNumberGetValue(sessionsToNotify[notifyCnt],
@@ -361,7 +366,7 @@ pushNotifications(FILE *_configd_trace)
                        }
               }
        }
                        }
               }
        }
-       free(sessionsToNotify);
+       if (sessionsToNotify != sessionsToNotify_q) CFAllocatorDeallocate(NULL, sessionsToNotify);
 
        /*
         * this list of notifications have been posted, wait for some more.
 
        /*
         * this list of notifications have been posted, wait for some more.
index f532b47a9800698eaee81620037e1b46290a51b5..8f01964bb908fc2b444fd69faaa4bfd873375d91 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -134,7 +134,7 @@ _configadd(mach_port_t                      server,
                }
        }
 
                }
        }
 
-       if (!hasWriteAccess(mySession)) {
+       if (!hasWriteAccess(mySession, key)) {
                *sc_status = kSCStatusAccessError;
                goto done;
        }
                *sc_status = kSCStatusAccessError;
                goto done;
        }
index 34e46b36fe1d778715cb939ac735efe405045a04..61729e48fcd1bbe9d617055c800433b7b2dde0be 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -36,8 +36,6 @@
 #include "configd.h"
 #include "session.h"
 
 #include "configd.h"
 #include "session.h"
 
-#define        N_QUICK 16
-
 static Boolean
 isMySessionKey(CFStringRef sessionKey, CFStringRef key)
 {
 static Boolean
 isMySessionKey(CFStringRef sessionKey, CFStringRef key)
 {
index 52db0f86e58f4c020e475b17c08247c9896d26fe..ee85c5ce76d3c9dbb8ccf64be2afb5cec4505585 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -109,7 +109,7 @@ _confignotify(mach_port_t           server,
                }
        }
 
                }
        }
 
-       if (!hasWriteAccess(mySession)) {
+       if (!hasWriteAccess(mySession, key)) {
                *sc_status = kSCStatusAccessError;
                goto done;
        }
                *sc_status = kSCStatusAccessError;
                goto done;
        }
index 2d43008f26b9a17f468b9c44da9e8e46f82602f1..eb27106ea92accbac49a5747766e4dbf802b255d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -149,7 +149,7 @@ _configremove(mach_port_t           server,
                }
        }
 
                }
        }
 
-       if (!hasWriteAccess(mySession)) {
+       if (!hasWriteAccess(mySession, key)) {
                *sc_status = kSCStatusAccessError;
                goto done;
        }
                *sc_status = kSCStatusAccessError;
                goto done;
        }
index ee05645aa2edc85c7824619f00ad59e1d1457abb..0dd2b41b8ec8d1509d67a2d2d4068b50e471eea4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -255,7 +255,7 @@ _configset(mach_port_t                      server,
                }
        }
 
                }
        }
 
-       if (!hasWriteAccess(mySession)) {
+       if (!hasWriteAccess(mySession, key)) {
                *sc_status = kSCStatusAccessError;
                goto done;
        }
                *sc_status = kSCStatusAccessError;
                goto done;
        }
@@ -371,6 +371,8 @@ __SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet,
        return sc_status;
 }
 
        return sc_status;
 }
 
+#define        N_QUICK 32
+
 __private_extern__
 kern_return_t
 _configset_m(mach_port_t               server,
 __private_extern__
 kern_return_t
 _configset_m(mach_port_t               server,
@@ -440,9 +442,65 @@ _configset_m(mach_port_t           server,
                }
        }
 
                }
        }
 
-       if (!hasWriteAccess(mySession)) {
-               *sc_status = kSCStatusAccessError;
-               goto done;
+       if (dict != NULL) {
+               const void *    keys_q[N_QUICK];
+               const void **   keys    = keys_q;
+               CFIndex         i;
+               CFIndex         n;
+               Boolean         writeOK = TRUE;
+
+               n = CFDictionaryGetCount(dict);
+               if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFStringRef))) {
+                       keys   = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
+               }
+               CFDictionaryGetKeysAndValues(dict, keys, NULL);
+               for (i = 0; i < n; i++) {
+                       CFStringRef     key;
+
+                       key = (CFStringRef)keys[i];
+                       if (!hasWriteAccess(mySession, key)) {
+                               writeOK = FALSE;
+                               break;
+                       }
+               }
+               if (keys != keys_q) {
+                       CFAllocatorDeallocate(NULL, keys);
+               }
+
+               if (!writeOK) {
+                       *sc_status = kSCStatusAccessError;
+                       goto done;
+               }
+       }
+
+       if (remove != NULL) {
+               CFIndex i;
+               CFIndex n       = CFArrayGetCount(remove);
+
+               for (i = 0; i < n; i++) {
+                       CFStringRef     key;
+
+                       key = CFArrayGetValueAtIndex(remove, i);
+                       if (!hasWriteAccess(mySession, key)) {
+                               *sc_status = kSCStatusAccessError;
+                               goto done;
+                       }
+               }
+       }
+
+       if (notify != NULL) {
+               CFIndex i;
+               CFIndex n       = CFArrayGetCount(notify);
+
+               for (i = 0; i < n; i++) {
+                       CFStringRef     key;
+
+                       key = CFArrayGetValueAtIndex(notify, i);
+                       if (!hasWriteAccess(mySession, key)) {
+                               *sc_status = kSCStatusAccessError;
+                               goto done;
+                       }
+               }
        }
 
        *sc_status = __SCDynamicStoreSetMultiple(mySession->store, dict, remove, notify);
        }
 
        *sc_status = __SCDynamicStoreSetMultiple(mySession->store, dict, remove, notify);
index bd4a261e328c65d0a8e9f530d5db756cdae92f0e..9c894a570f90fda66180a721f67a8961d89b64dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2006, 2008, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006, 2008, 2010-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -100,7 +100,7 @@ __SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boole
 
                /*
                 * We are watching a specific key. As such, update the
 
                /*
                 * We are watching a specific key. As such, update the
-                * store to mark our interest in any changes.
+                * store to remove our interest in any changes.
                 */
                sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                _removeWatcher(sessionNum, key);
                 */
                sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                _removeWatcher(sessionNum, key);
index 33473f19a316b9c0f7ec5b1db77b8e60aa73c69f..e9c87cf0b4a40a291adb7b9d72969d093623fc36 100644 (file)
                <true/>
                <key>com.apple.SystemConfiguration.SCNetworkReachability</key>
                <true/>
                <true/>
                <key>com.apple.SystemConfiguration.SCNetworkReachability</key>
                <true/>
+               <key>com.apple.SystemConfiguration.DNSConfiguration</key>
+               <true/>
+               <key>com.apple.SystemConfiguration.NetworkInformation</key>
+               <true/>
        </dict>
        <key>POSIXSpawnType</key>
        <string>Interactive</string>
        </dict>
        <key>POSIXSpawnType</key>
        <string>Interactive</string>
diff --git a/configd.tproj/com.apple.configd_sim.plist b/configd.tproj/com.apple.configd_sim.plist
new file mode 100644 (file)
index 0000000..39b9c8e
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>EnableTransactions</key>
+       <true/>
+       <key>KeepAlive</key>
+       <true/>
+       <key>Label</key>
+       <string>com.apple.configd_sim</string>
+       <key>MachServices</key>
+       <dict>
+               <key>com.apple.SystemConfiguration.configd_sim</key>
+               <true/>
+               <key>com.apple.SystemConfiguration.SCNetworkReachability_sim</key>
+               <true/>
+               <key>com.apple.SystemConfiguration.DNSConfiguration_sim</key>
+               <true/>
+               <key>com.apple.SystemConfiguration.NetworkInformation_sim</key>
+               <true/>
+       </dict>
+       <key>POSIXSpawnType</key>
+       <string>Interactive</string>
+       <key>ProgramArguments</key>
+       <array>
+               <string>/usr/libexec/configd_sim</string>
+               <string>-d</string>
+       </array>
+       <key>Umask</key>
+       <integer>18</integer>
+</dict>
+</plist>
index f697803fe94e9741ec68f7acb238026758dab4af..9006d7b9ffd7ceecb805508cd77b7380ca067883 100644 (file)
@@ -51,10 +51,10 @@ in the foreground without forking.  This is useful for debugging.
 .It Fl v
 Puts
 .Nm
 .It Fl v
 Puts
 .Nm
-into verbose mode.  Displays debugging information about 
+into verbose mode.  Displays debugging information about
 bundles as they are being loaded.
 .It Fl V Ar bundleID
 bundles as they are being loaded.
 .It Fl V Ar bundleID
-Turns verbose mode on for the bundle with the specified 
+Turns verbose mode on for the bundle with the specified
 .Ar bundleID .
 .It Fl t Ar bundle-path
 Loads only the bundle specified by
 .Ar bundleID .
 .It Fl t Ar bundle-path
 Loads only the bundle specified by
index 0a527297db532ac331af94e5379dda028376bb3d..852c41af6d9c4babc7c354ab295a368436a73e93 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -55,9 +55,9 @@
 #include "configd_server.h"
 #include "plugin_support.h"
 
 #include "configd_server.h"
 #include "plugin_support.h"
 
-#if    TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#if    TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 #include <CoreFoundation/CFUserNotification.h>
 #include <CoreFoundation/CFUserNotification.h>
-#endif // TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 
 __private_extern__
 Boolean        _configd_verbose                = FALSE;        /* TRUE if verbose logging enabled */
 
 __private_extern__
 Boolean        _configd_verbose                = FALSE;        /* TRUE if verbose logging enabled */
@@ -346,15 +346,17 @@ main(int argc, char * const argv[])
 //     argv += optind;
 
        /* check credentials */
 //     argv += optind;
 
        /* check credentials */
+#if    !TARGET_IPHONE_SIMULATOR
        if (getuid() != 0) {
                fprintf(stderr, "%s: permission denied.\n", prog);
                exit (EX_NOPERM);
        }
        if (getuid() != 0) {
                fprintf(stderr, "%s: permission denied.\n", prog);
                exit (EX_NOPERM);
        }
+#endif // !TARGET_IPHONE_SIMULATOR
 
        /* check if we have been started by launchd */
        vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &is_launchd_job);
 
 
        /* check if we have been started by launchd */
        vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &is_launchd_job);
 
-#if    TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#if    TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
        // if launchd job, check to see if we have been restarted
        if (is_launchd_job) {
                int64_t status  = 0;
        // if launchd job, check to see if we have been restarted
        if (is_launchd_job) {
                int64_t status  = 0;
@@ -379,7 +381,7 @@ main(int argc, char * const argv[])
                        }
                }
        }
                        }
                }
        }
-#endif // TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM)
+#endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM)
 
        /* ensure that forked plugins behave */
        if ((testBundle != NULL) && (getenv("__FORKED_PLUGIN__") != NULL)) {
 
        /* ensure that forked plugins behave */
        if ((testBundle != NULL) && (getenv("__FORKED_PLUGIN__") != NULL)) {
index 99240d50217ec84e06cb3b8d333216d637c2019f..bbbb9c1a63c3547fb244c43e6696e2d7c76000ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -34,6 +34,7 @@
  * - initial revision
  */
 
  * - initial revision
  */
 
+#include <TargetConditionals.h>
 #include <sysexits.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sysexits.h>
 #include <unistd.h>
 #include <sys/types.h>
 extern struct mig_subsystem    _config_subsystem;
 extern boolean_t               config_server(mach_msg_header_t *, mach_msg_header_t *);
 
 extern struct mig_subsystem    _config_subsystem;
 extern boolean_t               config_server(mach_msg_header_t *, mach_msg_header_t *);
 
-#include "shared_dns_info_types.h"
-#include "dnsinfo_server.h"
-
-/* MiG generated externals and functions */
-extern struct mig_subsystem    _shared_dns_info_subsystem;
-extern boolean_t               shared_dns_info_server(mach_msg_header_t *, mach_msg_header_t *);
-
 /* configd server port (for new session requests) */
 static CFMachPortRef           configd_port            = NULL;
 
 /* configd server port (for new session requests) */
 static CFMachPortRef           configd_port            = NULL;
 
@@ -72,14 +66,6 @@ config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
                return TRUE;
        }
 
                return TRUE;
        }
 
-       /*
-        * (attempt to) process DNS configuration requests.
-        */
-       processed = shared_dns_info_server(request, reply);
-       if (processed) {
-               return TRUE;
-       }
-
        /*
         * (attempt to) process (NO MORE SENDERS) notification messages.
         */
        /*
         * (attempt to) process (NO MORE SENDERS) notification messages.
         */
@@ -121,9 +107,6 @@ configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
        if (bufSize == 0) {
                // get max size for MiG reply buffers
                bufSize = _config_subsystem.maxsize;
        if (bufSize == 0) {
                // get max size for MiG reply buffers
                bufSize = _config_subsystem.maxsize;
-               if (_shared_dns_info_subsystem.maxsize > bufSize) {
-                       bufSize = _shared_dns_info_subsystem.maxsize;
-               }
 
                // check if our on-the-stack reply buffer will be big enough
                if (bufSize > sizeof(bufReply_q)) {
 
                // check if our on-the-stack reply buffer will be big enough
                if (bufSize > sizeof(bufReply_q)) {
@@ -240,7 +223,8 @@ server_init()
                        exit (EX_UNAVAILABLE);
                default :
                        SCLog(TRUE, LOG_ERR,
                        exit (EX_UNAVAILABLE);
                default :
                        SCLog(TRUE, LOG_ERR,
-                             CFSTR("server_init bootstrap_check_in() failed: %s"),
+                             CFSTR("server_init bootstrap_check_in(..., '%s', ...) failed: %s"),
+                             service_name,
                              bootstrap_strerror(status));
                        exit (EX_UNAVAILABLE);
        }
                              bootstrap_strerror(status));
                        exit (EX_UNAVAILABLE);
        }
@@ -268,7 +252,6 @@ server_shutdown()
        if (configd_port != NULL) {
                mach_port_t     service_port    = CFMachPortGetPort(configd_port);
 
        if (configd_port != NULL) {
                mach_port_t     service_port    = CFMachPortGetPort(configd_port);
 
-               CFMachPortSetInvalidationCallBack(configd_port, NULL);
                CFMachPortInvalidate(configd_port);
                CFRelease(configd_port);
                configd_port = NULL;
                CFMachPortInvalidate(configd_port);
                CFRelease(configd_port);
                configd_port = NULL;
index 5b7d736a8c2262e4e97743f6590a06848b265171..f3624c60529190e7579af091601da1ab77331c6d 100644 (file)
@@ -8,11 +8,20 @@
                <string>com.apple.certificates</string>
                <string>com.apple.identities</string>
        </array>
                <string>com.apple.certificates</string>
                <string>com.apple.identities</string>
        </array>
+       <key>com.apple.private.mobileinstall.allowedSPI</key>
+       <array>
+               <string>Uninstall</string>
+               <string>Lookup</string>
+       </array>
        <key>com.apple.springboard.launchapplications</key>
        <true/>
        <key>com.apple.multitasking.unlimitedassertions</key>
        <true/>
        <key>com.apple.wifi.manager-access</key>
        <true/>
        <key>com.apple.springboard.launchapplications</key>
        <true/>
        <key>com.apple.multitasking.unlimitedassertions</key>
        <true/>
        <key>com.apple.wifi.manager-access</key>
        <true/>
+       <key>com.apple.coretelephony.Identity.get</key>
+       <true/>
+       <key>com.apple.private.SCNetworkConnection-proxy-user</key>
+       <true/>
 </dict>
 </plist>
 </dict>
 </plist>
index f30790316790479c77629f2eac9a782b3edb977b..87bcbb1035360eb4bba70269d702c09b0e97856c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003, 2004, 2006-2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2003, 2004, 2006-2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -47,7 +47,7 @@
 
 typedef struct {
        CFMutableArrayRef       pInfo;
 
 typedef struct {
        CFMutableArrayRef       pInfo;
-       regex_t                 *preg;
+       CFDataRef               pRegex;
 } addContext, *addContextRef;
 
 
 } addContext, *addContextRef;
 
 
@@ -67,39 +67,33 @@ my_CFDictionaryApplyFunction(CFDictionaryRef                        theDict,
 }
 
 
 }
 
 
-static void
-identifyKeyForPattern(const void *key, void *val, void *context)
+static Boolean
+keyMatchesPattern(CFStringRef key, CFDataRef pRegex)
 {
 {
-       CFStringRef             storeKey        = (CFStringRef)key;
-       CFDictionaryRef         storeValue      = (CFDictionaryRef)val;
-       CFMutableArrayRef       pInfo           = ((addContextRef)context)->pInfo;
-       regex_t *               preg            = ((addContextRef)context)->preg;
-
        CFIndex                 len;
        CFIndex                 len;
+       Boolean                 match           = FALSE;
+       regex_t                 *preg;
        int                     reError;
        char                    str_q[256];
        char *                  str             = str_q;
 
        int                     reError;
        char                    str_q[256];
        char *                  str             = str_q;
 
-       if (!CFDictionaryContainsKey(storeValue, kSCDData)) {
-               /* if no data (yet) */
-               return;
-       }
-
        /* convert store key to C string */
        /* convert store key to C string */
-       len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(storeKey), kCFStringEncodingASCII) + 1;
+       len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), kCFStringEncodingASCII) + 1;
        if (len > (CFIndex)sizeof(str_q))
                str = CFAllocatorAllocate(NULL, len, 0);
        if (len > (CFIndex)sizeof(str_q))
                str = CFAllocatorAllocate(NULL, len, 0);
-       if (_SC_cfstring_to_cstring(storeKey, str, len, kCFStringEncodingASCII) == NULL) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("identifyKeyForPattern(): could not convert store key to C string"));
+       if (_SC_cfstring_to_cstring(key, str, len, kCFStringEncodingASCII) == NULL) {
+               SCLog(TRUE, LOG_DEBUG, CFSTR("keyMatchesPattern(): could not convert store key to C string"));
                goto done;
        }
 
                goto done;
        }
 
-       /* compare store key to new notification keys regular expression pattern */
+       /* ALIGN: CF aligns to >8 byte boundries */
+       preg = (regex_t *)(void *)CFDataGetBytePtr(pRegex);
+
+       /* compare key to regular expression pattern */
        reError = regexec(preg, str, 0, NULL, 0);
        switch (reError) {
                case 0 :
        reError = regexec(preg, str, 0, NULL, 0);
        switch (reError) {
                case 0 :
-                       /* we've got a match */
-                       CFArrayAppendValue(pInfo, storeKey);
+                       match = TRUE;
                        break;
                case REG_NOMATCH :
                        /* no match */
                        break;
                case REG_NOMATCH :
                        /* no match */
@@ -108,7 +102,7 @@ identifyKeyForPattern(const void *key, void *val, void *context)
                        char    reErrBuf[256];
 
                        (void)regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
                        char    reErrBuf[256];
 
                        (void)regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("identifyKeyForPattern regexec(): %s"), reErrBuf);
+                       SCLog(TRUE, LOG_DEBUG, CFSTR("keyMatchesPattern regexec(): %s"), reErrBuf);
                        break;
                }
        }
                        break;
                }
        }
@@ -116,12 +110,34 @@ identifyKeyForPattern(const void *key, void *val, void *context)
     done :
 
        if (str != str_q) CFAllocatorDeallocate(NULL, str);
     done :
 
        if (str != str_q) CFAllocatorDeallocate(NULL, str);
+       return match;
+}
+
+
+static void
+identifyKeyForPattern(const void *key, void *val, void *context)
+{
+       CFStringRef             storeKey        = (CFStringRef)key;
+       CFDictionaryRef         storeValue      = (CFDictionaryRef)val;
+       CFMutableArrayRef       pInfo           = ((addContextRef)context)->pInfo;
+       CFDataRef               pRegex          = ((addContextRef)context)->pRegex;
+
+       if (!CFDictionaryContainsKey(storeValue, kSCDData)) {
+               /* if no data (yet) */
+               return;
+       }
+
+       if (keyMatchesPattern(storeKey, pRegex)) {
+               /* if we've got a match */
+               CFArrayAppendValue(pInfo, storeKey);
+       }
+
        return;
 }
 
 
 static Boolean
        return;
 }
 
 
 static Boolean
-patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error)
+patternCompile(CFStringRef pattern, CFDataRef pRegex, CFStringRef *error)
 {
        Boolean         append          = FALSE;
        Boolean         insert          = FALSE;
 {
        Boolean         append          = FALSE;
        Boolean         insert          = FALSE;
@@ -174,8 +190,12 @@ patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error)
                CFRelease(pattern);
        }
        if (ok) {
                CFRelease(pattern);
        }
        if (ok) {
+               regex_t *preg;
                int     reError;
 
                int     reError;
 
+               /* ALIGN: CF aligns to >8 byte boundries */
+               preg = (regex_t *)(void *)CFDataGetBytePtr(pRegex);
+
                reError = regcomp(preg, str, REG_EXTENDED);
                if (reError != 0) {
                        char    reErrBuf[256];
                reError = regcomp(preg, str, REG_EXTENDED);
                if (reError != 0) {
                        char    reErrBuf[256];
@@ -199,13 +219,26 @@ patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error)
 }
 
 
 }
 
 
+static void
+patternRelease(CFDataRef pRegex)
+{
+       regex_t         *preg;
+
+       /* ALIGN: CF aligns to >8 byte boundries */
+       preg = (regex_t *)(void *)CFDataGetBytePtr(pRegex);
+       regfree(preg);
+
+       return;
+}
+
+
 static CF_RETURNS_RETAINED CFMutableArrayRef
 patternCopy(CFStringRef        pattern)
 {
        CFArrayRef      pInfo;
 
        pInfo = CFDictionaryGetValue(patternData, pattern);
 static CF_RETURNS_RETAINED CFMutableArrayRef
 patternCopy(CFStringRef        pattern)
 {
        CFArrayRef      pInfo;
 
        pInfo = CFDictionaryGetValue(patternData, pattern);
-       return pInfo ? CFArrayCreateMutableCopy(NULL, 0, pInfo) : NULL;
+       return (pInfo != NULL) ? CFArrayCreateMutableCopy(NULL, 0, pInfo) : NULL;
 }
 
 
 }
 
 
@@ -224,8 +257,7 @@ patternNew(CFStringRef pattern)
        /* compile the regular expression from the pattern string. */
        pRegex = CFDataCreateMutable(NULL, sizeof(regex_t));
        CFDataSetLength(pRegex, sizeof(regex_t));
        /* compile the regular expression from the pattern string. */
        pRegex = CFDataCreateMutable(NULL, sizeof(regex_t));
        CFDataSetLength(pRegex, sizeof(regex_t));
-       /* ALIGN: CF aligns to >8 byte boundries */
-       if (!patternCompile(pattern, (regex_t *)(void *)CFDataGetBytePtr(pRegex), &err)) {
+       if (!patternCompile(pattern, pRegex, &err)) {
                CFRelease(err);
                CFRelease(pRegex);
                CFRelease(pInfo);
                CFRelease(err);
                CFRelease(pRegex);
                CFRelease(pInfo);
@@ -241,9 +273,8 @@ patternNew(CFStringRef pattern)
        CFRelease(pSessions);
 
        /* identify/add all existing keys that match the specified pattern */
        CFRelease(pSessions);
 
        /* identify/add all existing keys that match the specified pattern */
-       context.pInfo = pInfo;
-       /* ALIGN: CF aligns to >8 byte boundries */
-       context.preg  = (regex_t *)(void *)CFDataGetBytePtr(pRegex);
+       context.pInfo  = pInfo;
+       context.pRegex = pRegex;
        my_CFDictionaryApplyFunction(storeData,
                                     (CFDictionaryApplierFunction)identifyKeyForPattern,
                                     &context);
        my_CFDictionaryApplyFunction(storeData,
                                     (CFDictionaryApplierFunction)identifyKeyForPattern,
                                     &context);
@@ -277,8 +308,7 @@ patternCopyMatches(CFStringRef pattern)
                CFDataRef       pRegex;
 
                pRegex = CFArrayGetValueAtIndex(pInfo, 0);
                CFDataRef       pRegex;
 
                pRegex = CFArrayGetValueAtIndex(pInfo, 0);
-               /* ALIGN: CF aligns to >8 byte boundries */
-               regfree((regex_t *)(void *)CFDataGetBytePtr(pRegex));
+               patternRelease(pRegex);
        }
 
        CFArrayReplaceValues(pInfo, CFRangeMake(0, 2), NULL, 0);
        }
 
        CFArrayReplaceValues(pInfo, CFRangeMake(0, 2), NULL, 0);
@@ -289,6 +319,52 @@ patternCopyMatches(CFStringRef pattern)
 }
 
 
 }
 
 
+__private_extern__
+Boolean
+patternKeyMatches(CFStringRef pattern, CFStringRef key)
+{
+       Boolean                 isNew   = FALSE;
+       Boolean                 match   = FALSE;
+       CFMutableArrayRef       pInfo;
+       CFDataRef               pRegex;
+
+       /* find (or create new instance of) this pattern */
+       pInfo = patternCopy(pattern);
+       if (pInfo != NULL) {
+               CFIndex         n;
+
+               /* if existing pattern, check if known key */
+               n = CFArrayGetCount(pInfo);
+               match = (n > 2) &&
+                       CFArrayContainsValue(pInfo, CFRangeMake(2, n - 2), key);
+               if (match) {
+                       goto done;
+               }
+       } else {
+               /* if new pattern */
+               pInfo = patternNew(pattern);
+               if (pInfo == NULL) {
+                       return FALSE;
+               }
+
+               isNew = TRUE;
+       }
+
+       pRegex = CFArrayGetValueAtIndex(pInfo, 0);
+       match = keyMatchesPattern(key, pRegex);
+
+       if (isNew) {
+               patternRelease(pRegex);
+       }
+
+    done :
+
+       CFRelease(pInfo);
+
+       return match;
+}
+
+
 __private_extern__
 Boolean
 patternAddSession(CFStringRef pattern, CFNumberRef sessionNum)
 __private_extern__
 Boolean
 patternAddSession(CFStringRef pattern, CFNumberRef sessionNum)
@@ -344,6 +420,7 @@ patternRemoveSession(CFStringRef pattern, CFNumberRef sessionNum)
 
        /* find instance of this pattern */
        pInfo = patternCopy(pattern);
 
        /* find instance of this pattern */
        pInfo = patternCopy(pattern);
+       assert(pInfo != NULL);
 
        /* remove this session as a watcher from all matching keys */
        n = CFArrayGetCount(pInfo);
 
        /* remove this session as a watcher from all matching keys */
        n = CFArrayGetCount(pInfo);
@@ -371,8 +448,7 @@ patternRemoveSession(CFStringRef pattern, CFNumberRef sessionNum)
                /* if no other sessions are watching this pattern */
 
                pRegex = CFArrayGetValueAtIndex(pInfo, 0);
                /* if no other sessions are watching this pattern */
 
                pRegex = CFArrayGetValueAtIndex(pInfo, 0);
-               /* ALIGN: CF aligns to >8 byte boundries */
-               regfree((regex_t *)(void *)CFDataGetBytePtr(pRegex));
+               patternRelease(pRegex);
                CFDictionaryRemoveValue(patternData, pattern);
        }
 
                CFDictionaryRemoveValue(patternData, pattern);
        }
 
index 417fedc7e68c6e18ffd1ead7f2fff557b8d88a49..4798b8acc44438507496ba6817240fb484dd6192 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003, 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2003, 2007, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -38,6 +38,9 @@ __BEGIN_DECLS
 
 CFArrayRef             patternCopyMatches      (CFStringRef            pattern);
 
 
 CFArrayRef             patternCopyMatches      (CFStringRef            pattern);
 
+Boolean                        patternKeyMatches       (CFStringRef            pattern,
+                                                CFStringRef            key);
+
 Boolean                        patternAddSession       (CFStringRef            pattern,
                                                 CFNumberRef            sessionNum);
 
 Boolean                        patternAddSession       (CFStringRef            pattern,
                                                 CFNumberRef            sessionNum);
 
index 309631d5bb18b6a81cb3b7950ee9964dac52aad1..90a85ccb5baecc70680feb6344d07b1a309678b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2009, 2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -61,19 +61,17 @@ void        _SCDPluginExecInit();
 
 
 #define PLUGIN_ALL(p)          CFSTR(p)
 
 
 #define PLUGIN_ALL(p)          CFSTR(p)
-#if    !TARGET_OS_EMBEDDED
+#if    !TARGET_OS_IPHONE
 #define PLUGIN_MACOSX(p)       CFSTR(p)
 #define PLUGIN_IOS(p)          NULL
 #define PLUGIN_MACOSX(p)       CFSTR(p)
 #define PLUGIN_IOS(p)          NULL
-#else  // !TARGET_OS_EMBEDDED
+#else  // !TARGET_OS_IPHONE
 #define PLUGIN_MACOSX(p)       NULL
 #define PLUGIN_IOS(p)          CFSTR(p)
 #define PLUGIN_MACOSX(p)       NULL
 #define PLUGIN_IOS(p)          CFSTR(p)
-#endif // !TARGET_OS_EMBEDDED
+#endif // !TARGET_OS_IPHONE
 
 // white-listed (ok-to-load) bundle identifiers
 static const CFStringRef       pluginWhitelist[]       = {
 
 // white-listed (ok-to-load) bundle identifiers
 static const CFStringRef       pluginWhitelist[]       = {
-       PLUGIN_MACOSX("com.apple.SystemConfiguration.Apple80211"),
        PLUGIN_MACOSX("com.apple.SystemConfiguration.ApplicationFirewall"),
        PLUGIN_MACOSX("com.apple.SystemConfiguration.ApplicationFirewall"),
-       PLUGIN_MACOSX("com.apple.SystemConfiguration.Bluetooth"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.EAPOLController"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.IPConfiguration"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.IPMonitor"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.EAPOLController"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.IPConfiguration"),
        PLUGIN_ALL   ("com.apple.SystemConfiguration.IPMonitor"),
@@ -86,7 +84,6 @@ static const CFStringRef      pluginWhitelist[]       = {
 #ifdef HAVE_REACHABILITY_SERVER
        PLUGIN_ALL   ("com.apple.SystemConfiguration.SCNetworkReachability"),
 #endif // HAVE_REACHABILITY_SERVER
 #ifdef HAVE_REACHABILITY_SERVER
        PLUGIN_ALL   ("com.apple.SystemConfiguration.SCNetworkReachability"),
 #endif // HAVE_REACHABILITY_SERVER
-       PLUGIN_MACOSX("com.apple.SystemConfiguration.wwanConfig"),
        PLUGIN_MACOSX("com.apple.print.notification"),
 };
 #define        N_PLUGIN_WHITELIST      (sizeof(pluginWhitelist) / sizeof(pluginWhitelist[0]))
        PLUGIN_MACOSX("com.apple.print.notification"),
 };
 #define        N_PLUGIN_WHITELIST      (sizeof(pluginWhitelist) / sizeof(pluginWhitelist[0]))
@@ -119,12 +116,14 @@ CFRunLoopRef                      plugin_runLoop          = NULL;
 
 extern SCDynamicStoreBundleLoadFunction                load_IPMonitor;
 extern SCDynamicStoreBundlePrimeFunction       prime_IPMonitor;
 
 extern SCDynamicStoreBundleLoadFunction                load_IPMonitor;
 extern SCDynamicStoreBundlePrimeFunction       prime_IPMonitor;
+#if    !TARGET_IPHONE_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;
 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
 #ifdef HAVE_REACHABILITY_SERVER
 extern SCDynamicStoreBundleLoadFunction                load_SCNetworkReachability;
 #endif // HAVE_REACHABILITY_SERVER
 #ifdef HAVE_REACHABILITY_SERVER
 extern SCDynamicStoreBundleLoadFunction                load_SCNetworkReachability;
 #endif // HAVE_REACHABILITY_SERVER
@@ -147,6 +146,7 @@ static const builtin builtin_plugins[] = {
                &prime_IPMonitor,
                NULL
        },
                &prime_IPMonitor,
                NULL
        },
+#if    !TARGET_IPHONE_SIMULATOR
        {
                CFSTR("com.apple.SystemConfiguration.InterfaceNamer"),
                &load_InterfaceNamer,
        {
                CFSTR("com.apple.SystemConfiguration.InterfaceNamer"),
                &load_InterfaceNamer,
@@ -175,6 +175,7 @@ static const builtin builtin_plugins[] = {
                &prime_PreferencesMonitor,
                NULL
        },
                &prime_PreferencesMonitor,
                NULL
        },
+#endif // !TARGET_IPHONE_SIMULATOR
 #ifdef HAVE_REACHABILITY_SERVER
        {
                CFSTR("com.apple.SystemConfiguration.SCNetworkReachability"),
 #ifdef HAVE_REACHABILITY_SERVER
        {
                CFSTR("com.apple.SystemConfiguration.SCNetworkReachability"),
@@ -853,15 +854,28 @@ timerCallback(CFRunLoopTimerRef timer, void *info)
 static void
 sortBundles(CFMutableArrayRef orig)
 {
 static void
 sortBundles(CFMutableArrayRef orig)
 {
+       CFIndex                 i;
+       CFIndex                 n;
        CFMutableArrayRef       new;
        CFMutableArrayRef       new;
+       CFMutableSetRef         orig_bundleIDs;
+
+       orig_bundleIDs = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+
+       n = CFArrayGetCount(orig);
+       for (i = 0; i < n; i++) {
+               bundleInfoRef   bundleInfo      = (bundleInfoRef)CFArrayGetValueAtIndex(orig, i);
+               CFStringRef     bundleID        = CFBundleGetIdentifier(bundleInfo->bundle);
+
+               if (bundleID != NULL) {
+                       CFSetAddValue(orig_bundleIDs, bundleID);
+               }
+       }
 
        new = CFArrayCreateMutable(NULL, 0, NULL);
 
        new = CFArrayCreateMutable(NULL, 0, NULL);
-       while (CFArrayGetCount(orig) > 0) {
-               int     i;
+       while (n > 0) {
                Boolean inserted        = FALSE;
                Boolean inserted        = FALSE;
-               int     nOrig           = CFArrayGetCount(orig);
 
 
-               for (i = 0; i < nOrig; i++) {
+               for (i = 0; i < n; i++) {
                        bundleInfoRef   bundleInfo1     = (bundleInfoRef)CFArrayGetValueAtIndex(orig, i);
                        CFStringRef     bundleID1       = CFBundleGetIdentifier(bundleInfo1->bundle);
                        int             count;
                        bundleInfoRef   bundleInfo1     = (bundleInfoRef)CFArrayGetValueAtIndex(orig, i);
                        CFStringRef     bundleID1       = CFBundleGetIdentifier(bundleInfo1->bundle);
                        int             count;
@@ -887,6 +901,12 @@ sortBundles(CFMutableArrayRef orig)
                                int             nNew;
                                CFStringRef     r       = CFArrayGetValueAtIndex(requires, j);
 
                                int             nNew;
                                CFStringRef     r       = CFArrayGetValueAtIndex(requires, j);
 
+                               if (!CFSetContainsValue(orig_bundleIDs, r)) {
+                                       // if dependency not present
+                                       count--;
+                                       continue;
+                               }
+
                                nNew = CFArrayGetCount(new);
                                for (k = 0; k < nNew; k++) {
                                        bundleInfoRef   bundleInfo2     = (bundleInfoRef)CFArrayGetValueAtIndex(new, k);
                                nNew = CFArrayGetCount(new);
                                for (k = 0; k < nNew; k++) {
                                        bundleInfoRef   bundleInfo2     = (bundleInfoRef)CFArrayGetValueAtIndex(new, k);
@@ -910,6 +930,8 @@ sortBundles(CFMutableArrayRef orig)
                        SCLog(TRUE, LOG_NOTICE, CFSTR("Bundles have circular dependency!!!"));
                        break;
                }
                        SCLog(TRUE, LOG_NOTICE, CFSTR("Bundles have circular dependency!!!"));
                        break;
                }
+
+               n = CFArrayGetCount(orig);
        }
        if (CFArrayGetCount(orig) > 0) {
                /* we have a circular dependency, append remaining items on new array */
        }
        if (CFArrayGetCount(orig) > 0) {
                /* we have a circular dependency, append remaining items on new array */
@@ -922,6 +944,7 @@ sortBundles(CFMutableArrayRef orig)
        CFArrayRemoveAllValues(orig);
        CFArrayAppendArray(orig, new, CFRangeMake(0, CFArrayGetCount(new)));
        CFRelease(new);
        CFArrayRemoveAllValues(orig);
        CFArrayAppendArray(orig, new, CFRangeMake(0, CFArrayGetCount(new)));
        CFRelease(new);
+       CFRelease(orig_bundleIDs);
        return;
 }
 
        return;
 }
 
@@ -972,9 +995,24 @@ plugin_exec(void *arg)
                        CFArrayRef      bundles;
                        CFURLRef        url;
 
                        CFArrayRef      bundles;
                        CFURLRef        url;
 
+#if    TARGET_IPHONE_SIMULATOR
+                       const char      *path_sim_prefix;
+
+                       path_sim_prefix = getenv("IPHONE_SIMULATOR_ROOT");
+                       if ((path_sim_prefix != NULL) && (strcmp(path_sim_prefix, ".") != 0)) {
+                               char    path_sim[MAXPATHLEN];
+
+                               strlcpy(path_sim, path_sim_prefix, sizeof(path_sim));
+                               strlcat(path_sim, path, sizeof(path_sim));
+                               strlcpy(path, path_sim, sizeof(path));
+                       } else {
+                               path[0] = '\0';
+                       }
+#endif // TARGET_IPHONE_SIMULATOR
+
                        /* load any available bundle */
                        strlcat(path, BUNDLE_DIRECTORY, sizeof(path));
                        /* load any available bundle */
                        strlcat(path, BUNDLE_DIRECTORY, sizeof(path));
-                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("searching for bundles in \".\""));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("searching for bundles in \"%s\""), path);
                        url = CFURLCreateFromFileSystemRepresentation(NULL,
                                                                      (UInt8 *)path,
                                                                      strlen(path),
                        url = CFURLCreateFromFileSystemRepresentation(NULL,
                                                                      (UInt8 *)path,
                                                                      strlen(path),
@@ -1048,12 +1086,12 @@ plugin_exec(void *arg)
         * Since xpcd calls getpwuid_r() during its initialization, it will
         * block until the platform UUID is available.
         */
         * Since xpcd calls getpwuid_r() during its initialization, it will
         * block until the platform UUID is available.
         */
-       for (int i = 0; i < CFArrayGetCount(allBundles); i++) {
+       for (i = 0; i < CFArrayGetCount(allBundles); i++) {
                bundleInfoRef   bi              = (bundleInfoRef)CFArrayGetValueAtIndex(allBundles, i);
                CFStringRef     bundleID        = CFBundleGetIdentifier(bi->bundle);
 
                if (_SC_CFEqual(bundleID,
                bundleInfoRef   bi              = (bundleInfoRef)CFArrayGetValueAtIndex(allBundles, i);
                CFStringRef     bundleID        = CFBundleGetIdentifier(bi->bundle);
 
                if (_SC_CFEqual(bundleID,
-                               CFSTR("com.apple.SystemConfiguration.InterfaceNamer")))
+                               CFSTR("com.apple.SystemConfiguration.InterfaceNamer")))
                {
                        CFArrayRemoveValueAtIndex(allBundles, i);
                        CFArrayInsertValueAtIndex(allBundles, 0, bi);
                {
                        CFArrayRemoveValueAtIndex(allBundles, i);
                        CFArrayInsertValueAtIndex(allBundles, 0, bi);
index cbb5b961c77a2df59e162b03a9934df8fbbff7e1..f6c88216bf9ad2f828e7eb61cb98f48598c37427 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * - initial revision
  */
 
  * - initial revision
  */
 
+#include <SystemConfiguration/SystemConfiguration.h>
 #include "configd.h"
 #include "configd_server.h"
 #include "configd.h"
 #include "configd_server.h"
+#include "pattern.h"
 #include "session.h"
 
 #include <unistd.h>
 #include "session.h"
 
 #include <unistd.h>
@@ -52,20 +54,6 @@ static CFRunLoopRef  sessionRunLoop  = NULL;
 static serverSessionRef        temp_session    = NULL;
 
 
 static serverSessionRef        temp_session    = NULL;
 
 
-static void
-CFMachPortInvalidateSessionCallback(CFMachPortRef port, void *info)
-{
-       CFRunLoopRef    currentRunLoop  = CFRunLoopGetCurrent();
-
-       // Bear trap
-       if (!_SC_CFEqual(currentRunLoop, sessionRunLoop)) {
-               _SC_crash("SCDynamicStore CFMachPort invalidation error",
-                          CFSTR("CFMachPort invalidated"),
-                          CFSTR("An SCDynamicStore CFMachPort has incorrectly been invalidated."));
-       }
-}
-
-
 __private_extern__
 serverSessionRef
 getSession(mach_port_t server)
 __private_extern__
 serverSessionRef
 getSession(mach_port_t server)
@@ -120,11 +108,17 @@ tempSession(mach_port_t server, CFStringRef name, audit_token_t auditToken)
                (void) __SCDynamicStoreOpen(&temp_session->store, NULL);
        });
 
                (void) __SCDynamicStoreOpen(&temp_session->store, NULL);
        });
 
-       /* save audit token */
-       temp_session->auditToken        = auditToken;
-       temp_session->callerEUID        = -1;           /* not "root" */
-       temp_session->callerRootAccess  = UNKNOWN;
-       temp_session->callerWriteAccess = UNKNOWN;
+       /* save audit token, caller entitlements */
+       temp_session->auditToken                = auditToken;
+       temp_session->callerEUID                = 1;            /* not "root" */
+       temp_session->callerRootAccess          = UNKNOWN;
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+       if ((temp_session->callerWriteEntitlement != NULL) &&
+           (temp_session->callerWriteEntitlement != kCFNull)) {
+               CFRelease(temp_session->callerWriteEntitlement);
+       }
+       temp_session->callerWriteEntitlement    = kCFNull;      /* UNKNOWN */
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
 
        /* save name */
        storePrivate = (SCDynamicStorePrivateRef)temp_session->store;
 
        /* save name */
        storePrivate = (SCDynamicStorePrivateRef)temp_session->store;
@@ -221,13 +215,6 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info))
                                                               configdCallback,
                                                               &context);
 
                                                               configdCallback,
                                                               &context);
 
-       //
-       // Set bear trap (an invalidation callback) to catch other
-       // threads stomping on us
-       //
-       CFMachPortSetInvalidationCallBack(sessions[n]->serverPort,
-                                         CFMachPortInvalidateSessionCallback);
-
        if (n > 0) {
                // insert send right that will be moved to the client
                (void) mach_port_insert_right(mach_task_self(),
        if (n > 0) {
                // insert send right that will be moved to the client
                (void) mach_port_insert_right(mach_task_self(),
@@ -236,12 +223,14 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info))
                                              MACH_MSG_TYPE_MAKE_SEND);
        }
 
                                              MACH_MSG_TYPE_MAKE_SEND);
        }
 
-       sessions[n]->key                 = mp;
-//     sessions[n]->serverRunLoopSource = NULL;
-//     sessions[n]->store               = NULL;
-       sessions[n]->callerEUID          = 1;           /* not "root" */
-       sessions[n]->callerRootAccess    = UNKNOWN;
-       sessions[n]->callerWriteAccess   = UNKNOWN;
+       sessions[n]->key                        = mp;
+//     sessions[n]->serverRunLoopSource        = NULL;
+//     sessions[n]->store                      = NULL;
+       sessions[n]->callerEUID                 = 1;            /* not "root" */
+       sessions[n]->callerRootAccess           = UNKNOWN;
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+       sessions[n]->callerWriteEntitlement     = kCFNull;      /* UNKNOWN */
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
 
        return sessions[n];
 }
 
        return sessions[n];
 }
@@ -284,6 +273,16 @@ cleanupSession(mach_port_t server)
                         */
                        (void) mach_port_mod_refs(mach_task_self(), server, MACH_PORT_RIGHT_RECEIVE, -1);
 
                         */
                        (void) mach_port_mod_refs(mach_task_self(), server, MACH_PORT_RIGHT_RECEIVE, -1);
 
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+                       /*
+                        * release any entitlement info
+                        */
+                       if ((thisSession->callerWriteEntitlement != NULL) &&
+                           (thisSession->callerWriteEntitlement != kCFNull)) {
+                               CFRelease(thisSession->callerWriteEntitlement);
+                       }
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+
                        /*
                         * We don't need any remaining information in the
                         * sessionData dictionary, remove it.
                        /*
                         * We don't need any remaining information in the
                         * sessionData dictionary, remove it.
@@ -374,7 +373,7 @@ listSessions(FILE *f)
 }
 
 
 }
 
 
-#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
 
 #include <Security/Security.h>
 #include <Security/SecTask.h>
 
 #include <Security/Security.h>
 #include <Security/SecTask.h>
@@ -397,66 +396,81 @@ sessionName(serverSessionRef session)
        return (name != NULL) ? name : CFSTR("???");
 }
 
        return (name != NULL) ? name : CFSTR("???");
 }
 
-
-static Boolean
-hasEntitlement(serverSessionRef session, CFStringRef entitlement)
+static CFTypeRef
+copyEntitlement(serverSessionRef session, CFStringRef entitlement)
 {
 {
-       Boolean         hasEntitlement  = FALSE;
        SecTaskRef      task;
        SecTaskRef      task;
+       CFTypeRef       value   = NULL;
 
 
-       /* Create the security task from the audit token. */
+       // Create the security task from the audit token
        task = SecTaskCreateWithAuditToken(NULL, session->auditToken);
        if (task != NULL) {
                CFErrorRef      error   = NULL;
        task = SecTaskCreateWithAuditToken(NULL, session->auditToken);
        if (task != NULL) {
                CFErrorRef      error   = NULL;
-               CFTypeRef       value;
 
 
-               /* Get the value for the entitlement. */
+               // Get the value for the entitlement
                value = SecTaskCopyValueForEntitlement(task, entitlement, &error);
                value = SecTaskCopyValueForEntitlement(task, entitlement, &error);
-               if (value != NULL) {
-                       if (isA_CFBoolean(value)) {
-                               if (CFBooleanGetValue(value)) {
-                                       /* if client DOES have entitlement */
-                                       hasEntitlement = TRUE;
-                               }
-                       } else {
+               if ((value == NULL) && (error != NULL)) {
+                       CFIndex         code    = CFErrorGetCode(error);
+                       CFStringRef     domain  = CFErrorGetDomain(error);
+
+                       if (!CFEqual(domain, kCFErrorDomainMach) ||
+                           ((code != kIOReturnInvalid) && (code != kIOReturnNotFound))) {
+                               // if unexpected error
                                SCLog(TRUE, LOG_ERR,
                                SCLog(TRUE, LOG_ERR,
-                                     CFSTR("hasEntitlement: entitlement not valid: %@"),
+                                     CFSTR("SecTaskCopyValueForEntitlement(,\"%@\",) failed, error = %@ : %@"),
+                                     entitlement,
+                                     error,
                                      sessionName(session));
                        }
                                      sessionName(session));
                        }
-
-                       CFRelease(value);
-               }
-               if (error != NULL) {
-                       SCLog(TRUE,
-                             (value == NULL) ? LOG_ERR : LOG_DEBUG,
-                             CFSTR("hasEntitlement SecTaskCopyValueForEntitlement() %s, error domain=%@, error code=%lx"),
-                             (value == NULL) ? "failed" : "warned",
-                             CFErrorGetDomain(error),
-                             CFErrorGetCode(error));
                        CFRelease(error);
                }
 
                CFRelease(task);
        } else {
                SCLog(TRUE, LOG_ERR,
                        CFRelease(error);
                }
 
                CFRelease(task);
        } else {
                SCLog(TRUE, LOG_ERR,
-                     CFSTR("hasEntitlement SecTaskCreateWithAuditToken() failed: %@"),
+                     CFSTR("SecTaskCreateWithAuditToken() failed: %@"),
                      sessionName(session));
        }
 
                      sessionName(session));
        }
 
-       return hasEntitlement;
+       return value;
 }
 
 }
 
-#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+
+
+static pid_t
+sessionPid(serverSessionRef session)
+{
+       pid_t   caller_pid;
+
+#if     (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+       caller_pid = audit_token_to_pid(session->auditToken);
+#else  // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+       audit_token_to_au32(session->auditToken,
+                           NULL,               // auidp
+                           NULL,               // euid
+                           NULL,               // egid
+                           NULL,               // ruid
+                           NULL,               // rgid
+                           &caller_pid,        // pid
+                           NULL,               // asid
+                           NULL);              // tid
+#endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+
+       return caller_pid;
+}
 
 
 __private_extern__
 Boolean
 hasRootAccess(serverSessionRef session)
 {
 
 
 __private_extern__
 Boolean
 hasRootAccess(serverSessionRef session)
 {
+#if    !TARGET_IPHONE_SIMULATOR
+
        if (session->callerRootAccess == UNKNOWN) {
        if (session->callerRootAccess == UNKNOWN) {
-               /*
-                * get the credentials associated with the caller.
-                */
+#if     (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+               session->callerEUID = audit_token_to_euid(session->auditToken);
+#else  // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
                audit_token_to_au32(session->auditToken,
                                    NULL,                       // auidp
                                    &session->callerEUID,       // euid
                audit_token_to_au32(session->auditToken,
                                    NULL,                       // auidp
                                    &session->callerEUID,       // euid
@@ -466,35 +480,127 @@ hasRootAccess(serverSessionRef session)
                                    NULL,                       // pid
                                    NULL,                       // asid
                                    NULL);                      // tid
                                    NULL,                       // pid
                                    NULL,                       // asid
                                    NULL);                      // tid
-
+#endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
                session->callerRootAccess = (session->callerEUID == 0) ? YES : NO;
        }
 
        return (session->callerRootAccess == YES) ? TRUE : FALSE;
                session->callerRootAccess = (session->callerEUID == 0) ? YES : NO;
        }
 
        return (session->callerRootAccess == YES) ? TRUE : FALSE;
+
+#else  // !TARGET_IPHONE_SIMULATOR
+
+       /*
+        * assume that all processes interacting with
+        * the iOS Simulator "configd" are OK.
+        */
+       return TRUE;
+
+#endif // !TARGET_IPHONE_SIMULATOR
 }
 
 
 __private_extern__
 Boolean
 }
 
 
 __private_extern__
 Boolean
-hasWriteAccess(serverSessionRef session)
+hasWriteAccess(serverSessionRef session, CFStringRef key)
 {
 {
-       if (session->callerWriteAccess == UNKNOWN) {
-               /* assume that the client DOES NOT have the entitlement */
-               session->callerWriteAccess = NO;
+       Boolean isSetup;
 
 
-               if (hasRootAccess(session)) {
-                       // grant write access to eUID==0 processes
-                       session->callerWriteAccess = YES;
+       // need to special case writing "Setup:" keys
+       isSetup = CFStringHasPrefix(key, kSCDynamicStoreDomainSetup);
+
+       if (hasRootAccess(session)) {
+               pid_t   pid;
+
+               // grant write access to eUID==0 processes
+
+               pid = sessionPid(session);
+               if (isSetup && (pid != getpid())) {
+                       /*
+                        * WAIT!!!
+                        *
+                        * This is NOT configd (or a plugin) trying to
+                        * write to an SCDynamicStore "Setup:" key.  In
+                        * general, this is unwise and we should at the
+                        * very least complain.
+                        */
+                       SCLog(TRUE, LOG_ERR,
+                             CFSTR("*** Non-configd process (pid=%d) attempting to modify \"%@\" ***"),
+                             pid,
+                             key);
                }
                }
-#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
-               else if (hasEntitlement(session, kSCWriteEntitlementName)) {
-                       // grant write access to "entitled" processes
-                       session->callerWriteAccess = YES;
+
+               return TRUE;
+       }
+
+       if (isSetup) {
+               /*
+                * STOP!!!
+                *
+                * This is a non-root process trying to write to
+                * an SCDynamicStore "Setup:" key.  This is not
+                * something we should ever allow (regardless of
+                * any entitlements).
+                */
+               SCLog(TRUE, LOG_ERR,
+                     CFSTR("*** Non-root process (pid=%d) attempting to modify \"%@\" ***"),
+                     sessionPid(session),
+                     key);
+
+               //return FALSE;         // return FALSE when rdar://9811832 has beed fixed
+       }
+
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+       if (session->callerWriteEntitlement == kCFNull) {
+               session->callerWriteEntitlement = copyEntitlement(session,
+                                                                 kSCWriteEntitlementName);
+       }
+
+       if (session->callerWriteEntitlement == NULL) {
+               return FALSE;
+       }
+
+       if (isA_CFBoolean(session->callerWriteEntitlement) &&
+           CFBooleanGetValue(session->callerWriteEntitlement)) {
+               // grant write access to "entitled" processes
+               return TRUE;
+       }
+
+       if (isA_CFDictionary(session->callerWriteEntitlement)) {
+               CFArrayRef      keys;
+               CFArrayRef      patterns;
+
+               keys = CFDictionaryGetValue(session->callerWriteEntitlement, CFSTR("keys"));
+               if (isA_CFArray(keys)) {
+                       if (CFArrayContainsValue(keys,
+                                                CFRangeMake(0, CFArrayGetCount(keys)),
+                                                key)) {
+                               // if key matches one of the entitlement "keys", grant
+                               // write access
+                               return TRUE;
+                       }
+               }
+
+               patterns = CFDictionaryGetValue(session->callerWriteEntitlement, CFSTR("patterns"));
+               if (isA_CFArray(patterns)) {
+                       CFIndex         i;
+                       CFIndex         n       = CFArrayGetCount(patterns);
+
+                       for (i = 0; i < n; i++) {
+                               CFStringRef     pattern;
+
+                               pattern = CFArrayGetValueAtIndex(patterns, i);
+                               if (isA_CFString(pattern)) {
+                                       if (patternKeyMatches(pattern, key)) {
+                                               // if key matches one of the entitlement
+                                               // "patterns", grant write access
+                                               return TRUE;
+                                       }
+                               }
+                       }
                }
                }
-#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
        }
        }
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
 
 
-       return (session->callerWriteAccess == YES) ? TRUE : FALSE;
+       return FALSE;
 }
 
 
 }
 
 
@@ -510,6 +616,9 @@ hasPathAccess(serverSessionRef session, const char *path)
                return FALSE;
        }
 
                return FALSE;
        }
 
+#if    (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+       pid = audit_token_to_pid(session->auditToken);
+#else  // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
        audit_token_to_au32(session->auditToken,
                            NULL,               // auidp
                            NULL,               // euid
        audit_token_to_au32(session->auditToken,
                            NULL,               // auidp
                            NULL,               // euid
@@ -519,8 +628,11 @@ hasPathAccess(serverSessionRef session, const char *path)
                            &pid,               // pid
                            NULL,               // asid
                            NULL);              // tid
                            &pid,               // pid
                            NULL,               // asid
                            NULL);              // tid
-
-       if (sandbox_check(pid, "file-write-data", SANDBOX_FILTER_PATH, realPath) > 0) {
+#endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) && !TARGET_OS_IPHONE
+       if (sandbox_check(pid,                                                  // pid
+                         "file-write-data",                                    // operation
+                         SANDBOX_FILTER_PATH | SANDBOX_CHECK_NO_REPORT,        // sandbox_filter_type
+                         realPath) > 0) {                                      // ...
                SCLog(TRUE, LOG_DEBUG, CFSTR("hasPathAccess sandbox access denied: %s"), strerror(errno));
                return FALSE;
        }
                SCLog(TRUE, LOG_DEBUG, CFSTR("hasPathAccess sandbox access denied: %s"), strerror(errno));
                return FALSE;
        }
index 68d8f910ad322887126cff19259454f95a8d4dfd..ab4c4d62786e491e64164e35be3a55e756b2f5af 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2005-2007, 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2005-2007, 2009-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 
 #if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
 
 
 #if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+/*
+ * SCDynamicStore write access entitlement
+ *
+ *   Key   : "com.apple.SystemConfiguration.SCDynamicStore-write-access"
+ *   Value : Boolean
+ *             TRUE == allow SCDynamicStore write access for this process
+ *
+ *           Dictionary
+ *             Key   : "keys"
+ *             Value : <array> of CFString with write access allowed for
+ *                     each SCDynamicStore key matching the string(s)
+ *
+ *             Key   : "patterns"
+ *             Value : <array> of CFString with write access allowed for
+ *                     each SCDynamicStore key matching the regex pattern(s)
+ */
 #define        kSCWriteEntitlementName CFSTR("com.apple.SystemConfiguration.SCDynamicStore-write-access")
 #endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
 
 #define        kSCWriteEntitlementName CFSTR("com.apple.SystemConfiguration.SCDynamicStore-write-access")
 #endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
 
@@ -69,8 +85,18 @@ typedef struct {
        /* root access credential associated with this "open" session */
        lazyBoolean             callerRootAccess;
 
        /* root access credential associated with this "open" session */
        lazyBoolean             callerRootAccess;
 
-       /* write access entitlement associated with this "open" session */
-       lazyBoolean             callerWriteAccess;
+#if    TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
+       /*
+        * write access entitlement associated with this "open" session
+        *
+        *   kCFNull            caller entitlements unknown (need to fetch)
+        *   NULL               no entitlement
+        *   CFBoolean          true/false
+        *   CFDictionary       "keys"     = CFArray[writable keys]
+        *                      "patterns" = CFArray[writable patterns]
+        */
+       CFTypeRef               callerWriteEntitlement;
+#endif  // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/)
 
 } serverSession, *serverSessionRef;
 
 
 } serverSession, *serverSessionRef;
 
@@ -91,7 +117,8 @@ void                 listSessions    (FILE           *f);
 
 Boolean                        hasRootAccess   (serverSessionRef       session);
 
 
 Boolean                        hasRootAccess   (serverSessionRef       session);
 
-Boolean                        hasWriteAccess  (serverSessionRef       session);
+Boolean                        hasWriteAccess  (serverSessionRef       session,
+                                        CFStringRef            key);
 
 Boolean                        hasPathAccess   (serverSessionRef       session,
                                         const char             *path);
 
 Boolean                        hasPathAccess   (serverSessionRef       session,
                                         const char             *path);
index ebce9e4d5fefa75cf28bcd48047ddafcdfd94b9b..2fced37ca811fa11fedce78b55e9e474f33524a2 100644 (file)
                        );
                        dependencies = (
                                15A5A2710D5B942D0087BDA0 /* PBXTargetDependency */,
                        );
                        dependencies = (
                                15A5A2710D5B942D0087BDA0 /* PBXTargetDependency */,
+                               15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */,
+                               15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */,
+                               15AB752216EC005A00FAA8CE /* PBXTargetDependency */,
+                               15AB752416EC005A00FAA8CE /* PBXTargetDependency */,
+                               15D3083016F3EAD000014F82 /* PBXTargetDependency */,
+                               15D3083216F3EAD000014F82 /* PBXTargetDependency */,
+                               15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */,
+                               15E1B04016EBAB9400E5F06F /* PBXTargetDependency */,
                        );
                        name = "configd_base-EmbeddedSimulator";
                        productName = Frameworks;
                        );
                        name = "configd_base-EmbeddedSimulator";
                        productName = Frameworks;
                        name = configd_base;
                        productName = Frameworks;
                };
                        name = configd_base;
                        productName = Frameworks;
                };
+               157FDE3B164A075F0040D6A8 /* configd_libSystem-EmbeddedSimulator */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 157FDE3E164A075F0040D6A8 /* Build configuration list for PBXAggregateTarget "configd_libSystem-EmbeddedSimulator" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               15732AE616EA6BCE00F3AC4C /* PBXTargetDependency */,
+                       );
+                       name = "configd_libSystem-EmbeddedSimulator";
+                       productName = configd_libSystem;
+               };
                158316CF0CFB774B006F62B9 /* configd_base-Embedded */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 158316D80CFB774B006F62B9 /* Build configuration list for PBXAggregateTarget "configd_base-Embedded" */;
                158316CF0CFB774B006F62B9 /* configd_base-Embedded */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 158316D80CFB774B006F62B9 /* Build configuration list for PBXAggregateTarget "configd_base-Embedded" */;
                        name = "configd_executables-Embedded";
                        productName = configd_executables;
                };
                        name = "configd_executables-Embedded";
                        productName = configd_executables;
                };
-               1583E9E01083959E00A3BC0C /* All-EmbeddedOther */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 1583E9E91083959E00A3BC0C /* Build configuration list for PBXAggregateTarget "All-EmbeddedOther" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               15AC515810839608004A9ED5 /* PBXTargetDependency */,
-                               15AC515B1083960E004A9ED5 /* PBXTargetDependency */,
-                               15AC515D10839613004A9ED5 /* PBXTargetDependency */,
-                               15AC515F1083961E004A9ED5 /* PBXTargetDependency */,
-                       );
-                       name = "All-EmbeddedOther";
-                       productName = Embedded;
-               };
-               1583E9FD108395BB00A3BC0C /* configd_libSystem-EmbeddedOther */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 1583EA01108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_libSystem-EmbeddedOther" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               15AC516110839649004A9ED5 /* PBXTargetDependency */,
-                       );
-                       name = "configd_libSystem-EmbeddedOther";
-                       productName = configd_libSystem;
-               };
-               1583EA11108395BB00A3BC0C /* configd_base-EmbeddedOther */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 1583EA16108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_base-EmbeddedOther" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               15AC516310839666004A9ED5 /* PBXTargetDependency */,
-                               15AC51651083966B004A9ED5 /* PBXTargetDependency */,
-                       );
-                       name = "configd_base-EmbeddedOther";
-                       productName = Frameworks;
-               };
-               1583EAAC108395BB00A3BC0C /* configd_plugins-EmbeddedOther */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 1583EAC7108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_plugins-EmbeddedOther" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               15AC5185108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5183108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5189108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5187108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5181108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC517F108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC517D108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC517B108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5179108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5173108396D2004A9ED5 /* PBXTargetDependency */,
-                               15AC5171108396D2004A9ED5 /* PBXTargetDependency */,
-                               1528C0131357420300691881 /* PBXTargetDependency */,
-                               1528C0151357420300691881 /* PBXTargetDependency */,
-                       );
-                       name = "configd_plugins-EmbeddedOther";
-                       productName = Plugins;
-               };
-               1583EB41108395BD00A3BC0C /* configd_executables-EmbeddedOther */ = {
-                       isa = PBXAggregateTarget;
-                       buildConfigurationList = 1583EB48108395BD00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_executables-EmbeddedOther" */;
-                       buildPhases = (
-                       );
-                       dependencies = (
-                               15AC516E108396B7004A9ED5 /* PBXTargetDependency */,
-                               15AC516C108396B7004A9ED5 /* PBXTargetDependency */,
-                               15AC516A108396B7004A9ED5 /* PBXTargetDependency */,
-                       );
-                       name = "configd_executables-EmbeddedOther";
-                       productName = configd_executables;
-               };
                159D542007528E7C004F8947 /* configd_plugins */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 156EB61E0905594A00EEF749 /* Build configuration list for PBXAggregateTarget "configd_plugins" */;
                159D542007528E7C004F8947 /* configd_plugins */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 156EB61E0905594A00EEF749 /* Build configuration list for PBXAggregateTarget "configd_plugins" */;
                        name = All;
                        productName = "configd (Aggregate)";
                };
                        name = All;
                        productName = "configd (Aggregate)";
                };
+               15E83104167F9AF600FD51EC /* EVERYTHING */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 15E83107167F9AF600FD51EC /* Build configuration list for PBXAggregateTarget "EVERYTHING" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               15E83109167F9B0600FD51EC /* PBXTargetDependency */,
+                               15E8310B167F9B0C00FD51EC /* PBXTargetDependency */,
+                               15E8310D167F9B1200FD51EC /* PBXTargetDependency */,
+                       );
+                       name = EVERYTHING;
+                       productName = EVERYTHING;
+               };
                15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 15FD13C60D59485000F9409C /* Build configuration list for PBXAggregateTarget "All-EmbeddedSimulator" */;
                        buildPhases = (
                        );
                        dependencies = (
                15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = 15FD13C60D59485000F9409C /* Build configuration list for PBXAggregateTarget "All-EmbeddedSimulator" */;
                        buildPhases = (
                        );
                        dependencies = (
+                               157FDE44164A079B0040D6A8 /* PBXTargetDependency */,
                                151FE37A0D5B713C000D6DB1 /* PBXTargetDependency */,
                        );
                        name = "All-EmbeddedSimulator";
                                151FE37A0D5B713C000D6DB1 /* PBXTargetDependency */,
                        );
                        name = "All-EmbeddedSimulator";
 /* Begin PBXBuildFile section */
                15060818075A00A300B147BA /* SCSchemaDefinitions.c in Sources */ = {isa = PBXBuildFile; fileRef = 150607BD075A00A200B147BA /* SCSchemaDefinitions.c */; };
                1506081A075A00A300B147BA /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
 /* Begin PBXBuildFile section */
                15060818075A00A300B147BA /* SCSchemaDefinitions.c in Sources */ = {isa = PBXBuildFile; fileRef = 150607BD075A00A200B147BA /* SCSchemaDefinitions.c */; };
                1506081A075A00A300B147BA /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               150BEC1814CA24F900237116 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
+               150BEC1A14CA252200237116 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
                150D7E1E0D16DC6C00AF4BED /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                150D7E1E0D16DC6C00AF4BED /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
-               151E0CA31378EE1000C5DA2A /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               151E0CA51378EE3B00C5DA2A /* network_information.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A77136891300091C931 /* network_information.c */; };
                1520A3870846829A0010B584 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                1520A3DF0846B2DD0010B584 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                152140020E93EC6500DACD2C /* logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 1531D3DB0E93E6DA00248432 /* logger.c */; };
                1520A3870846829A0010B584 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                1520A3DF0846B2DD0010B584 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
                152140020E93EC6500DACD2C /* logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 1531D3DB0E93E6DA00248432 /* logger.c */; };
                1522FCFB0FA7FE4B00B24128 /* dnsinfo_flatfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */; };
                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                1522FCFB0FA7FE4B00B24128 /* dnsinfo_flatfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */; };
                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
-               152691DD1129EEB1006BD2D5 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                152691DF1129EEC8006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                152691DF1129EEC8006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
-               152691E01129EECB006BD2D5 /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; };
                1528BFEF135733F500691881 /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
                1528BFF313573FEE00691881 /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
                1528BFEF135733F500691881 /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
                1528BFF313573FEE00691881 /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
-               1528C0021357401900691881 /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
                1528C0171357465900691881 /* libSCNetworkReachability.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1528BFF713573FEE00691881 /* libSCNetworkReachability.a */; };
                1528C019135746BB00691881 /* libSCNetworkReachability.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1528BFE21357305400691881 /* libSCNetworkReachability.a */; };
                1528C0171357465900691881 /* libSCNetworkReachability.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1528BFF713573FEE00691881 /* libSCNetworkReachability.a */; };
                1528C019135746BB00691881 /* libSCNetworkReachability.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1528BFE21357305400691881 /* libSCNetworkReachability.a */; };
-               1528C01A135746D700691881 /* libSCNetworkReachability.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1528C0061357401900691881 /* libSCNetworkReachability.a */; };
                152E0E7F10FE820E00E402F2 /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                152E0E8010FE820E00E402F2 /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                152E0E7F10FE820E00E402F2 /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                152E0E8010FE820E00E402F2 /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-               152E0E8110FE820E00E402F2 /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                152E0E8910FE824000E402F2 /* helper_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E0E8810FE824000E402F2 /* helper_types.h */; };
                152E0E8A10FE824000E402F2 /* helper_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E0E8810FE824000E402F2 /* helper_types.h */; };
                152E0E8910FE824000E402F2 /* helper_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E0E8810FE824000E402F2 /* helper_types.h */; };
                152E0E8A10FE824000E402F2 /* helper_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E0E8810FE824000E402F2 /* helper_types.h */; };
-               152E0E8B10FE824000E402F2 /* helper_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E0E8810FE824000E402F2 /* helper_types.h */; };
                152E68C10A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E68C00A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                152E68C30A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 152E68C20A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c */; };
                152E68C10A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E68C00A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                152E68C30A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 152E68C20A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c */; };
+               153338BC14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */; };
+               153338BD14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */; };
+               153338BF14BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */; };
+               153338C014BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */; };
+               153ACCA814E322D5005029A5 /* network_information_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 153ACCA614E322D5005029A5 /* network_information_server.c */; };
+               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 */; };
                154361E00752C81800A8EC6C /* set-hostname.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AB07528B36004F8947 /* set-hostname.c */; };
                1543636B0752D03C00A8EC6C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                1540E3610987DA9500157C07 /* com.apple.configd.plist in CopyFiles */ = {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 */; };
                156CA47F0EF853BB00C59A18 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                1572C4A90CFB55B400E2776E /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
                1572C4AA0CFB55B400E2776E /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                156CA47F0EF853BB00C59A18 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                1572C4A90CFB55B400E2776E /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
                1572C4AA0CFB55B400E2776E /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1572C4AB0CFB55B400E2776E /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               1572C4AB0CFB55B400E2776E /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                1572C4AC0CFB55B400E2776E /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1572C4AD0CFB55B400E2776E /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                1572C4AE0CFB55B400E2776E /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4AC0CFB55B400E2776E /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1572C4AD0CFB55B400E2776E /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                1572C4AE0CFB55B400E2776E /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1572C4AF0CFB55B400E2776E /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               1572C4AF0CFB55B400E2776E /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                1572C4B00CFB55B400E2776E /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B10CFB55B400E2776E /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B00CFB55B400E2776E /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B10CFB55B400E2776E /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1572C4B20CFB55B400E2776E /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1572C4B30CFB55B400E2776E /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               1572C4B20CFB55B400E2776E /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
+               1572C4B30CFB55B400E2776E /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                1572C4B40CFB55B400E2776E /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                1572C4B50CFB55B400E2776E /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B40CFB55B400E2776E /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                1572C4B50CFB55B400E2776E /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1572C4B60CFB55B400E2776E /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               1572C4B60CFB55B400E2776E /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                1572C4B70CFB55B400E2776E /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B80CFB55B400E2776E /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B90CFB55B400E2776E /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                1572C4B70CFB55B400E2776E /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B80CFB55B400E2776E /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4B90CFB55B400E2776E /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                1572C4BB0CFB55B400E2776E /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4BC0CFB55B400E2776E /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4BD0CFB55B400E2776E /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4BB0CFB55B400E2776E /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4BC0CFB55B400E2776E /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                1572C4BD0CFB55B400E2776E /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1572C4BE0CFB55B400E2776E /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               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 */; };
                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 */; };
                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, ); }; };
                1572C5150CFB55B400E2776E /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
                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, ); }; };
                1572C5150CFB55B400E2776E /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
-               1572C5180CFB55B400E2776E /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                1572C5190CFB55B400E2776E /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                1572C51A0CFB55B400E2776E /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; };
                1572C51B0CFB55B400E2776E /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; };
                1572C5190CFB55B400E2776E /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                1572C51A0CFB55B400E2776E /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; };
                1572C51B0CFB55B400E2776E /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; };
                1572C5210CFB55B400E2776E /* SCPreferencesKeychainPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 152E68C20A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c */; };
                1572C5220CFB55B400E2776E /* SCNetworkSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */; };
                1572C5240CFB55B400E2776E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                1572C5210CFB55B400E2776E /* SCPreferencesKeychainPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 152E68C20A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c */; };
                1572C5220CFB55B400E2776E /* SCNetworkSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */; };
                1572C5240CFB55B400E2776E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
+               1572C57F171CCFE200870549 /* pppcontroller_mach_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */; };
+               1572C580171CCFF000870549 /* pppcontroller_mach_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */; };
+               1572C581171CD00E00870549 /* pppcontroller_mach_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */; };
                1572EB7B0A506D3B00D02459 /* smb-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1572EB7A0A506D3B00D02459 /* smb-configuration.c */; };
                1572EB7B0A506D3B00D02459 /* smb-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1572EB7A0A506D3B00D02459 /* smb-configuration.c */; };
+               15732A7816EA503200F3AC4C /* configd.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69CF05C0722B0099E85F /* configd.h */; };
+               15732A7916EA503200F3AC4C /* _SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D105C0722B0099E85F /* _SCD.h */; };
+               15732A7A16EA503200F3AC4C /* configd_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D305C0722B0099E85F /* configd_server.h */; };
+               15732A7B16EA503200F3AC4C /* notify_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D505C0722B0099E85F /* notify_server.h */; };
+               15732A7C16EA503200F3AC4C /* plugin_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D705C0722B0099E85F /* plugin_support.h */; };
+               15732A7D16EA503200F3AC4C /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D905C0722B0099E85F /* session.h */; };
+               15732A7E16EA503200F3AC4C /* pattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69DB05C0722B0099E85F /* pattern.h */; };
+               15732A8016EA503200F3AC4C /* configd.m in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E005C0722B0099E85F /* configd.m */; settings = {ATTRIBUTES = (); }; };
+               15732A8116EA503200F3AC4C /* _SCD.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E205C0722B0099E85F /* _SCD.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8216EA503200F3AC4C /* configd_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E405C0722B0099E85F /* configd_server.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8316EA503200F3AC4C /* notify_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E605C0722B0099E85F /* notify_server.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8416EA503200F3AC4C /* plugin_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E805C0722B0099E85F /* plugin_support.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8516EA503200F3AC4C /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69EA05C0722B0099E85F /* session.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8616EA503200F3AC4C /* pattern.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69EC05C0722B0099E85F /* pattern.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8716EA503200F3AC4C /* _configopen.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F005C0722B0099E85F /* _configopen.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8816EA503200F3AC4C /* _configclose.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F205C0722B0099E85F /* _configclose.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8916EA503200F3AC4C /* _configunlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F605C0722B0099E85F /* _configunlock.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8A16EA503200F3AC4C /* _configlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F805C0722B0099E85F /* _configlist.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8B16EA503200F3AC4C /* _configadd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69FA05C0722B0099E85F /* _configadd.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8C16EA503200F3AC4C /* _configget.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69FE05C0722B0099E85F /* _configget.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8D16EA503200F3AC4C /* _configset.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0005C0722B0099E85F /* _configset.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8E16EA503200F3AC4C /* _configremove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0205C0722B0099E85F /* _configremove.c */; settings = {ATTRIBUTES = (); }; };
+               15732A8F16EA503200F3AC4C /* _confignotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0605C0722B0099E85F /* _confignotify.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9016EA503200F3AC4C /* _notifyadd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0805C0722B0099E85F /* _notifyadd.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9116EA503200F3AC4C /* _notifyremove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0A05C0722B0099E85F /* _notifyremove.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9216EA503200F3AC4C /* _notifychanges.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0C05C0722B0099E85F /* _notifychanges.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9316EA503200F3AC4C /* _notifyviaport.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0E05C0722B0099E85F /* _notifyviaport.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9416EA503200F3AC4C /* _notifyviafd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1005C0722B0099E85F /* _notifyviafd.c */; settings = {ATTRIBUTES = (); }; };
+               15732A9516EA503200F3AC4C /* _notifyviasignal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1205C0722B0099E85F /* _notifyviasignal.c */; settings = {ATTRIBUTES = (); }; };
+               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 */; };
+               15732A9A16EA503200F3AC4C /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_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 */; };
+               15732A9F16EA503200F3AC4C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
+               15732AA016EA503200F3AC4C /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
+               15732AAF16EA511900F3AC4C /* scutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4305C0722B0099E85F /* scutil.h */; };
+               15732AB016EA511900F3AC4C /* commands.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4505C0722B0099E85F /* commands.h */; };
+               15732AB116EA511900F3AC4C /* dictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4705C0722B0099E85F /* dictionary.h */; };
+               15732AB216EA511900F3AC4C /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4905C0722B0099E85F /* session.h */; };
+               15732AB316EA511900F3AC4C /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4B05C0722B0099E85F /* cache.h */; };
+               15732AB416EA511900F3AC4C /* notifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4D05C0722B0099E85F /* notifications.h */; };
+               15732AB516EA511900F3AC4C /* tests.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4F05C0722B0099E85F /* tests.h */; };
+               15732AB616EA511900F3AC4C /* prefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A5105C0722B0099E85F /* prefs.h */; };
+               15732AB716EA511900F3AC4C /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A509A406C2518F001F0AB7 /* net.h */; };
+               15732AB816EA511900F3AC4C /* net_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC34680711D49400A3311C /* net_interface.h */; };
+               15732AB916EA511900F3AC4C /* net_protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346A0711D49400A3311C /* net_protocol.h */; };
+               15732ABA16EA511900F3AC4C /* net_service.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346C0711D49400A3311C /* net_service.h */; };
+               15732ABB16EA511900F3AC4C /* net_set.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346E0711D49400A3311C /* net_set.h */; };
+               15732ABC16EA511900F3AC4C /* nc.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B43726113C7BFC00EBF1B6 /* nc.h */; };
+               15732ABE16EA511900F3AC4C /* scutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5405C0722B0099E85F /* scutil.c */; settings = {ATTRIBUTES = (); }; };
+               15732ABF16EA511900F3AC4C /* commands.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5605C0722B0099E85F /* commands.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC016EA511900F3AC4C /* dictionary.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5805C0722B0099E85F /* dictionary.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC116EA511900F3AC4C /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5A05C0722B0099E85F /* session.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC216EA511900F3AC4C /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5C05C0722B0099E85F /* cache.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC316EA511900F3AC4C /* notifications.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5E05C0722B0099E85F /* notifications.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC416EA511900F3AC4C /* tests.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A6005C0722B0099E85F /* tests.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC516EA511900F3AC4C /* prefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A6205C0722B0099E85F /* prefs.c */; settings = {ATTRIBUTES = (); }; };
+               15732AC616EA511900F3AC4C /* net.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A509A306C2518F001F0AB7 /* net.c */; };
+               15732AC716EA511900F3AC4C /* net_interface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC34670711D49400A3311C /* net_interface.c */; };
+               15732AC816EA511900F3AC4C /* net_protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC34690711D49400A3311C /* net_protocol.c */; };
+               15732AC916EA511900F3AC4C /* net_service.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC346B0711D49400A3311C /* net_service.c */; };
+               15732ACA16EA511900F3AC4C /* net_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC346D0711D49400A3311C /* net_set.c */; };
+               15732ACB16EA511900F3AC4C /* nc.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B43727113C7BFC00EBF1B6 /* nc.c */; };
+               15732ACC16EA511900F3AC4C /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
+               15732ACE16EA511900F3AC4C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
+               15732ACF16EA511900F3AC4C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
+               15732AD016EA511900F3AC4C /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152CEED0070CF6640050F23C /* libedit.dylib */; };
+               15732AD816EA6B6700F3AC4C /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               15732AD916EA6B6700F3AC4C /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               15732ADA16EA6B6700F3AC4C /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
+               15732ADB16EA6B6700F3AC4C /* libSystemConfiguration_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */; };
+               15732ADD16EA6B6700F3AC4C /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
+               15732ADE16EA6B6700F3AC4C /* network_information.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A77136891300091C931 /* network_information.c */; };
+               15732ADF16EA6B6700F3AC4C /* libSystemConfiguration_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */; };
                157433E00D4A8122002ACA73 /* scselect.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A2E05C0722B0099E85F /* scselect.c */; settings = {ATTRIBUTES = (); }; };
                157433E20D4A8122002ACA73 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                157433E30D4A8122002ACA73 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
                157433E00D4A8122002ACA73 /* scselect.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A2E05C0722B0099E85F /* scselect.c */; settings = {ATTRIBUTES = (); }; };
                157433E20D4A8122002ACA73 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                157433E30D4A8122002ACA73 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
                1575FD2812CD15C60003D86E /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
                1575FD2912CD15C60003D86E /* proxy-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1575FD2512CD15C60003D86E /* proxy-configuration.c */; };
                1575FD2A12CD15C60003D86E /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
                1575FD2812CD15C60003D86E /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
                1575FD2912CD15C60003D86E /* proxy-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1575FD2512CD15C60003D86E /* proxy-configuration.c */; };
                1575FD2A12CD15C60003D86E /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
-               1575FD2B12CD15C60003D86E /* proxy-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 1575FD2512CD15C60003D86E /* proxy-configuration.c */; };
-               1575FD2C12CD15C60003D86E /* proxy-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1575FD2612CD15C60003D86E /* proxy-configuration.h */; };
                15792B9B0DA2C190008DDED9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                157A84DA0D56C63900B6F1A0 /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
                157A84DB0D56C63900B6F1A0 /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
                15792B9B0DA2C190008DDED9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                157A84DA0D56C63900B6F1A0 /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
                157A84DB0D56C63900B6F1A0 /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
-               157A84DE0D56C63900B6F1A0 /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
                157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
-               157A84E00D56C63900B6F1A0 /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
                157A84F60D56C7E800B6F1A0 /* dns-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22380AF13A7300D52ED0 /* dns-configuration.h */; };
                157A84F70D56C7E800B6F1A0 /* set-hostname.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22390AF13A7300D52ED0 /* set-hostname.h */; };
                157A84FB0D56C7E800B6F1A0 /* dns-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AA07528B36004F8947 /* dns-configuration.c */; };
                157A84F60D56C7E800B6F1A0 /* dns-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22380AF13A7300D52ED0 /* dns-configuration.h */; };
                157A84F70D56C7E800B6F1A0 /* set-hostname.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22390AF13A7300D52ED0 /* set-hostname.h */; };
                157A84FB0D56C7E800B6F1A0 /* dns-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AA07528B36004F8947 /* dns-configuration.c */; };
                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, ); }; };
                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, ); }; };
-               158317480CFB80A1006F62B9 /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
                158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
                158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
-               1583174A0CFB80A1006F62B9 /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                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 */; };
                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 */; };
                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 */; };
                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 */; };
-               1583EA06108395BB00A3BC0C /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA07108395BB00A3BC0C /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
-               1583EA09108395BB00A3BC0C /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
-               1583EA0A108395BB00A3BC0C /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
-               1583EA0B108395BB00A3BC0C /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
-               1583EA1B108395BB00A3BC0C /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA1C108395BB00A3BC0C /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA1D108395BB00A3BC0C /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA1E108395BB00A3BC0C /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA1F108395BB00A3BC0C /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
-               1583EA20108395BB00A3BC0C /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA21108395BB00A3BC0C /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA22108395BB00A3BC0C /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA23108395BB00A3BC0C /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA24108395BB00A3BC0C /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA25108395BB00A3BC0C /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA26108395BB00A3BC0C /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
-               1583EA27108395BB00A3BC0C /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA28108395BB00A3BC0C /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA29108395BB00A3BC0C /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA2A108395BB00A3BC0C /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA2B108395BB00A3BC0C /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA2C108395BB00A3BC0C /* SCNetworkConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */; settings = {ATTRIBUTES = (); }; };
-               1583EA2D108395BB00A3BC0C /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA2E108395BB00A3BC0C /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA2F108395BB00A3BC0C /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               1583EA30108395BB00A3BC0C /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               1583EA31108395BB00A3BC0C /* DHCPClientPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA32108395BB00A3BC0C /* SCDynamicStoreCopyDHCPInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693F05C0722B0099E85F /* SCDynamicStoreCopyDHCPInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA33108395BB00A3BC0C /* moh_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694105C0722B0099E85F /* moh_msg.h */; };
-               1583EA34108395BB00A3BC0C /* moh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694305C0722B0099E85F /* moh.h */; };
-               1583EA35108395BB00A3BC0C /* DeviceOnHold.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694505C0722B0099E85F /* DeviceOnHold.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA36108395BB00A3BC0C /* dy_framework.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694905C0722B0099E85F /* dy_framework.h */; };
-               1583EA37108395BB00A3BC0C /* SCPreferencesPathKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 151BDA2B05D9E28B00657BC7 /* SCPreferencesPathKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA38108395BB00A3BC0C /* pppcontroller_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */; };
-               1583EA39108395BB00A3BC0C /* pppcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = 23C1E2BE062DD5DB00835B54 /* pppcontroller.h */; };
-               1583EA3A108395BB00A3BC0C /* SCPreferencesSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA3B108395BB00A3BC0C /* SCPreferencesGetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 154CF3F307E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA3C108395BB00A3BC0C /* SCNetworkConfigurationPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA3E108395BB00A3BC0C /* SCHelper_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 155B7BF60847776D00F0E262 /* SCHelper_client.h */; };
-               1583EA3F108395BB00A3BC0C /* SCNetworkConnectionPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA40108395BB00A3BC0C /* SCPreferencesKeychainPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 152E68C00A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA41108395BB00A3BC0C /* SCSchemaDefinitionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 157A88880A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA42108395BB00A3BC0C /* SCNetworkSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA43108395BB00A3BC0C /* SCNetworkSignaturePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1583EA44108395BB00A3BC0C /* CaptiveNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A1FF3010597F17004C9CC9 /* CaptiveNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               1583EA4B108395BB00A3BC0C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 15A6F7C20A4B266D00B907EA /* Localizable.strings */; };
-               1583EA4C108395BB00A3BC0C /* NetworkInterface.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1577253606EFBF3100D7B52B /* NetworkInterface.strings */; };
-               1583EA4D108395BB00A3BC0C /* NetworkConfiguration.plist in Resources */ = {isa = PBXBuildFile; fileRef = 15B686220678B65C00FF4023 /* NetworkConfiguration.plist */; };
-               1583EA4E108395BB00A3BC0C /* get-mobility-info in Resources */ = {isa = PBXBuildFile; fileRef = 15CFC229068B222F00123568 /* get-mobility-info */; };
-               1583EA50108395BB00A3BC0C /* SCSchemaDefinitions.c in Sources */ = {isa = PBXBuildFile; fileRef = 150607BD075A00A200B147BA /* SCSchemaDefinitions.c */; };
-               1583EA51108395BB00A3BC0C /* SCD.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695005C0722B0099E85F /* SCD.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA52108395BB00A3BC0C /* SCDKeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695205C0722B0099E85F /* SCDKeys.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA53108395BB00A3BC0C /* SCDPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695405C0722B0099E85F /* SCDPrivate.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA54108395BB00A3BC0C /* SCDPlugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695605C0722B0099E85F /* SCDPlugin.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA55108395BB00A3BC0C /* SCDOpen.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695805C0722B0099E85F /* SCDOpen.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA58108395BB00A3BC0C /* SCDList.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB695E05C0722B0099E85F /* SCDList.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA59108395BB00A3BC0C /* SCDAdd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696005C0722B0099E85F /* SCDAdd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA5A108395BB00A3BC0C /* SCDGet.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696405C0722B0099E85F /* SCDGet.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA5B108395BB00A3BC0C /* SCDSet.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696605C0722B0099E85F /* SCDSet.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA5C108395BB00A3BC0C /* SCDRemove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696805C0722B0099E85F /* SCDRemove.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA5E108395BB00A3BC0C /* SCDNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696C05C0722B0099E85F /* SCDNotify.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA5F108395BB00A3BC0C /* SCDNotifierSetKeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB696E05C0722B0099E85F /* SCDNotifierSetKeys.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA60108395BB00A3BC0C /* SCDNotifierAdd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697005C0722B0099E85F /* SCDNotifierAdd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA61108395BB00A3BC0C /* SCDNotifierRemove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697205C0722B0099E85F /* SCDNotifierRemove.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA62108395BB00A3BC0C /* SCDNotifierGetChanges.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697405C0722B0099E85F /* SCDNotifierGetChanges.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA63108395BB00A3BC0C /* SCDNotifierWait.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697605C0722B0099E85F /* SCDNotifierWait.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA64108395BB00A3BC0C /* SCDNotifierInformViaCallback.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697805C0722B0099E85F /* SCDNotifierInformViaCallback.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA66108395BB00A3BC0C /* SCDNotifierInformViaFD.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697C05C0722B0099E85F /* SCDNotifierInformViaFD.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA67108395BB00A3BC0C /* SCDNotifierInformViaSignal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB697E05C0722B0099E85F /* SCDNotifierInformViaSignal.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA68108395BB00A3BC0C /* SCDNotifierCancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698005C0722B0099E85F /* SCDNotifierCancel.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA69108395BB00A3BC0C /* SCDSnapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698205C0722B0099E85F /* SCDSnapshot.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6A108395BB00A3BC0C /* SCP.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698405C0722B0099E85F /* SCP.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6B108395BB00A3BC0C /* SCPOpen.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698605C0722B0099E85F /* SCPOpen.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6C108395BB00A3BC0C /* SCPLock.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698805C0722B0099E85F /* SCPLock.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6D108395BB00A3BC0C /* SCPUnlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698A05C0722B0099E85F /* SCPUnlock.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6E108395BB00A3BC0C /* SCPList.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698C05C0722B0099E85F /* SCPList.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA6F108395BB00A3BC0C /* SCPGet.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB698E05C0722B0099E85F /* SCPGet.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA70108395BB00A3BC0C /* SCPAdd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699005C0722B0099E85F /* SCPAdd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA71108395BB00A3BC0C /* SCPSet.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699205C0722B0099E85F /* SCPSet.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA72108395BB00A3BC0C /* SCPRemove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699405C0722B0099E85F /* SCPRemove.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA73108395BB00A3BC0C /* SCPCommit.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699605C0722B0099E85F /* SCPCommit.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA74108395BB00A3BC0C /* SCPApply.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699805C0722B0099E85F /* SCPApply.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA75108395BB00A3BC0C /* SCPPath.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699A05C0722B0099E85F /* SCPPath.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA76108395BB00A3BC0C /* SCDHostName.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB699E05C0722B0099E85F /* SCDHostName.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA77108395BB00A3BC0C /* SCLocation.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A005C0722B0099E85F /* SCLocation.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA78108395BB00A3BC0C /* SCNetwork.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A205C0722B0099E85F /* SCNetwork.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA79108395BB00A3BC0C /* pppcontroller.defs in Sources */ = {isa = PBXBuildFile; fileRef = 23C1E2B8062DD45900835B54 /* pppcontroller.defs */; settings = {ATTRIBUTES = (Client, ); }; };
-               1583EA7A108395BB00A3BC0C /* SCNetworkConnection.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A405C0722B0099E85F /* SCNetworkConnection.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA7B108395BB00A3BC0C /* SCNetworkConnectionPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A2972D0A13C08C009879B3 /* SCNetworkConnectionPrivate.c */; };
-               1583EA7C108395BB00A3BC0C /* SCNetworkReachability.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA7D108395BB00A3BC0C /* SCProxies.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69A805C0722B0099E85F /* SCProxies.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA7E108395BB00A3BC0C /* DHCP.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AC05C0722B0099E85F /* DHCP.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA7F108395BB00A3BC0C /* moh.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69AE05C0722B0099E85F /* moh.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA80108395BB00A3BC0C /* DeviceOnHold.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B005C0722B0099E85F /* DeviceOnHold.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA81108395BB00A3BC0C /* LinkConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B205C0722B0099E85F /* LinkConfiguration.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA82108395BB00A3BC0C /* dy_framework.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B405C0722B0099E85F /* dy_framework.c */; settings = {ATTRIBUTES = (); }; };
-               1583EA83108395BB00A3BC0C /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Client, ); }; };
-               1583EA84108395BB00A3BC0C /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
-               1583EA85108395BB00A3BC0C /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
-               1583EA86108395BB00A3BC0C /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
-               1583EA87108395BB00A3BC0C /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; };
-               1583EA88108395BB00A3BC0C /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; };
-               1583EA89108395BB00A3BC0C /* SCNetworkService.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3D0670A85900BFE03C /* SCNetworkService.c */; };
-               1583EA8A108395BB00A3BC0C /* SCNetworkSet.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3E0670A85900BFE03C /* SCNetworkSet.c */; };
-               1583EA8C108395BB00A3BC0C /* SCHelper_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D808466D4900D1B2BD /* SCHelper_client.c */; };
-               1583EA8D108395BB00A3BC0C /* SCPreferencesKeychainPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 152E68C20A2C89E30011FDA8 /* SCPreferencesKeychainPrivate.c */; };
-               1583EA8E108395BB00A3BC0C /* SCNetworkSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */; };
-               1583EA8F108395BB00A3BC0C /* CaptiveNetwork.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A1FF3110597F17004C9CC9 /* CaptiveNetwork.c */; };
-               1583EA94108395BB00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EA9E108395BB00A3BC0C /* SCHelper_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 155B7BF60847776D00F0E262 /* SCHelper_client.h */; };
-               1583EAA0108395BB00A3BC0C /* SCHelper_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D908466D4900D1B2BD /* SCHelper_server.c */; };
-               1583EAA2108395BB00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EAA3108395BB00A3BC0C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
-               1583EAA4108395BB00A3BC0C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
-               1583EAA6108395BB00A3BC0C /* com.apple.SCHelper-embedded.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 151356AD0CE0CF2F0017E523 /* com.apple.SCHelper-embedded.plist */; };
-               1583EACC108395BB00A3BC0C /* dns-configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22380AF13A7300D52ED0 /* dns-configuration.h */; };
-               1583EACD108395BB00A3BC0C /* set-hostname.h in Headers */ = {isa = PBXBuildFile; fileRef = 155D22390AF13A7300D52ED0 /* set-hostname.h */; };
-               1583EACE108395BB00A3BC0C /* dnsinfo_create.h in Headers */ = {isa = PBXBuildFile; fileRef = 1532629006281C9D00B1C10C /* dnsinfo_create.h */; };
-               1583EAD0108395BB00A3BC0C /* ip_plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53A707528B36004F8947 /* ip_plugin.c */; };
-               1583EAD1108395BB00A3BC0C /* dns-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AA07528B36004F8947 /* dns-configuration.c */; };
-               1583EAD2108395BB00A3BC0C /* set-hostname.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AB07528B36004F8947 /* set-hostname.c */; };
-               1583EAD3108395BB00A3BC0C /* dnsinfo_create.c in Sources */ = {isa = PBXBuildFile; fileRef = 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */; };
-               1583EAD4108395BB00A3BC0C /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; };
-               1583EAE3108395BB00A3BC0C /* ifnamer.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AE07528B36004F8947 /* ifnamer.c */; };
-               1583EAF1108395BC00A3BC0C /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53CB07528B36004F8947 /* cache.h */; };
-               1583EAF2108395BC00A3BC0C /* ev_dlil.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B207528B36004F8947 /* ev_dlil.h */; };
-               1583EAF3108395BC00A3BC0C /* ev_ipv4.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B807528B36004F8947 /* ev_ipv4.h */; };
-               1583EAF4108395BC00A3BC0C /* ev_ipv6.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53BA07528B36004F8947 /* ev_ipv6.h */; };
-               1583EAF5108395BC00A3BC0C /* eventmon.h in Headers */ = {isa = PBXBuildFile; fileRef = 159D53B707528B36004F8947 /* eventmon.h */; };
-               1583EAF7108395BC00A3BC0C /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53CA07528B36004F8947 /* cache.c */; };
-               1583EAF8108395BC00A3BC0C /* ev_dlil.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B107528B36004F8947 /* ev_dlil.c */; };
-               1583EAF9108395BC00A3BC0C /* ev_ipv4.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B307528B36004F8947 /* ev_ipv4.c */; };
-               1583EAFA108395BC00A3BC0C /* ev_ipv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B407528B36004F8947 /* ev_ipv6.c */; };
-               1583EAFB108395BC00A3BC0C /* eventmon.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53B007528B36004F8947 /* eventmon.c */; };
-               1583EB0A108395BC00A3BC0C /* linkconfig.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53C107528B36004F8947 /* linkconfig.c */; };
-               1583EB18108395BC00A3BC0C /* logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 1531D3DB0E93E6DA00248432 /* logger.c */; };
-               1583EB1A108395BC00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EB1B108395BC00A3BC0C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */; };
-               1583EB1C108395BC00A3BC0C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
-               1583EB35108395BD00A3BC0C /* prefsmon.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53C307528B36004F8947 /* prefsmon.c */; };
-               1583EB4D108395BD00A3BC0C /* configd.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69CF05C0722B0099E85F /* configd.h */; };
-               1583EB4E108395BD00A3BC0C /* _SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D105C0722B0099E85F /* _SCD.h */; };
-               1583EB4F108395BD00A3BC0C /* configd_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D305C0722B0099E85F /* configd_server.h */; };
-               1583EB50108395BD00A3BC0C /* notify_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D505C0722B0099E85F /* notify_server.h */; };
-               1583EB51108395BD00A3BC0C /* plugin_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D705C0722B0099E85F /* plugin_support.h */; };
-               1583EB52108395BD00A3BC0C /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69D905C0722B0099E85F /* session.h */; };
-               1583EB53108395BD00A3BC0C /* pattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB69DB05C0722B0099E85F /* pattern.h */; };
-               1583EB55108395BD00A3BC0C /* configd.m in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E005C0722B0099E85F /* configd.m */; settings = {ATTRIBUTES = (); }; };
-               1583EB56108395BD00A3BC0C /* _SCD.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E205C0722B0099E85F /* _SCD.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB57108395BD00A3BC0C /* configd_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E405C0722B0099E85F /* configd_server.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB58108395BD00A3BC0C /* notify_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E605C0722B0099E85F /* notify_server.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB59108395BD00A3BC0C /* plugin_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69E805C0722B0099E85F /* plugin_support.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB5A108395BD00A3BC0C /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69EA05C0722B0099E85F /* session.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB5B108395BD00A3BC0C /* pattern.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69EC05C0722B0099E85F /* pattern.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB5C108395BD00A3BC0C /* _configopen.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F005C0722B0099E85F /* _configopen.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB5D108395BD00A3BC0C /* _configclose.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F205C0722B0099E85F /* _configclose.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB5F108395BD00A3BC0C /* _configunlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F605C0722B0099E85F /* _configunlock.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB60108395BD00A3BC0C /* _configlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69F805C0722B0099E85F /* _configlist.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB61108395BD00A3BC0C /* _configadd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69FA05C0722B0099E85F /* _configadd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB62108395BD00A3BC0C /* _configget.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69FE05C0722B0099E85F /* _configget.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB63108395BD00A3BC0C /* _configset.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0005C0722B0099E85F /* _configset.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB64108395BD00A3BC0C /* _configremove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0205C0722B0099E85F /* _configremove.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB66108395BD00A3BC0C /* _confignotify.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0605C0722B0099E85F /* _confignotify.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB67108395BD00A3BC0C /* _notifyadd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0805C0722B0099E85F /* _notifyadd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB68108395BD00A3BC0C /* _notifyremove.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0A05C0722B0099E85F /* _notifyremove.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB69108395BD00A3BC0C /* _notifychanges.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0C05C0722B0099E85F /* _notifychanges.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6A108395BD00A3BC0C /* _notifyviaport.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A0E05C0722B0099E85F /* _notifyviaport.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6B108395BD00A3BC0C /* _notifyviafd.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1005C0722B0099E85F /* _notifyviafd.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6C108395BD00A3BC0C /* _notifyviasignal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1205C0722B0099E85F /* _notifyviasignal.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6D108395BD00A3BC0C /* _notifycancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1405C0722B0099E85F /* _notifycancel.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6E108395BD00A3BC0C /* _snapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1605C0722B0099E85F /* _snapshot.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB6F108395BD00A3BC0C /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-               1583EB70108395BD00A3BC0C /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
-               1583EB71108395BD00A3BC0C /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
-               1583EB72108395BD00A3BC0C /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-               1583EB74108395BD00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EB75108395BD00A3BC0C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
-               1583EB76108395BD00A3BC0C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
-               1583EB77108395BD00A3BC0C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1520A3DE0846B2DC0010B584 /* Security.framework */; };
-               1583EB78108395BD00A3BC0C /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
-               1583EB79108395BD00A3BC0C /* libKernelEventMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53D407528BDA004F8947 /* libKernelEventMonitor.a */; };
-               1583EB7A108395BD00A3BC0C /* libInterfaceNamer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53E507528C4A004F8947 /* libInterfaceNamer.a */; };
-               1583EB7B108395BD00A3BC0C /* libIPMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53EC07528C61004F8947 /* libIPMonitor.a */; };
-               1583EB7C108395BD00A3BC0C /* libLinkConfiguration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53F307528C79004F8947 /* libLinkConfiguration.a */; };
-               1583EB7E108395BD00A3BC0C /* libPreferencesMonitor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 159D53FA07528C95004F8947 /* libPreferencesMonitor.a */; };
-               1583EB80108395BD00A3BC0C /* com.apple.configd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1540E3600987DA9500157C07 /* com.apple.configd.plist */; };
-               1583EB89108395BE00A3BC0C /* scselect.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A2E05C0722B0099E85F /* scselect.c */; settings = {ATTRIBUTES = (); }; };
-               1583EB8B108395BE00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EB8C108395BE00A3BC0C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
-               1583EB94108395BE00A3BC0C /* scutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4305C0722B0099E85F /* scutil.h */; };
-               1583EB95108395BE00A3BC0C /* commands.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4505C0722B0099E85F /* commands.h */; };
-               1583EB96108395BE00A3BC0C /* dictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4705C0722B0099E85F /* dictionary.h */; };
-               1583EB97108395BE00A3BC0C /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4905C0722B0099E85F /* session.h */; };
-               1583EB98108395BE00A3BC0C /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4B05C0722B0099E85F /* cache.h */; };
-               1583EB99108395BE00A3BC0C /* notifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4D05C0722B0099E85F /* notifications.h */; };
-               1583EB9A108395BE00A3BC0C /* tests.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A4F05C0722B0099E85F /* tests.h */; };
-               1583EB9B108395BE00A3BC0C /* prefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB6A5105C0722B0099E85F /* prefs.h */; };
-               1583EB9C108395BE00A3BC0C /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A509A406C2518F001F0AB7 /* net.h */; };
-               1583EB9D108395BE00A3BC0C /* net_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC34680711D49400A3311C /* net_interface.h */; };
-               1583EB9E108395BE00A3BC0C /* net_protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346A0711D49400A3311C /* net_protocol.h */; };
-               1583EB9F108395BE00A3BC0C /* net_service.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346C0711D49400A3311C /* net_service.h */; };
-               1583EBA0108395BE00A3BC0C /* net_set.h in Headers */ = {isa = PBXBuildFile; fileRef = 15DC346E0711D49400A3311C /* net_set.h */; };
-               1583EBA2108395BE00A3BC0C /* scutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5405C0722B0099E85F /* scutil.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA3108395BE00A3BC0C /* commands.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5605C0722B0099E85F /* commands.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA4108395BE00A3BC0C /* dictionary.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5805C0722B0099E85F /* dictionary.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA5108395BE00A3BC0C /* session.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5A05C0722B0099E85F /* session.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA6108395BE00A3BC0C /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5C05C0722B0099E85F /* cache.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA7108395BE00A3BC0C /* notifications.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A5E05C0722B0099E85F /* notifications.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA8108395BE00A3BC0C /* tests.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A6005C0722B0099E85F /* tests.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBA9108395BE00A3BC0C /* prefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A6205C0722B0099E85F /* prefs.c */; settings = {ATTRIBUTES = (); }; };
-               1583EBAA108395BE00A3BC0C /* net.c in Sources */ = {isa = PBXBuildFile; fileRef = 15A509A306C2518F001F0AB7 /* net.c */; };
-               1583EBAB108395BE00A3BC0C /* net_interface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC34670711D49400A3311C /* net_interface.c */; };
-               1583EBAC108395BE00A3BC0C /* net_protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC34690711D49400A3311C /* net_protocol.c */; };
-               1583EBAD108395BE00A3BC0C /* net_service.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC346B0711D49400A3311C /* net_service.c */; };
-               1583EBAE108395BE00A3BC0C /* net_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DC346D0711D49400A3311C /* net_set.c */; };
-               1583EBB0108395BE00A3BC0C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
-               1583EBB1108395BE00A3BC0C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */; };
-               1583EBB2108395BE00A3BC0C /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152CEED0070CF6640050F23C /* libedit.dylib */; };
                158E595E1107CAE40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                158E595F1107CAE80062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                158E595E1107CAE40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                158E595F1107CAE80062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
-               158E59601107CAF10062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                158E59611107CAF40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                15943D440E94081800B87535 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
                158E59611107CAF40062081E /* helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 152E0E7E10FE820E00E402F2 /* helper.defs */; };
                15943D440E94081800B87535 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1543636A0752D03C00A8EC6C /* IOKit.framework */; };
+               1596A7B114EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */; };
+               1596A7B214EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */; };
+               1596A7B414EDB73D00798C39 /* libSystemConfiguration_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */; };
+               1596A7B514EDB73D00798C39 /* libSystemConfiguration_server.h in Headers */ = {isa = PBXBuildFile; fileRef = 1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */; };
                159A751A107FEAA400A57EAB /* VPNPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 159A7513107FEAA400A57EAB /* VPNPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                159A751C107FEAA400A57EAB /* VPNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 159A7515107FEAA400A57EAB /* VPNConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; };
                159A751E107FEAA400A57EAB /* VPNPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7517107FEAA400A57EAB /* VPNPrivate.c */; };
                159A751A107FEAA400A57EAB /* VPNPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 159A7513107FEAA400A57EAB /* VPNPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                159A751C107FEAA400A57EAB /* VPNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 159A7515107FEAA400A57EAB /* VPNConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; };
                159A751E107FEAA400A57EAB /* VPNPrivate.c in Sources */ = {isa = PBXBuildFile; fileRef = 159A7517107FEAA400A57EAB /* VPNPrivate.c */; };
                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, ); }; };
                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, ); }; };
-               159D54C707529FFF004F8947 /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
                159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
                159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0D05FD1B670096477F /* dnsinfo_server.c */; };
-               159D54C907529FFF004F8947 /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Server, ); }; };
                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 */; };
                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 */; };
                15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15A5A1E70D5B94190087BDA0 /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15A5A1E80D5B94190087BDA0 /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15A5A1E70D5B94190087BDA0 /* SCSchemaDefinitions.h in Headers */ = {isa = PBXBuildFile; fileRef = 150607DE075A00A300B147BA /* SCSchemaDefinitions.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15A5A1E80D5B94190087BDA0 /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15A5A1E90D5B94190087BDA0 /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15A5A1E90D5B94190087BDA0 /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15A5A1EA0D5B94190087BDA0 /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15A5A1EB0D5B94190087BDA0 /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15A5A1EC0D5B94190087BDA0 /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1EA0D5B94190087BDA0 /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15A5A1EB0D5B94190087BDA0 /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15A5A1EC0D5B94190087BDA0 /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15A5A1ED0D5B94190087BDA0 /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15A5A1ED0D5B94190087BDA0 /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15A5A1EE0D5B94190087BDA0 /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1EF0D5B94190087BDA0 /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1EE0D5B94190087BDA0 /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1EF0D5B94190087BDA0 /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15A5A1F00D5B94190087BDA0 /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               15A5A1F10D5B94190087BDA0 /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15A5A1F00D5B94190087BDA0 /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
+               15A5A1F10D5B94190087BDA0 /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15A5A1F20D5B94190087BDA0 /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15A5A1F30D5B94190087BDA0 /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F20D5B94190087BDA0 /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15A5A1F30D5B94190087BDA0 /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15A5A1F40D5B94190087BDA0 /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15A5A1F40D5B94190087BDA0 /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15A5A1F50D5B94190087BDA0 /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F60D5B94190087BDA0 /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F70D5B94190087BDA0 /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15A5A1F50D5B94190087BDA0 /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F60D5B94190087BDA0 /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F70D5B94190087BDA0 /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15A5A1F90D5B94190087BDA0 /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1FA0D5B94190087BDA0 /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1FB0D5B94190087BDA0 /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1F90D5B94190087BDA0 /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1FA0D5B94190087BDA0 /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15A5A1FB0D5B94190087BDA0 /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15A5A1FC0D5B94190087BDA0 /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               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 */; };
                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 */; };
                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, ); }; };
                15A5A2540D5B94190087BDA0 /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
                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, ); }; };
                15A5A2540D5B94190087BDA0 /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
-               15A5A2550D5B94190087BDA0 /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
-               15A5A2560D5B94190087BDA0 /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
-               15A5A2570D5B94190087BDA0 /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                15A5A2580D5B94190087BDA0 /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                15A5A2590D5B94190087BDA0 /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; };
                15A5A25A0D5B94190087BDA0 /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; };
                15A5A2580D5B94190087BDA0 /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                15A5A2590D5B94190087BDA0 /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; };
                15A5A25A0D5B94190087BDA0 /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; };
                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 */; };
                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 */; };
-               15B274A5114467CD003414AD /* nc.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B43727113C7BFC00EBF1B6 /* nc.c */; };
-               15B274A6114467D8003414AD /* nc.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B43726113C7BFC00EBF1B6 /* nc.h */; };
+               15AB751516EBFF3400FAA8CE /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
+               15AB752D16EC2AE900FAA8CE /* libIPMonitor_sim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */; };
+               15AB752E16EC2AE900FAA8CE /* libSCNetworkReachability_sim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15AB751916EBFF3400FAA8CE /* libSCNetworkReachability_sim.a */; };
                15BAA32307F0699A00D9EC95 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
                15C330BC134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
                15C330BD134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
                15C330BE134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
                15BAA32307F0699A00D9EC95 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
                15C330BC134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
                15C330BD134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
                15C330BE134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
-               15C330BF134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */; };
-               15C330C0134B92780028E36B /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B8134B92780028E36B /* rb.c */; };
-               15C330C1134B92780028E36B /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B8134B92780028E36B /* rb.c */; };
-               15C330C2134B92780028E36B /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B8134B92780028E36B /* rb.c */; };
-               15C330C3134B92780028E36B /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330B8134B92780028E36B /* rb.c */; };
-               15C330C4134B92780028E36B /* rb.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330B9134B92780028E36B /* rb.h */; };
-               15C330C5134B92780028E36B /* rb.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330B9134B92780028E36B /* rb.h */; };
-               15C330C6134B92780028E36B /* rb.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330B9134B92780028E36B /* rb.h */; };
-               15C330C7134B92780028E36B /* rb.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330B9134B92780028E36B /* rb.h */; };
                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
-               15C330D4134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; };
                15C330E5134BD2AC0028E36B /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
                15C330E5134BD2AC0028E36B /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
-               15C330E6134BD2BB0028E36B /* SCNetworkReachabilityServer_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */; };
+               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 */; };
                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 */; };
-               15D48ED30F67079B00B4711E /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; };
-               15D48ED40F6707A600B4711E /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; };
+               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 */; };
                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 */; };
-               15D8B22D1450D8450090CECF /* SCD.h in Headers */ = {isa = PBXBuildFile; fileRef = 15D8B2291450D8450090CECF /* SCD.h */; };
-               15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15D9DCFA10DD90A1004E545D /* AppWorkaround.plist */; };
+               15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in AppWorkaround.plist */ = {isa = PBXBuildFile; fileRef = 15D9DCFA10DD90A1004E545D /* AppWorkaround.plist */; };
                15DAD5E1075913CE0084A6ED /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15DAD5E2075913CE0084A6ED /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
                15DAD5E1075913CE0084A6ED /* dnsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0905FD1B670096477F /* dnsinfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15DAD5E2075913CE0084A6ED /* dnsinfo_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B73F0C05FD1B670096477F /* dnsinfo_private.h */; };
-               15DAD5E5075913CE0084A6ED /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
                15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0805FD1B670096477F /* dnsinfo_copy.c */; };
-               15DAD5E7075913CE0084A6ED /* dnsinfo_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 15B73F0B05FD1B670096477F /* dnsinfo_private.c */; };
                15DAD64307591A1A0084A6ED /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64307591A1A0084A6ED /* SystemConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691305C0722B0099E85F /* SystemConfiguration.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15DAD64407591A1A0084A6ED /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15DAD64407591A1A0084A6ED /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15DAD64507591A1A0084A6ED /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15DAD64607591A1A0084A6ED /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15DAD64707591A1A0084A6ED /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64507591A1A0084A6ED /* SCDPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691705C0722B0099E85F /* SCDPlugin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                15DAD64607591A1A0084A6ED /* SCDynamicStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691B05C0722B0099E85F /* SCDynamicStoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15DAD64707591A1A0084A6ED /* SCDynamicStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691D05C0722B0099E85F /* SCDynamicStore.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15DAD64807591A1A0084A6ED /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15DAD64807591A1A0084A6ED /* SCDynamicStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691F05C0722B0099E85F /* SCDynamicStorePrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15DAD64907591A1A0084A6ED /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64A07591A1A0084A6ED /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64907591A1A0084A6ED /* SCDynamicStoreKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692105C0722B0099E85F /* SCDynamicStoreKey.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64A07591A1A0084A6ED /* SCDynamicStoreCopySpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692305C0722B0099E85F /* SCDynamicStoreCopySpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15DAD64B07591A1A0084A6ED /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
-               15DAD64C07591A1A0084A6ED /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15DAD64B07591A1A0084A6ED /* SCDynamicStoreCopySpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692505C0722B0099E85F /* SCDynamicStoreCopySpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
+               15DAD64C07591A1A0084A6ED /* SCDynamicStoreSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692705C0722B0099E85F /* SCDynamicStoreSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15DAD64D07591A1A0084A6ED /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15DAD64E07591A1A0084A6ED /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD64D07591A1A0084A6ED /* SCPreferencesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692905C0722B0099E85F /* SCPreferencesInternal.h */; settings = {ATTRIBUTES = (Project, ); }; };
                15DAD64E07591A1A0084A6ED /* SCPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692B05C0722B0099E85F /* SCPreferences.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15DAD64F07591A1A0084A6ED /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               15DAD64F07591A1A0084A6ED /* SCPreferencesPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692D05C0722B0099E85F /* SCPreferencesPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
                15DAD65007591A1A0084A6ED /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65107591A1A0084A6ED /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65207591A1A0084A6ED /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15DAD65007591A1A0084A6ED /* SCPreferencesPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB692F05C0722B0099E85F /* SCPreferencesPath.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65107591A1A0084A6ED /* SCPreferencesSetSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693105C0722B0099E85F /* SCPreferencesSetSpecific.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65207591A1A0084A6ED /* SCNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
                15DAD65407591A1A0084A6ED /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65507591A1A0084A6ED /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65607591A1A0084A6ED /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65407591A1A0084A6ED /* SCNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693305C0722B0099E85F /* SCNetwork.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65507591A1A0084A6ED /* SCNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693505C0722B0099E85F /* SCNetworkConnection.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
                15DAD65607591A1A0084A6ED /* SCNetworkReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693705C0722B0099E85F /* SCNetworkReachability.h */; settings = {ATTRIBUTES = (Public, Project, ); }; };
-               15DAD65707591A1A0084A6ED /* SCValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB693905C0722B0099E85F /* SCValidation.h */; settings = {ATTRIBUTES = (Project, Private, ); }; };
+               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, ); }; };
                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, ); }; };
-               15DAD65D07591A1A0084A6ED /* LinkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB694705C0722B0099E85F /* LinkConfiguration.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 */; };
                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 */; };
                15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; settings = {ATTRIBUTES = (); COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6A007591A1A0084A6ED /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                15DAD6A207591A1A0084A6ED /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
                15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69B605C0722B0099E85F /* VLANConfiguration.c */; settings = {ATTRIBUTES = (); COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6A007591A1A0084A6ED /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                15DAD6A207591A1A0084A6ED /* SCPreferencesPathKey.c in Sources */ = {isa = PBXBuildFile; fileRef = 151BDA5D05D9E2ED00657BC7 /* SCPreferencesPathKey.c */; };
-               15DAD6A507591A1A0084A6ED /* shared_dns_info.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */; settings = {ATTRIBUTES = (Client, ); }; };
                15DAD6A607591A1A0084A6ED /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                15DAD6A707591A1A0084A6ED /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6A807591A1A0084A6ED /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6A607591A1A0084A6ED /* SCNetworkConfigurationInternal.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */; };
                15DAD6A707591A1A0084A6ED /* SCNetworkInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3B0670A85900BFE03C /* SCNetworkInterface.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6A807591A1A0084A6ED /* SCNetworkProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
                15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                15DAF2DC08466D4900D1B2BD /* SCHelper_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D808466D4900D1B2BD /* SCHelper_client.c */; };
                15DAF2E108466D4900D1B2BD /* SCHelper_server.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D908466D4900D1B2BD /* SCHelper_server.c */; };
                15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                15DAF2DC08466D4900D1B2BD /* SCHelper_client.c in Sources */ = {isa = PBXBuildFile; fileRef = 15DAF2D808466D4900D1B2BD /* SCHelper_client.c */; };
                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 */; };
+               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 */; };
+               15E1B04B16EBAE3C00E5F06F /* dns-configuration.c in Sources */ = {isa = PBXBuildFile; fileRef = 159D53AA07528B36004F8947 /* dns-configuration.c */; };
+               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 */; };
+               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 */; };
+               15E1B05416EBAE3C00E5F06F /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               15E1B05516EBAE3C00E5F06F /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
                15F21618110F823500E89CF7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
                15F21618110F823500E89CF7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
-               15F21619110F826800E89CF7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
                15FC130B0CCEA59E0013872C /* monitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC130A0CCEA59E0013872C /* monitor.c */; };
                15FC13180CCF74740013872C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                15FD7B3C101E439200C56621 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                15FC130B0CCEA59E0013872C /* monitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC130A0CCEA59E0013872C /* monitor.c */; };
                15FC13180CCF74740013872C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */; };
                15FD7B3C101E439200C56621 /* BridgeConfiguration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */; };
                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 */; };
                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 */; };
+               72C3E82715003E78000D68CB /* MobileInstallation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C3E82615003E78000D68CB /* MobileInstallation.framework */; };
+               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 */; };
+               B03FEFBB16382C1300A1B88F /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
+               B084710F16385121006C92A3 /* SCNetworkConnectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */; };
+               B084711016385121006C92A3 /* SCNetworkConnectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */; };
+               B0A88CA716397A1200A60B3A /* VPNAppLayerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               B0A88CA816397A1200A60B3A /* VPNAppLayerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               B0C967F817441F0E00889853 /* SNHelperPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C967F717441F0E00889853 /* SNHelperPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               B0C9689C174426C600889853 /* SNHelper.c in Sources */ = {isa = PBXBuildFile; fileRef = B0C9689B174426C200889853 /* SNHelper.c */; };
+               B0C9689D174426D100889853 /* SNHelper.c in Sources */ = {isa = PBXBuildFile; fileRef = B0C9689B174426C200889853 /* SNHelper.c */; };
+               B0C9689E174426DD00889853 /* SNHelperPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B0C967F717441F0E00889853 /* SNHelperPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               B0FEF41A164406F400174B99 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BAA32207F0699A00D9EC95 /* libbsm.dylib */; };
+               B0FEF41B1644089200174B99 /* VPNAppLayer.c in Sources */ = {isa = PBXBuildFile; fileRef = B03FEFB516376D2800A1B88F /* VPNAppLayer.c */; };
+               C4CDB8151631935700819B44 /* VPNFlow.c in Sources */ = {isa = PBXBuildFile; fileRef = C4CDB8141631935700819B44 /* VPNFlow.c */; };
+               C4CDB8161631935700819B44 /* VPNFlow.c in Sources */ = {isa = PBXBuildFile; fileRef = C4CDB8141631935700819B44 /* VPNFlow.c */; };
+               C4CDB8171631938000819B44 /* VPNFlow.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CDB8111631933400819B44 /* VPNFlow.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4CDB8181631938400819B44 /* VPNFlowPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CDB8121631933400819B44 /* VPNFlowPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4CDB819163193AA00819B44 /* VPNFlow.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CDB8111631933400819B44 /* VPNFlow.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4CDB81A163193AF00819B44 /* VPNFlowPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CDB8121631933400819B44 /* VPNFlowPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4F1848016237AFC00D97043 /* VPNService.c in Sources */ = {isa = PBXBuildFile; fileRef = C4F1847F16237AFC00D97043 /* VPNService.c */; };
+               C4F1848116237AFC00D97043 /* VPNService.c in Sources */ = {isa = PBXBuildFile; fileRef = C4F1847F16237AFC00D97043 /* VPNService.c */; };
+               C4F1848316237B1400D97043 /* VPNService.c in Sources */ = {isa = PBXBuildFile; fileRef = C4F1847F16237AFC00D97043 /* VPNService.c */; };
+               D61AAEAE1522C99C0066B003 /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               D61AAEAF1522C99C0066B003 /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               D61AAEB01522C99C0066B003 /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               D61AAEB11522C99C0066B003 /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               D61AAEB21522C99C0066B003 /* scprefs_observer.c in Sources */ = {isa = PBXBuildFile; fileRef = D61AAEAD1522C99C0066B003 /* scprefs_observer.c */; };
+               D61AAEB51522C9D00066B003 /* scprefs_observer.h in Headers */ = {isa = PBXBuildFile; fileRef = D61AAEB41522C9BD0066B003 /* scprefs_observer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               D61AAEB61522C9E60066B003 /* scprefs_observer.h in Headers */ = {isa = PBXBuildFile; fileRef = D61AAEB41522C9BD0066B003 /* scprefs_observer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               D61AAEB71522C9EF0066B003 /* scprefs_observer.h in Headers */ = {isa = PBXBuildFile; fileRef = D61AAEB41522C9BD0066B003 /* scprefs_observer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                D661C2EF1368BB280030B977 /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
                D661C2F11368BB600030B977 /* network_information.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A77136891300091C931 /* network_information.c */; };
                D661C2F21368BB720030B977 /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
                D661C2EF1368BB280030B977 /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
                D661C2F11368BB600030B977 /* network_information.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A77136891300091C931 /* network_information.c */; };
                D661C2F21368BB720030B977 /* network_information.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A781368913C0091C931 /* network_information.h */; settings = {ATTRIBUTES = (Public, ); }; };
                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 */; };
                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 */; };
-               E4F211D5137B0AD700BBB915 /* network_information_priv.c in Sources */ = {isa = PBXBuildFile; fileRef = D6986A75136891120091C931 /* network_information_priv.c */; };
-               E4F211D6137B0ADB00BBB915 /* 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 */; };
                F95B8A430B03E07A00993BA3 /* SCNetworkSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */; };
                F95B8A460B03E09300993BA3 /* SCNetworkSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
                F95B8A470B03E09300993BA3 /* SCNetworkSignaturePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E4F211D7137B0AF200BBB915 /* network_information_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = D6986A761368911E0091C931 /* network_information_priv.h */; };
                F95B8A430B03E07A00993BA3 /* SCNetworkSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */; };
                F95B8A460B03E09300993BA3 /* SCNetworkSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
                F95B8A470B03E09300993BA3 /* SCNetworkSignaturePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               F9A3781016A4847700C57CDC /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
+               F9A3781116A4849100C57CDC /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
+               F9B50FF316A4CBB200CA274E /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
+               F9B50FF416A4CBB800CA274E /* IPMonitorControlPrefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                        remoteGlobalIDString = 1528BFF813573FF500691881;
                        remoteInfo = "SCNetworkReachability.bundle-Embedded";
                };
                        remoteGlobalIDString = 1528BFF813573FF500691881;
                        remoteInfo = "SCNetworkReachability.bundle-Embedded";
                };
-               1528C0121357420300691881 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1528BFFF1357401900691881;
-                       remoteInfo = "SCNetworkReachability-EmbeddedOther";
-               };
-               1528C0141357420300691881 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1528C0071357401D00691881;
-                       remoteInfo = "SCNetworkReachability.bundle-EmbeddedOther";
-               };
                1558480507550D470046C2E9 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                1558480507550D470046C2E9 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        remoteGlobalIDString = 156CA4790EF853BB00C59A18;
                        remoteInfo = "Logger.bundle-Embedded";
                };
                        remoteGlobalIDString = 156CA4790EF853BB00C59A18;
                        remoteInfo = "Logger.bundle-Embedded";
                };
+               15732AE516EA6BCE00F3AC4C /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 15732AD616EA6B6700F3AC4C;
+                       remoteInfo = "libsystem_configuration-EmbeddedSimulator";
+               };
                1574341E0D4A815E002ACA73 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                1574341E0D4A815E002ACA73 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        remoteGlobalIDString = 157BB8AE075924360025DA7A;
                        remoteInfo = Frameworks;
                };
                        remoteGlobalIDString = 157BB8AE075924360025DA7A;
                        remoteInfo = Frameworks;
                };
+               157FDE43164A079B0040D6A8 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 157FDE3B164A075F0040D6A8;
+                       remoteInfo = "configd_libSystem-EmbeddedSimulator";
+               };
                15828B060753B77E00AD4710 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                15828B060753B77E00AD4710 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        remoteGlobalIDString = 15A5A1E40D5B94190087BDA0;
                        remoteInfo = "SystemConfiguration.framework-EmbeddedSimulator";
                };
                        remoteGlobalIDString = 15A5A1E40D5B94190087BDA0;
                        remoteInfo = "SystemConfiguration.framework-EmbeddedSimulator";
                };
-               15AC515710839608004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583E9FD108395BB00A3BC0C;
-                       remoteInfo = "configd_libSystem-EmbeddedOther";
-               };
-               15AC515A1083960E004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EA11108395BB00A3BC0C;
-                       remoteInfo = "configd_base-EmbeddedOther";
-               };
-               15AC515C10839613004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EAAC108395BB00A3BC0C;
-                       remoteInfo = "configd_plugins-EmbeddedOther";
-               };
-               15AC515E1083961E004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EB41108395BD00A3BC0C;
-                       remoteInfo = "configd_executables-EmbeddedOther";
-               };
-               15AC516010839649004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EA04108395BB00A3BC0C;
-                       remoteInfo = "DNSConfiguration-EmbeddedOther";
-               };
-               15AC516210839666004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EA19108395BB00A3BC0C;
-                       remoteInfo = "SystemConfiguration.framework-EmbeddedOther";
-               };
-               15AC51641083966B004A9ED5 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 1583EA9B108395BB00A3BC0C;
-                       remoteInfo = "SCHelper-EmbeddedOther";
-               };
-               15AC5169108396B7004A9ED5 /* PBXContainerItemProxy */ = {
+               15AB752116EC005A00FAA8CE /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB92108395BE00A3BC0C;
-                       remoteInfo = "scutil-EmbeddedOther";
+                       remoteGlobalIDString = 15AB751216EBFF3400FAA8CE;
+                       remoteInfo = "SCNetworkReachability-EmbeddedSimulator";
                };
                };
-               15AC516B108396B7004A9ED5 /* PBXContainerItemProxy */ = {
+               15AB752316EC005A00FAA8CE /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB86108395BE00A3BC0C;
-                       remoteInfo = "scselect-EmbeddedOther";
+                       remoteGlobalIDString = 15AB751A16EBFF8A00FAA8CE;
+                       remoteInfo = "SCNetworkReachability.bundle-EmbeddedSimulator";
                };
                };
-               15AC516D108396B7004A9ED5 /* PBXContainerItemProxy */ = {
+               15AB752916EC254D00FAA8CE /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB4B108395BD00A3BC0C;
-                       remoteInfo = "configd-EmbeddedOther";
+                       remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F;
+                       remoteInfo = "IPMonitor-EmbeddedSimulator";
                };
                };
-               15AC5170108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15AB752B16EC254D00FAA8CE /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB3A108395BD00A3BC0C;
-                       remoteInfo = "PreferencesMonitor.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15AB751216EBFF3400FAA8CE;
+                       remoteInfo = "SCNetworkReachability-EmbeddedSimulator";
                };
                };
-               15AC5172108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15C64A210F684C4900D78394 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB32108395BD00A3BC0C;
-                       remoteInfo = "PreferencesMonitor-EmbeddedOther";
+                       remoteGlobalIDString = 15DAD5DF075913CE0084A6ED;
+                       remoteInfo = DNSConfiguration;
                };
                };
-               15AC5178108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15C64A230F684C5700D78394 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB16108395BC00A3BC0C;
-                       remoteInfo = "Logger.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15C64A1E0F684C3300D78394;
+                       remoteInfo = configd_libSystem;
                };
                };
-               15AC517A108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15C64A2E0F684C8300D78394 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB0F108395BC00A3BC0C;
-                       remoteInfo = "LinkConfiguration.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15C64A280F684C6B00D78394;
+                       remoteInfo = "configd_libSystem-Embedded";
                };
                };
-               15AC517C108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15C64A300F684C8F00D78394 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB07108395BC00A3BC0C;
-                       remoteInfo = "LinkConfiguration-EmbeddedOther";
+                       remoteGlobalIDString = 157A84D80D56C63900B6F1A0;
+                       remoteInfo = "DNSConfiguration-Embedded";
                };
                };
-               15AC517E108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15D3082F16F3EAD000014F82 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EB00108395BC00A3BC0C;
-                       remoteInfo = "KernelEventMonitor.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15D3080F16F3E4DA00014F82;
+                       remoteInfo = "SimulatorSupport-EmbeddedSimulator";
                };
                };
-               15AC5180108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15D3083116F3EAD000014F82 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EAEF108395BC00A3BC0C;
-                       remoteInfo = "KernelEventMonitor-EmbeddedOther";
+                       remoteGlobalIDString = 15D3082816F3E4E100014F82;
+                       remoteInfo = "SimulatorSupport.bundle-EmbeddedSimulator";
                };
                };
-               15AC5182108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15D3083416F3EB2500014F82 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EAE8108395BC00A3BC0C;
-                       remoteInfo = "InterfaceNamer.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15D3080F16F3E4DA00014F82;
+                       remoteInfo = "SimulatorSupport-EmbeddedSimulator";
                };
                };
-               15AC5184108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EAE0108395BB00A3BC0C;
-                       remoteInfo = "InterfaceNamer-EmbeddedOther";
+                       remoteGlobalIDString = 15732A7616EA503200F3AC4C;
+                       remoteInfo = "configd-EmbeddedSimulator";
                };
                };
-               15AC5186108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15E1B03F16EBAB9400E5F06F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EAD9108395BB00A3BC0C;
-                       remoteInfo = "IPMonitor.bundle-EmbeddedOther";
+                       remoteGlobalIDString = 15732AAD16EA511900F3AC4C;
+                       remoteInfo = "scutil-EmbeddedSimulator";
                };
                };
-               15AC5188108396D2004A9ED5 /* PBXContainerItemProxy */ = {
+               15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 1583EACA108395BB00A3BC0C;
-                       remoteInfo = "IPMonitor-EmbeddedOther";
+                       remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F;
+                       remoteInfo = "IPMonitor-EmbeddedSimulator";
                };
                };
-               15C64A210F684C4900D78394 /* PBXContainerItemProxy */ = {
+               15E1B06516EBAF2A00E5F06F /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 15DAD5DF075913CE0084A6ED;
-                       remoteInfo = DNSConfiguration;
+                       remoteGlobalIDString = 15E1B05A16EBAE7800E5F06F;
+                       remoteInfo = "IPMonitor.bundle-EmbeddedSimulator";
                };
                };
-               15C64A230F684C5700D78394 /* PBXContainerItemProxy */ = {
+               15E83108167F9B0600FD51EC /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 15C64A1E0F684C3300D78394;
-                       remoteInfo = configd_libSystem;
+                       remoteGlobalIDString = 15CB690005C0722A0099E85F;
+                       remoteInfo = All;
                };
                };
-               15C64A2E0F684C8300D78394 /* PBXContainerItemProxy */ = {
+               15E8310A167F9B0C00FD51EC /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 15C64A280F684C6B00D78394;
-                       remoteInfo = "configd_libSystem-Embedded";
+                       remoteGlobalIDString = 151C1CC60CFB487000C5AFD6;
+                       remoteInfo = "All-Embedded";
                };
                };
-               15C64A300F684C8F00D78394 /* PBXContainerItemProxy */ = {
+               15E8310C167F9B1200FD51EC /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
                        isa = PBXContainerItemProxy;
                        containerPortal = 15CB6A7705C0722B0099E85F /* Project object */;
                        proxyType = 1;
-                       remoteGlobalIDString = 157A84D80D56C63900B6F1A0;
-                       remoteInfo = "DNSConfiguration-Embedded";
+                       remoteGlobalIDString = 15FD13BF0D59485000F9409C;
+                       remoteInfo = "All-EmbeddedSimulator";
                };
                D6DDAC3C147A24BC00A2E902 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                };
                D6DDAC3C147A24BC00A2E902 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               15732AA716EA503200F3AC4C /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = "$(SDKROOT)/System/Library/LaunchDaemons";
+                       dstSubfolderSpec = 0;
+                       files = (
+                               15D3083B16F4E81C00014F82 /* com.apple.configd_sim.plist in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
                1583175B0CFB80A1006F62B9 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                1583175B0CFB80A1006F62B9 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               1583EAA5108395BB00A3BC0C /* CopyFiles */ = {
+               159D54D507529FFF004F8947 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
-                       dstPath = /System/Library/LaunchDaemons;
+                       dstPath = /usr/share/man/man8;
                        dstSubfolderSpec = 0;
                        files = (
                        dstSubfolderSpec = 0;
                        files = (
-                               1583EAA6108395BB00A3BC0C /* com.apple.SCHelper-embedded.plist in CopyFiles */,
+                               159D54D607529FFF004F8947 /* configd.8 in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               1583EB7F108395BD00A3BC0C /* CopyFiles */ = {
+               159D54D707529FFF004F8947 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /System/Library/LaunchDaemons;
                        dstSubfolderSpec = 0;
                        files = (
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /System/Library/LaunchDaemons;
                        dstSubfolderSpec = 0;
                        files = (
-                               1583EB80108395BD00A3BC0C /* com.apple.configd.plist in CopyFiles */,
+                               1540E3610987DA9500157C07 /* com.apple.configd.plist in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               159D54D507529FFF004F8947 /* CopyFiles */ = {
+               15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
-                       dstPath = /usr/share/man/man8;
+                       dstPath = /private/etc/asl;
                        dstSubfolderSpec = 0;
                        files = (
                        dstSubfolderSpec = 0;
                        files = (
-                               159D54D607529FFF004F8947 /* configd.8 in CopyFiles */,
+                               15D54E2715B4FA4600F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */,
                        );
                        );
+                       name = com.apple.networking.IPMonitor;
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               159D54D707529FFF004F8947 /* CopyFiles */ = {
+               15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
-                       dstPath = /System/Library/LaunchDaemons;
+                       dstPath = /private/etc/asl;
                        dstSubfolderSpec = 0;
                        files = (
                        dstSubfolderSpec = 0;
                        files = (
-                               1540E3610987DA9500157C07 /* com.apple.configd.plist in CopyFiles */,
+                               15D54E2B15B4FB0300F5229A /* com.apple.networking.IPMonitor in com.apple.networking.IPMonitor */,
                        );
                        );
+                       name = com.apple.networking.IPMonitor;
                        runOnlyForDeploymentPostprocessing = 1;
                };
                        runOnlyForDeploymentPostprocessing = 1;
                };
-               15D9DCF910DD909F004E545D /* CopyFiles */ = {
+               15D9DCF910DD909F004E545D /* AppWorkaround.plist */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /usr/local/AppSpecificWorkaround/SystemConfiguration;
                        dstSubfolderSpec = 0;
                        files = (
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 8;
                        dstPath = /usr/local/AppSpecificWorkaround/SystemConfiguration;
                        dstSubfolderSpec = 0;
                        files = (
-                               15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in CopyFiles */,
+                               15D9DCFB10DD90A1004E545D /* AppWorkaround.plist in AppWorkaround.plist */,
                        );
                        );
+                       name = AppWorkaround.plist;
                        runOnlyForDeploymentPostprocessing = 1;
                };
                15FF5C380CDF778F00EEC8AA /* CopyFiles */ = {
                        runOnlyForDeploymentPostprocessing = 1;
                };
                15FF5C380CDF778F00EEC8AA /* CopyFiles */ = {
                1528BFE91357312E00691881 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SCNetworkReachability/Info.plist; sourceTree = "<group>"; };
                1528BFF713573FEE00691881 /* libSCNetworkReachability.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSCNetworkReachability.a; sourceTree = BUILT_PRODUCTS_DIR; };
                1528BFFE13573FF500691881 /* SCNetworkReachability.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCNetworkReachability.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                1528BFE91357312E00691881 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SCNetworkReachability/Info.plist; sourceTree = "<group>"; };
                1528BFF713573FEE00691881 /* libSCNetworkReachability.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSCNetworkReachability.a; sourceTree = BUILT_PRODUCTS_DIR; };
                1528BFFE13573FF500691881 /* SCNetworkReachability.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCNetworkReachability.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1528C0061357401900691881 /* libSCNetworkReachability.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSCNetworkReachability.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1528C00D1357401D00691881 /* SCNetworkReachability.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCNetworkReachability.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                152CEED0070CF6640050F23C /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.2.dylib; sourceTree = "<absolute>"; };
                152E0E7E10FE820E00E402F2 /* helper.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; name = helper.defs; path = SystemConfiguration.fproj/helper/helper.defs; sourceTree = "<group>"; };
                152E0E8810FE824000E402F2 /* helper_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = helper_types.h; path = SystemConfiguration.fproj/helper/helper_types.h; sourceTree = "<group>"; };
                152CEED0070CF6640050F23C /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.2.dylib; sourceTree = "<absolute>"; };
                152E0E7E10FE820E00E402F2 /* helper.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; name = helper.defs; path = SystemConfiguration.fproj/helper/helper.defs; sourceTree = "<group>"; };
                152E0E8810FE824000E402F2 /* helper_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = helper_types.h; path = SystemConfiguration.fproj/helper/helper_types.h; sourceTree = "<group>"; };
                1531D3DA0E93E6DA00248432 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/Logger/Info.plist; sourceTree = "<group>"; };
                1531D3DB0E93E6DA00248432 /* logger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = logger.c; path = Plugins/Logger/logger.c; sourceTree = "<group>"; };
                1532629006281C9D00B1C10C /* dnsinfo_create.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_create.h; path = dnsinfo/dnsinfo_create.h; sourceTree = "<group>"; };
                1531D3DA0E93E6DA00248432 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/Logger/Info.plist; sourceTree = "<group>"; };
                1531D3DB0E93E6DA00248432 /* logger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = logger.c; path = Plugins/Logger/logger.c; sourceTree = "<group>"; };
                1532629006281C9D00B1C10C /* dnsinfo_create.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_create.h; path = dnsinfo/dnsinfo_create.h; sourceTree = "<group>"; };
+               153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libSystemConfiguration_client.c; path = libSystemConfiguration/libSystemConfiguration_client.c; sourceTree = "<group>"; };
+               153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libSystemConfiguration_client.h; path = libSystemConfiguration/libSystemConfiguration_client.h; sourceTree = "<group>"; };
                153393E20D34994100FE74E7 /* update-headers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "update-headers"; sourceTree = "<group>"; };
                153393E20D34994100FE74E7 /* update-headers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "update-headers"; sourceTree = "<group>"; };
+               153ACCA614E322D5005029A5 /* network_information_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = network_information_server.c; path = nwi/network_information_server.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
+               153ACCA714E322D5005029A5 /* network_information_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = network_information_server.h; path = nwi/network_information_server.h; sourceTree = "<group>"; };
                1540E3600987DA9500157C07 /* com.apple.configd.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 30; path = com.apple.configd.plist; sourceTree = "<group>"; };
                1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
                1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; };
                1540E3600987DA9500157C07 /* com.apple.configd.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 30; path = com.apple.configd.plist; sourceTree = "<group>"; };
                1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
                1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; };
                156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = "<group>"; };
                156CA4850EF853BB00C59A18 /* Logger.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Logger.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                156CA48D0EF853BB00C59A18 /* Info-Embedded.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-Embedded.plist"; path = "Plugins/Logger/Info-Embedded.plist"; sourceTree = "<group>"; };
                156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = "<group>"; };
                156CA4850EF853BB00C59A18 /* Logger.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Logger.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                156CA48D0EF853BB00C59A18 /* Info-Embedded.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-Embedded.plist"; path = "Plugins/Logger/Info-Embedded.plist"; sourceTree = "<group>"; };
+               1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; name = pppcontroller_mach_defines.h; path = usr/local/include/ppp/pppcontroller_mach_defines.h; sourceTree = SDKROOT; };
                1572EB7A0A506D3B00D02459 /* smb-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "smb-configuration.c"; sourceTree = "<group>"; };
                1572EB7A0A506D3B00D02459 /* smb-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "smb-configuration.c"; sourceTree = "<group>"; };
+               15732AAC16EA503300F3AC4C /* configd_sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd_sim; sourceTree = BUILT_PRODUCTS_DIR; };
+               15732AD516EA511900F3AC4C /* scutil_sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scutil_sim; sourceTree = BUILT_PRODUCTS_DIR; };
+               15732AE416EA6B6700F3AC4C /* libsystem_sim_configuration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_sim_configuration.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                157433EC0D4A8122002ACA73 /* scselect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scselect; sourceTree = BUILT_PRODUCTS_DIR; };
                1574341A0D4A8137002ACA73 /* scutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scutil; sourceTree = BUILT_PRODUCTS_DIR; };
                1575FD2512CD15C60003D86E /* proxy-configuration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "proxy-configuration.c"; sourceTree = "<group>"; };
                1575FD2612CD15C60003D86E /* proxy-configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "proxy-configuration.h"; sourceTree = "<group>"; };
                1577252F06EFB96700D7B52B /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/NetworkInterface.strings; sourceTree = "<group>"; };
                157433EC0D4A8122002ACA73 /* scselect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scselect; sourceTree = BUILT_PRODUCTS_DIR; };
                1574341A0D4A8137002ACA73 /* scutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scutil; sourceTree = BUILT_PRODUCTS_DIR; };
                1575FD2512CD15C60003D86E /* proxy-configuration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "proxy-configuration.c"; sourceTree = "<group>"; };
                1575FD2612CD15C60003D86E /* proxy-configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "proxy-configuration.h"; sourceTree = "<group>"; };
                1577252F06EFB96700D7B52B /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/NetworkInterface.strings; sourceTree = "<group>"; };
-               157A84E80D56C63900B6F1A0 /* libdnsinfo.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdnsinfo.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               157A84E80D56C63900B6F1A0 /* libsystem_configuration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_configuration.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85020D56C7E800B6F1A0 /* libIPMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A850D0D56C8AA00B6F1A0 /* libInterfaceNamer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInterfaceNamer.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85230D56C8E000B6F1A0 /* libKernelEventMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKernelEventMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85020D56C7E800B6F1A0 /* libIPMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A850D0D56C8AA00B6F1A0 /* libInterfaceNamer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInterfaceNamer.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85230D56C8E000B6F1A0 /* libKernelEventMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKernelEventMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85440D56C96F00B6F1A0 /* libPreferencesMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPreferencesMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A88880A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCSchemaDefinitionsPrivate.h; sourceTree = "<group>"; };
                15828AE70753B5F900AD4710 /* KernelEventMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KernelEventMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                157A85440D56C96F00B6F1A0 /* libPreferencesMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPreferencesMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
                157A88880A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCSchemaDefinitionsPrivate.h; sourceTree = "<group>"; };
                15828AE70753B5F900AD4710 /* KernelEventMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KernelEventMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EA10108395BB00A3BC0C /* libdnsinfo.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdnsinfo.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EA99108395BB00A3BC0C /* SystemConfiguration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemConfiguration.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EAAA108395BB00A3BC0C /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EAD8108395BB00A3BC0C /* libIPMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EADE108395BB00A3BC0C /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EAE7108395BB00A3BC0C /* libInterfaceNamer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInterfaceNamer.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EAED108395BC00A3BC0C /* InterfaceNamer.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InterfaceNamer.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EAFF108395BC00A3BC0C /* libKernelEventMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKernelEventMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB05108395BC00A3BC0C /* KernelEventMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KernelEventMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB0E108395BC00A3BC0C /* libLinkConfiguration.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLinkConfiguration.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB14108395BC00A3BC0C /* LinkConfiguration.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LinkConfiguration.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB21108395BC00A3BC0C /* Logger.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Logger.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB39108395BD00A3BC0C /* libPreferencesMonitor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPreferencesMonitor.a; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB3F108395BD00A3BC0C /* PreferencesMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PreferencesMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB84108395BD00A3BC0C /* configd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EB90108395BE00A3BC0C /* scselect */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scselect; sourceTree = BUILT_PRODUCTS_DIR; };
-               1583EBB6108395BE00A3BC0C /* scutil */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scutil; sourceTree = BUILT_PRODUCTS_DIR; };
                158AD8700754E3D400124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD8C00754E3EF00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD9100754E40E00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD8700754E3D400124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD8C00754E3EF00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                158AD9100754E40E00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-               158AD9F80754EA2F00124717 /* AppleTalk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleTalk.framework; path = /System/Library/Frameworks/AppleTalk.framework; sourceTree = "<absolute>"; };
+               1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = libSystemConfiguration_server.c; path = libSystemConfiguration/libSystemConfiguration_server.c; sourceTree = "<group>"; 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 = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                159A7513107FEAA400A57EAB /* VPNPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNPrivate.h; sourceTree = "<group>"; };
                159A7515107FEAA400A57EAB /* VPNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNConfiguration.h; sourceTree = "<group>"; };
                159A7517107FEAA400A57EAB /* VPNPrivate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNPrivate.c; sourceTree = "<group>"; };
                159A7519107FEAA400A57EAB /* VPNConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNConfiguration.c; sourceTree = "<group>"; };
                159A7513107FEAA400A57EAB /* VPNPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNPrivate.h; sourceTree = "<group>"; };
                159A7515107FEAA400A57EAB /* VPNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNConfiguration.h; sourceTree = "<group>"; };
                159A7517107FEAA400A57EAB /* VPNPrivate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNPrivate.c; sourceTree = "<group>"; };
                159A7519107FEAA400A57EAB /* VPNConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNConfiguration.c; sourceTree = "<group>"; };
+               159C9A8D17399609003DDA1D /* dnsinfo_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dnsinfo_internal.h; path = dnsinfo/dnsinfo_internal.h; sourceTree = "<group>"; };
                159D53A707528B36004F8947 /* ip_plugin.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = ip_plugin.c; sourceTree = "<group>"; };
                159D53AA07528B36004F8947 /* dns-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "dns-configuration.c"; sourceTree = "<group>"; };
                159D53AB07528B36004F8947 /* set-hostname.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "set-hostname.c"; sourceTree = "<group>"; };
                159D53A707528B36004F8947 /* ip_plugin.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = ip_plugin.c; sourceTree = "<group>"; };
                159D53AA07528B36004F8947 /* dns-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "dns-configuration.c"; sourceTree = "<group>"; };
                159D53AB07528B36004F8947 /* set-hostname.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "set-hostname.c"; sourceTree = "<group>"; };
                15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnelPrivate.h; sourceTree = "<group>"; };
                15AAA7F2108E310700C2A607 /* VPNTunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnel.h; sourceTree = "<group>"; };
                15AAA7F3108E310700C2A607 /* VPNTunnel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNTunnel.c; sourceTree = "<group>"; };
                15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnelPrivate.h; sourceTree = "<group>"; };
                15AAA7F2108E310700C2A607 /* VPNTunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnel.h; sourceTree = "<group>"; };
                15AAA7F3108E310700C2A607 /* VPNTunnel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNTunnel.c; sourceTree = "<group>"; };
+               15AB751916EBFF3400FAA8CE /* libSCNetworkReachability_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSCNetworkReachability_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               15AB751F16EBFF8A00FAA8CE /* SCNetworkReachability.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SCNetworkReachability.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+               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 = "<group>"; };
                15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationInternal.c; sourceTree = "<group>"; };
                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfigurationInternal.h; sourceTree = "<group>"; };
                15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfiguration.h; sourceTree = "<group>"; };
                15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationInternal.c; sourceTree = "<group>"; };
                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfigurationInternal.h; sourceTree = "<group>"; };
                15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkProtocol.c; sourceTree = "<group>"; };
                15AD7A3D0670A85900BFE03C /* SCNetworkService.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkService.c; sourceTree = "<group>"; };
                15AD7A3E0670A85900BFE03C /* SCNetworkSet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSet.c; sourceTree = "<group>"; };
                15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkProtocol.c; sourceTree = "<group>"; };
                15AD7A3D0670A85900BFE03C /* SCNetworkService.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkService.c; sourceTree = "<group>"; };
                15AD7A3E0670A85900BFE03C /* SCNetworkSet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSet.c; sourceTree = "<group>"; };
-               15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = AspenSDK.xcconfig; path = AppleInternal/XcodeConfig/AspenSDK.xcconfig; sourceTree = DEVELOPER_DIR; };
                15B686220678B65C00FF4023 /* NetworkConfiguration.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = NetworkConfiguration.plist; sourceTree = "<group>"; };
                15B73F0805FD1B670096477F /* dnsinfo_copy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_copy.c; path = dnsinfo/dnsinfo_copy.c; sourceTree = "<group>"; };
                15B73F0905FD1B670096477F /* dnsinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo.h; path = dnsinfo/dnsinfo.h; sourceTree = "<group>"; };
                15B686220678B65C00FF4023 /* NetworkConfiguration.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = NetworkConfiguration.plist; sourceTree = "<group>"; };
                15B73F0805FD1B670096477F /* dnsinfo_copy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_copy.c; path = dnsinfo/dnsinfo_copy.c; sourceTree = "<group>"; };
                15B73F0905FD1B670096477F /* dnsinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo.h; path = dnsinfo/dnsinfo.h; sourceTree = "<group>"; };
-               15B73F0B05FD1B670096477F /* dnsinfo_private.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_private.c; path = dnsinfo/dnsinfo_private.c; sourceTree = "<group>"; };
                15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = "<group>"; };
                15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = "<group>"; };
                15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = "<group>"; };
                15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
                15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_client.c; path = reachability/SCNetworkReachabilityServer_client.c; sourceTree = "<group>"; };
                15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = "<group>"; };
                15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = "<group>"; };
                15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = "<group>"; };
                15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = "<absolute>"; };
                15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_client.c; path = reachability/SCNetworkReachabilityServer_client.c; sourceTree = "<group>"; };
-               15C330B8134B92780028E36B /* rb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rb.c; path = reachability/rb.c; sourceTree = "<group>"; };
-               15C330B9134B92780028E36B /* rb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rb.h; path = reachability/rb.h; sourceTree = "<group>"; };
                15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_server.c; path = reachability/SCNetworkReachabilityServer_server.c; sourceTree = "<group>"; };
                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = "<group>"; };
                15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_server.c; path = reachability/SCNetworkReachabilityServer_server.c; sourceTree = "<group>"; };
                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = "<group>"; };
+               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 = "<group>"; };
                15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = "<group>"; };
                15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = "<group>"; };
                15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = "<group>"; };
                15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = "<group>"; };
                15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = "<group>"; };
                15CB694105C0722B0099E85F /* moh_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh_msg.h; sourceTree = "<group>"; };
                15CB694305C0722B0099E85F /* moh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh.h; sourceTree = "<group>"; };
                15CB694505C0722B0099E85F /* DeviceOnHold.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceOnHold.h; sourceTree = "<group>"; };
                15CB694105C0722B0099E85F /* moh_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh_msg.h; sourceTree = "<group>"; };
                15CB694305C0722B0099E85F /* moh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh.h; sourceTree = "<group>"; };
                15CB694505C0722B0099E85F /* DeviceOnHold.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceOnHold.h; sourceTree = "<group>"; };
-               15CB694705C0722B0099E85F /* LinkConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LinkConfiguration.h; sourceTree = "<group>"; };
                15CB694905C0722B0099E85F /* dy_framework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dy_framework.h; sourceTree = "<group>"; };
                15CB695005C0722B0099E85F /* SCD.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCD.c; sourceTree = "<group>"; };
                15CB695205C0722B0099E85F /* SCDKeys.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCDKeys.c; sourceTree = "<group>"; };
                15CB694905C0722B0099E85F /* dy_framework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dy_framework.h; sourceTree = "<group>"; };
                15CB695005C0722B0099E85F /* SCD.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCD.c; sourceTree = "<group>"; };
                15CB695205C0722B0099E85F /* SCDKeys.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCDKeys.c; sourceTree = "<group>"; };
                15CB69A005C0722B0099E85F /* SCLocation.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCLocation.c; sourceTree = "<group>"; };
                15CB69A205C0722B0099E85F /* SCNetwork.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetwork.c; sourceTree = "<group>"; };
                15CB69A405C0722B0099E85F /* SCNetworkConnection.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkConnection.c; sourceTree = "<group>"; };
                15CB69A005C0722B0099E85F /* SCLocation.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCLocation.c; sourceTree = "<group>"; };
                15CB69A205C0722B0099E85F /* SCNetwork.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetwork.c; sourceTree = "<group>"; };
                15CB69A405C0722B0099E85F /* SCNetworkConnection.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkConnection.c; sourceTree = "<group>"; };
-               15CB69A605C0722B0099E85F /* SCNetworkReachability.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkReachability.c; sourceTree = "<group>"; };
+               15CB69A605C0722B0099E85F /* SCNetworkReachability.c */ = {isa = PBXFileReference; indentWidth = 8; lastKnownFileType = sourcecode.c.c; path = SCNetworkReachability.c; sourceTree = "<group>"; };
                15CB69A805C0722B0099E85F /* SCProxies.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCProxies.c; sourceTree = "<group>"; };
                15CB69AC05C0722B0099E85F /* DHCP.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = DHCP.c; sourceTree = "<group>"; };
                15CB69AE05C0722B0099E85F /* moh.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = moh.c; sourceTree = "<group>"; };
                15CB69A805C0722B0099E85F /* SCProxies.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCProxies.c; sourceTree = "<group>"; };
                15CB69AC05C0722B0099E85F /* DHCP.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = DHCP.c; sourceTree = "<group>"; };
                15CB69AE05C0722B0099E85F /* moh.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = moh.c; sourceTree = "<group>"; };
                15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = "<group>"; };
                15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
                15CFC229068B222F00123568 /* get-mobility-info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "get-mobility-info"; sourceTree = SOURCE_ROOT; };
                15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = "<group>"; };
                15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
                15CFC229068B222F00123568 /* get-mobility-info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "get-mobility-info"; sourceTree = SOURCE_ROOT; };
+               15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSimulatorSupport_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulatorSupport.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+               15D3083616F3EB7200014F82 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SimulatorSupport/Info.plist; sourceTree = "<group>"; };
+               15D3083816F3EB8600014F82 /* simulator_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulator_support.c; path = Plugins/SimulatorSupport/simulator_support.c; sourceTree = "<group>"; };
+               15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.configd_sim.plist; sourceTree = "<group>"; };
                15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = "<group>"; };
                15D9DCFA10DD90A1004E545D /* AppWorkaround.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppWorkaround.plist; sourceTree = "<group>"; };
                15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = "<group>"; };
                15D9DCFA10DD90A1004E545D /* AppWorkaround.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppWorkaround.plist; sourceTree = "<group>"; };
-               15DAD5EE075913CE0084A6ED /* libdnsinfo.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdnsinfo.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               15DAD5EE075913CE0084A6ED /* libsystem_configuration.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_configuration.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                15DAF2D808466D4900D1B2BD /* SCHelper_client.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = SCHelper_client.c; path = helper/SCHelper_client.c; sourceTree = "<group>"; };
                15DAF2D908466D4900D1B2BD /* SCHelper_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = SCHelper_server.c; path = helper/SCHelper_server.c; sourceTree = "<group>"; };
                15DC34670711D49400A3311C /* net_interface.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_interface.c; sourceTree = "<group>"; };
                15DAF2D808466D4900D1B2BD /* SCHelper_client.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = SCHelper_client.c; path = helper/SCHelper_client.c; sourceTree = "<group>"; };
                15DAF2D908466D4900D1B2BD /* SCHelper_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = SCHelper_server.c; path = helper/SCHelper_server.c; sourceTree = "<group>"; };
                15DC34670711D49400A3311C /* net_interface.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_interface.c; sourceTree = "<group>"; };
                15DC346C0711D49400A3311C /* net_service.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_service.h; sourceTree = "<group>"; };
                15DC346D0711D49400A3311C /* net_set.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_set.c; sourceTree = "<group>"; };
                15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = "<group>"; };
                15DC346C0711D49400A3311C /* net_service.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_service.h; sourceTree = "<group>"; };
                15DC346D0711D49400A3311C /* net_set.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_set.c; sourceTree = "<group>"; };
                15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = "<group>"; };
+               15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPMonitor_sim.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15FC12F20CCEA4F00013872C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = SCMonitor/Info.plist; sourceTree = "<group>"; };
                15FC130A0CCEA59E0013872C /* monitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor.c; path = SCMonitor/monitor.c; sourceTree = "<group>"; };
                15FC12F20CCEA4F00013872C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = SCMonitor/Info.plist; sourceTree = "<group>"; };
                15FC130A0CCEA59E0013872C /* monitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor.c; path = SCMonitor/monitor.c; sourceTree = "<group>"; };
-               15FCAACF05FD0EBF00CB79E6 /* shared_dns_info_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = shared_dns_info_types.h; path = dnsinfo/shared_dns_info_types.h; sourceTree = SOURCE_ROOT; };
-               15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; name = shared_dns_info.defs; path = dnsinfo/shared_dns_info.defs; sourceTree = "<group>"; };
                15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = IndigoSDK.xcconfig; path = /AppleInternal/Indigo/IndigoSDK.xcconfig; sourceTree = "<absolute>"; };
                15FD72970754DA2B001CC321 /* InterfaceNamer.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InterfaceNamer.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15FD72A50754DA4C001CC321 /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = IndigoSDK.xcconfig; path = /AppleInternal/Indigo/IndigoSDK.xcconfig; sourceTree = "<absolute>"; };
                15FD72970754DA2B001CC321 /* InterfaceNamer.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InterfaceNamer.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                15FD72A50754DA4C001CC321 /* IPMonitor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPMonitor.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
                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; };
                72B43726113C7BFC00EBF1B6 /* nc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nc.h; sourceTree = "<group>"; };
                72B43727113C7BFC00EBF1B6 /* nc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nc.c; sourceTree = "<group>"; };
                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; };
                72B43726113C7BFC00EBF1B6 /* nc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nc.h; sourceTree = "<group>"; };
                72B43727113C7BFC00EBF1B6 /* nc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nc.c; sourceTree = "<group>"; };
+               72C3E82615003E78000D68CB /* MobileInstallation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileInstallation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.Internal.sdk/System/Library/PrivateFrameworks/MobileInstallation.framework; sourceTree = DEVELOPER_DIR; };
                9EE943F306AF409B00772EB5 /* BondConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = BondConfiguration.c; sourceTree = "<group>"; };
                9EE943F306AF409B00772EB5 /* BondConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = BondConfiguration.c; sourceTree = "<group>"; };
+               B03FEFB516376D2800A1B88F /* VPNAppLayer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNAppLayer.c; sourceTree = "<group>"; };
+               B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkConnectionInternal.h; sourceTree = "<group>"; };
+               B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VPNAppLayerPrivate.h; sourceTree = "<group>"; tabWidth = 4; };
+               B0BF3440174594C400961734 /* entitlements-osx.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "entitlements-osx.plist"; sourceTree = "<group>"; };
+               B0C967F717441F0E00889853 /* SNHelperPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNHelperPrivate.h; sourceTree = "<group>"; };
+               B0C9689B174426C200889853 /* SNHelper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SNHelper.c; sourceTree = "<group>"; };
+               C4CDB8111631933400819B44 /* VPNFlow.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VPNFlow.h; sourceTree = "<group>"; tabWidth = 4; };
+               C4CDB8121631933400819B44 /* VPNFlowPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VPNFlowPrivate.h; sourceTree = "<group>"; };
+               C4CDB8141631935700819B44 /* VPNFlow.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = VPNFlow.c; sourceTree = "<group>"; tabWidth = 4; };
+               C4F1847F16237AFC00D97043 /* VPNService.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNService.c; sourceTree = "<group>"; };
+               D61AAEAD1522C99C0066B003 /* scprefs_observer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scprefs_observer.c; sourceTree = "<group>"; };
+               D61AAEB41522C9BD0066B003 /* scprefs_observer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scprefs_observer.h; sourceTree = "<group>"; };
+               D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.networking.IPMonitor; sourceTree = "<group>"; };
                D6986A75136891120091C931 /* network_information_priv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information_priv.c; path = nwi/network_information_priv.c; sourceTree = "<group>"; };
                D6986A761368911E0091C931 /* network_information_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information_priv.h; path = nwi/network_information_priv.h; sourceTree = "<group>"; };
                D6986A77136891300091C931 /* network_information.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information.c; path = nwi/network_information.c; sourceTree = "<group>"; };
                D6986A781368913C0091C931 /* network_information.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information.h; path = nwi/network_information.h; sourceTree = "<group>"; };
                D6986A75136891120091C931 /* network_information_priv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information_priv.c; path = nwi/network_information_priv.c; sourceTree = "<group>"; };
                D6986A761368911E0091C931 /* network_information_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information_priv.h; path = nwi/network_information_priv.h; sourceTree = "<group>"; };
                D6986A77136891300091C931 /* network_information.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information.c; path = nwi/network_information.c; sourceTree = "<group>"; };
                D6986A781368913C0091C931 /* network_information.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information.h; path = nwi/network_information.h; sourceTree = "<group>"; };
+               D6AEB89815AE4446009F2FAF /* ip_plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ip_plugin.h; sourceTree = "<group>"; };
                F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSignature.c; sourceTree = "<group>"; };
                F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignature.h; sourceTree = "<group>"; };
                F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignaturePrivate.h; sourceTree = "<group>"; };
                F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSignature.c; sourceTree = "<group>"; };
                F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignature.h; sourceTree = "<group>"; };
                F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignaturePrivate.h; sourceTree = "<group>"; };
+               F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = IPMonitorControlPrefs.c; sourceTree = "<group>"; };
+               F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPMonitorControlPrefs.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                        files = (
                                1558481907550EC10046C2E9 /* CoreFoundation.framework in Frameworks */,
                                1559C44E0D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
                        files = (
                                1558481907550EC10046C2E9 /* CoreFoundation.framework in Frameworks */,
                                1559C44E0D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */,
+                               15D2E437167643460078F547 /* Security.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        buildActionMask = 2147483647;
                        files = (
                                1572C5240CFB55B400E2776E /* CoreFoundation.framework in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                1572C5240CFB55B400E2776E /* CoreFoundation.framework in Frameworks */,
+                               B03FEFBB16382C1300A1B88F /* libbsm.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732A9B16EA503200F3AC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732A9C16EA503200F3AC4C /* CoreFoundation.framework in Frameworks */,
+                               15732A9D16EA503200F3AC4C /* SystemConfiguration.framework in Frameworks */,
+                               15732A9E16EA503200F3AC4C /* IOKit.framework in Frameworks */,
+                               15732A9F16EA503200F3AC4C /* Security.framework in Frameworks */,
+                               15732AA016EA503200F3AC4C /* libbsm.dylib in Frameworks */,
+                               15AB752D16EC2AE900FAA8CE /* libIPMonitor_sim.a in Frameworks */,
+                               15AB752E16EC2AE900FAA8CE /* libSCNetworkReachability_sim.a in Frameworks */,
+                               15D3083316F3EB0700014F82 /* libSimulatorSupport_sim.a in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732ACD16EA511900F3AC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732ACE16EA511900F3AC4C /* CoreFoundation.framework in Frameworks */,
+                               15732ACF16EA511900F3AC4C /* SystemConfiguration.framework in Frameworks */,
+                               15732AD016EA511900F3AC4C /* libedit.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732AE016EA6B6700F3AC4C /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1574340E0D4A8137002ACA73 /* CoreFoundation.framework in Frameworks */,
                                1574340F0D4A8137002ACA73 /* SystemConfiguration.framework in Frameworks */,
                                157434110D4A8137002ACA73 /* libedit.dylib in Frameworks */,
                                1574340E0D4A8137002ACA73 /* CoreFoundation.framework in Frameworks */,
                                1574340F0D4A8137002ACA73 /* SystemConfiguration.framework in Frameworks */,
                                157434110D4A8137002ACA73 /* libedit.dylib in Frameworks */,
+                               72C3E82715003E78000D68CB /* MobileInstallation.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EA0C108395BB00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EA93108395BB00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA94108395BB00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EAA1108395BB00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAA2108395BB00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                               1583EAA3108395BB00A3BC0C /* SystemConfiguration.framework in Frameworks */,
-                               1583EAA4108395BB00A3BC0C /* Security.framework in Frameworks */,
-                               15F21619110F826800E89CF7 /* libbsm.dylib in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB19108395BC00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB1A108395BC00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                               1583EB1B108395BC00A3BC0C /* SystemConfiguration.framework in Frameworks */,
-                               1583EB1C108395BC00A3BC0C /* IOKit.framework in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB73108395BD00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB74108395BD00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                               1583EB75108395BD00A3BC0C /* SystemConfiguration.framework in Frameworks */,
-                               1583EB76108395BD00A3BC0C /* IOKit.framework in Frameworks */,
-                               1583EB77108395BD00A3BC0C /* Security.framework in Frameworks */,
-                               1583EB78108395BD00A3BC0C /* libbsm.dylib in Frameworks */,
-                               1583EB79108395BD00A3BC0C /* libKernelEventMonitor.a in Frameworks */,
-                               1583EB7A108395BD00A3BC0C /* libInterfaceNamer.a in Frameworks */,
-                               1583EB7B108395BD00A3BC0C /* libIPMonitor.a in Frameworks */,
-                               1583EB7C108395BD00A3BC0C /* libLinkConfiguration.a in Frameworks */,
-                               1583EB7E108395BD00A3BC0C /* libPreferencesMonitor.a in Frameworks */,
-                               1528C01A135746D700691881 /* libSCNetworkReachability.a in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB8A108395BE00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB8B108395BE00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                               1583EB8C108395BE00A3BC0C /* SystemConfiguration.framework in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EBAF108395BE00A3BC0C /* Frameworks */ = {
-                       isa = PBXFrameworksBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EBB0108395BE00A3BC0C /* CoreFoundation.framework in Frameworks */,
-                               1583EBB1108395BE00A3BC0C /* SystemConfiguration.framework in Frameworks */,
-                               1583EBB2108395BE00A3BC0C /* libedit.dylib in Frameworks */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                159D54CA07529FFF004F8947 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                159D54CA07529FFF004F8947 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        buildActionMask = 2147483647;
                        files = (
                                15A5A2630D5B94190087BDA0 /* CoreFoundation.framework in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                15A5A2630D5B94190087BDA0 /* CoreFoundation.framework in Frameworks */,
+                               B0FEF41A164406F400174B99 /* libbsm.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        buildActionMask = 2147483647;
                        files = (
                                15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */,
                        buildActionMask = 2147483647;
                        files = (
                                15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */,
+                               B03FEFBA16382C0700A1B88F /* libbsm.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
-               1513E399108420A700088779 /* EmbeddedOther */ = {
-                       isa = PBXGroup;
-                       children = (
-                               1583EA10108395BB00A3BC0C /* libdnsinfo.dylib */,
-                               1583EA99108395BB00A3BC0C /* SystemConfiguration.framework */,
-                               1513E39D108420DE00088779 /* Plugins */,
-                               1583EAAA108395BB00A3BC0C /* SCHelper */,
-                               1513E3A11084216500088779 /* configd, scutil, scselect */,
-                       );
-                       name = EmbeddedOther;
-                       sourceTree = "<group>";
-               };
-               1513E39D108420DE00088779 /* Plugins */ = {
-                       isa = PBXGroup;
-                       children = (
-                               1583EAD8108395BB00A3BC0C /* libIPMonitor.a */,
-                               1583EADE108395BB00A3BC0C /* IPMonitor.bundle */,
-                               1583EAE7108395BB00A3BC0C /* libInterfaceNamer.a */,
-                               1583EAED108395BC00A3BC0C /* InterfaceNamer.bundle */,
-                               1583EAFF108395BC00A3BC0C /* libKernelEventMonitor.a */,
-                               1583EB05108395BC00A3BC0C /* KernelEventMonitor.bundle */,
-                               1583EB0E108395BC00A3BC0C /* libLinkConfiguration.a */,
-                               1583EB14108395BC00A3BC0C /* LinkConfiguration.bundle */,
-                               1583EB21108395BC00A3BC0C /* Logger.bundle */,
-                               1583EB39108395BD00A3BC0C /* libPreferencesMonitor.a */,
-                               1583EB3F108395BD00A3BC0C /* PreferencesMonitor.bundle */,
-                               1528C0061357401900691881 /* libSCNetworkReachability.a */,
-                               1528C00D1357401D00691881 /* SCNetworkReachability.bundle */,
-                       );
-                       name = Plugins;
-                       sourceTree = "<group>";
-               };
-               1513E3A11084216500088779 /* configd, scutil, scselect */ = {
-                       isa = PBXGroup;
-                       children = (
-                               1583EB84108395BD00A3BC0C /* configd */,
-                               1583EB90108395BE00A3BC0C /* scselect */,
-                               1583EBB6108395BE00A3BC0C /* scutil */,
-                       );
-                       name = "configd, scutil, scselect";
-                       sourceTree = "<group>";
-               };
                151F5DA80CCE995D0093AC3B /* SCMonitor */ = {
                        isa = PBXGroup;
                        children = (
                151F5DA80CCE995D0093AC3B /* SCMonitor */ = {
                        isa = PBXGroup;
                        children = (
                154083530D5B824400E07907 /* MacOSX */ = {
                        isa = PBXGroup;
                        children = (
                154083530D5B824400E07907 /* MacOSX */ = {
                        isa = PBXGroup;
                        children = (
-                               15DAD5EE075913CE0084A6ED /* libdnsinfo.dylib */,
+                               15DAD5EE075913CE0084A6ED /* libsystem_configuration.dylib */,
                                1547072E0D1F70C80075C28D /* SystemConfiguration.framework */,
                                1547001D08455B98006787CE /* SCHelper */,
                                151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */,
                                1547072E0D1F70C80075C28D /* SystemConfiguration.framework */,
                                1547001D08455B98006787CE /* SCHelper */,
                                151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */,
                1540835A0D5B825200E07907 /* Embedded */ = {
                        isa = PBXGroup;
                        children = (
                1540835A0D5B825200E07907 /* Embedded */ = {
                        isa = PBXGroup;
                        children = (
-                               157A84E80D56C63900B6F1A0 /* libdnsinfo.dylib */,
+                               157A84E80D56C63900B6F1A0 /* libsystem_configuration.dylib */,
                                1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */,
                                154083C50D5B832F00E07907 /* Plugins */,
                                1559C4470D349A4E0098FD59 /* SCHelper */,
                                1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */,
                                154083C50D5B832F00E07907 /* Plugins */,
                                1559C4470D349A4E0098FD59 /* SCHelper */,
                        isa = PBXGroup;
                        children = (
                                15A5A26A0D5B94190087BDA0 /* SystemConfiguration.framework */,
                        isa = PBXGroup;
                        children = (
                                15A5A26A0D5B94190087BDA0 /* SystemConfiguration.framework */,
+                               1541472016EBF5C500B197B9 /* Plugins */,
+                               1541471F16EBF32B00B197B9 /* configd, scutil */,
                        );
                        name = EmbeddedSimulator;
                        sourceTree = "<group>";
                        );
                        name = EmbeddedSimulator;
                        sourceTree = "<group>";
                        name = "configd, scutil, scselect";
                        sourceTree = "<group>";
                };
                        name = "configd, scutil, scselect";
                        sourceTree = "<group>";
                };
+               1541471F16EBF32B00B197B9 /* configd, scutil */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = "configd, scutil";
+                       sourceTree = "<group>";
+               };
+               1541472016EBF5C500B197B9 /* Plugins */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = Plugins;
+                       sourceTree = "<group>";
+               };
                1547002E084561B4006787CE /* SCHelper */ = {
                        isa = PBXGroup;
                        children = (
                1547002E084561B4006787CE /* SCHelper */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                15B73F0905FD1B670096477F /* dnsinfo.h */,
                                1532629006281C9D00B1C10C /* dnsinfo_create.h */,
                        children = (
                                15B73F0905FD1B670096477F /* dnsinfo.h */,
                                1532629006281C9D00B1C10C /* dnsinfo_create.h */,
+                               159C9A8D17399609003DDA1D /* dnsinfo_internal.h */,
                                15B73F0C05FD1B670096477F /* dnsinfo_private.h */,
                                15B73F0E05FD1B670096477F /* dnsinfo_server.h */,
                        );
                                15B73F0C05FD1B670096477F /* dnsinfo_private.h */,
                                15B73F0E05FD1B670096477F /* dnsinfo_server.h */,
                        );
                1582B37905FD1A66009C2750 /* Sources */ = {
                        isa = PBXGroup;
                        children = (
                1582B37905FD1A66009C2750 /* Sources */ = {
                        isa = PBXGroup;
                        children = (
-                               15B73F0B05FD1B670096477F /* dnsinfo_private.c */,
                                15B73F0805FD1B670096477F /* dnsinfo_copy.c */,
                                1521FC5C060F296A003B28F5 /* dnsinfo_create.c */,
                                1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */,
                                15B73F0805FD1B670096477F /* dnsinfo_copy.c */,
                                1521FC5C060F296A003B28F5 /* dnsinfo_create.c */,
                                1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */,
                                1531D3D90E93E6AA00248432 /* Logger */,
                                159D53C207528B36004F8947 /* PreferencesMonitor */,
                                1528BFDA13572FC200691881 /* SCNetworkReachability */,
                                1531D3D90E93E6AA00248432 /* Logger */,
                                159D53C207528B36004F8947 /* PreferencesMonitor */,
                                1528BFDA13572FC200691881 /* SCNetworkReachability */,
+                               15D3080E16F3E49F00014F82 /* SimulatorSupport */,
                        );
                        name = Plugins;
                        sourceTree = "<group>";
                        );
                        name = Plugins;
                        sourceTree = "<group>";
                159D53A607528B36004F8947 /* IPMonitor */ = {
                        isa = PBXGroup;
                        children = (
                159D53A607528B36004F8947 /* IPMonitor */ = {
                        isa = PBXGroup;
                        children = (
+                               D6AEB89815AE4446009F2FAF /* ip_plugin.h */,
                                159D53A707528B36004F8947 /* ip_plugin.c */,
                                155D22380AF13A7300D52ED0 /* dns-configuration.h */,
                                159D53AA07528B36004F8947 /* dns-configuration.c */,
                                159D53A707528B36004F8947 /* ip_plugin.c */,
                                155D22380AF13A7300D52ED0 /* dns-configuration.h */,
                                159D53AA07528B36004F8947 /* dns-configuration.c */,
                                155D223A0AF13A7300D52ED0 /* smb-configuration.h */,
                                1572EB7A0A506D3B00D02459 /* smb-configuration.c */,
                                15FD743E0754DE7A001CC321 /* Info.plist */,
                                155D223A0AF13A7300D52ED0 /* smb-configuration.h */,
                                1572EB7A0A506D3B00D02459 /* smb-configuration.c */,
                                15FD743E0754DE7A001CC321 /* Info.plist */,
+                               D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */,
                        );
                        name = IPMonitor;
                        path = Plugins/IPMonitor;
                        );
                        name = IPMonitor;
                        path = Plugins/IPMonitor;
                159D53C907528B36004F8947 /* common */ = {
                        isa = PBXGroup;
                        children = (
                159D53C907528B36004F8947 /* common */ = {
                        isa = PBXGroup;
                        children = (
+                               F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */,
+                               F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */,
                                159D53CA07528B36004F8947 /* cache.c */,
                                159D53CB07528B36004F8947 /* cache.h */,
                        );
                                159D53CA07528B36004F8947 /* cache.c */,
                                159D53CB07528B36004F8947 /* cache.h */,
                        );
                        path = Plugins/common;
                        sourceTree = "<group>";
                };
                        path = Plugins/common;
                        sourceTree = "<group>";
                };
+               15B534AD14BE778800EA6522 /* libsystem_configuration */ = {
+                       isa = PBXGroup;
+                       children = (
+                               153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */,
+                               153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */,
+                               1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */,
+                               1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */,
+                               1582B36B05FD1A4D009C2750 /* DNSConfiguration */,
+                               D6986A70136890B60091C931 /* NetworkInformation */,
+                       );
+                       name = libsystem_configuration;
+                       sourceTree = "<group>";
+               };
                15B6861D0678B61900FF4023 /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                15B6861D0678B61900FF4023 /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                15CB693705C0722B0099E85F /* SCNetworkReachability.h */,
                                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */,
                        children = (
                                15CB693705C0722B0099E85F /* SCNetworkReachability.h */,
                                15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */,
-                               15C330B9134B92780028E36B /* rb.h */,
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        );
                        name = Headers;
                        sourceTree = "<group>";
                                15CB69A605C0722B0099E85F /* SCNetworkReachability.c */,
                                15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */,
                                15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */,
                                15CB69A605C0722B0099E85F /* SCNetworkReachability.c */,
                                15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */,
                                15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */,
-                               15C330B8134B92780028E36B /* rb.c */,
                        );
                        name = Sources;
                        sourceTree = "<group>";
                        );
                        name = Sources;
                        sourceTree = "<group>";
                                15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */,
                                155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */,
                                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */,
                                15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */,
                                155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */,
                                15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */,
-                               15CB694705C0722B0099E85F /* LinkConfiguration.h */,
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        );
                        name = Headers;
                        sourceTree = "<group>";
                                9EE943F306AF409B00772EB5 /* BondConfiguration.c */,
                                15FD7B3B101E439200C56621 /* BridgeConfiguration.c */,
                                15CB69B605C0722B0099E85F /* VLANConfiguration.c */,
                                9EE943F306AF409B00772EB5 /* BondConfiguration.c */,
                                15FD7B3B101E439200C56621 /* BridgeConfiguration.c */,
                                15CB69B605C0722B0099E85F /* VLANConfiguration.c */,
+                               C4F1847F16237AFC00D97043 /* VPNService.c */,
                        );
                        name = Sources;
                        sourceTree = "<group>";
                        );
                        name = Sources;
                        sourceTree = "<group>";
                15C330E0134B9C4C0028E36B /* Headers */ = {
                        isa = PBXGroup;
                        children = (
                15C330E0134B9C4C0028E36B /* Headers */ = {
                        isa = PBXGroup;
                        children = (
+                               B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */,
                                15CB693505C0722B0099E85F /* SCNetworkConnection.h */,
                                15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */,
                                23C1E2BE062DD5DB00835B54 /* pppcontroller.h */,
                                15CB693505C0722B0099E85F /* SCNetworkConnection.h */,
                                15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */,
                                23C1E2BE062DD5DB00835B54 /* pppcontroller.h */,
                15C330E2134B9C9B0028E36B /* Sources */ = {
                        isa = PBXGroup;
                        children = (
                15C330E2134B9C9B0028E36B /* Sources */ = {
                        isa = PBXGroup;
                        children = (
+                               B0C9689B174426C200889853 /* SNHelper.c */,
+                               B03FEFB516376D2800A1B88F /* VPNAppLayer.c */,
+                               C4CDB8141631935700819B44 /* VPNFlow.c */,
                                159A7517107FEAA400A57EAB /* VPNPrivate.c */,
                                159A7519107FEAA400A57EAB /* VPNConfiguration.c */,
                                15AAA7F3108E310700C2A607 /* VPNTunnel.c */,
                                159A7517107FEAA400A57EAB /* VPNPrivate.c */,
                                159A7519107FEAA400A57EAB /* VPNConfiguration.c */,
                                15AAA7F3108E310700C2A607 /* VPNTunnel.c */,
                15C330E3134B9CA30028E36B /* Headers */ = {
                        isa = PBXGroup;
                        children = (
                15C330E3134B9CA30028E36B /* Headers */ = {
                        isa = PBXGroup;
                        children = (
+                               B0C967F717441F0E00889853 /* SNHelperPrivate.h */,
+                               B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */,
+                               C4CDB8111631933400819B44 /* VPNFlow.h */,
+                               C4CDB8121631933400819B44 /* VPNFlowPrivate.h */,
                                159A7513107FEAA400A57EAB /* VPNPrivate.h */,
                                159A7515107FEAA400A57EAB /* VPNConfiguration.h */,
                                15AAA7F2108E310700C2A607 /* VPNTunnel.h */,
                                159A7513107FEAA400A57EAB /* VPNPrivate.h */,
                                159A7515107FEAA400A57EAB /* VPNConfiguration.h */,
                                15AAA7F2108E310700C2A607 /* VPNTunnel.h */,
                        children = (
                                15CB6A8605C072500099E85F /* MiG */,
                                15CB6A8305C072410099E85F /* Schema */,
                        children = (
                                15CB6A8605C072500099E85F /* MiG */,
                                15CB6A8305C072410099E85F /* Schema */,
-                               D6986A70136890B60091C931 /* NetworkInformation */,
-                               1582B36B05FD1A4D009C2750 /* DNSConfiguration */,
+                               15B534AD14BE778800EA6522 /* libsystem_configuration */,
                                15CB690705C0722A0099E85F /* SystemConfiguration */,
                                151F5DA80CCE995D0093AC3B /* SCMonitor */,
                                15CB69C205C0722B0099E85F /* configd */,
                                15CB690705C0722A0099E85F /* SystemConfiguration */,
                                151F5DA80CCE995D0093AC3B /* SCMonitor */,
                                15CB69C205C0722B0099E85F /* configd */,
                                159D53A207528B06004F8947 /* Plugins */,
                                15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */,
                                15CB690F05C0722B0099E85F /* Products */,
                                159D53A207528B06004F8947 /* Plugins */,
                                15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */,
                                15CB690F05C0722B0099E85F /* Products */,
-                               15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */,
                                15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */,
                        );
                        indentWidth = 8;
                                15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */,
                        );
                        indentWidth = 8;
                                154083530D5B824400E07907 /* MacOSX */,
                                1540835A0D5B825200E07907 /* Embedded */,
                                154083890D5B82A900E07907 /* EmbeddedSimulator */,
                                154083530D5B824400E07907 /* MacOSX */,
                                1540835A0D5B825200E07907 /* Embedded */,
                                154083890D5B82A900E07907 /* EmbeddedSimulator */,
-                               1513E399108420A700088779 /* EmbeddedOther */,
+                               15732AAC16EA503300F3AC4C /* configd_sim */,
+                               15732AD516EA511900F3AC4C /* scutil_sim */,
+                               15732AE416EA6B6700F3AC4C /* libsystem_sim_configuration.dylib */,
+                               15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */,
+                               15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */,
+                               15AB751916EBFF3400FAA8CE /* libSCNetworkReachability_sim.a */,
+                               15AB751F16EBFF8A00FAA8CE /* SCNetworkReachability.bundle */,
+                               15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */,
+                               15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                        );
                        name = Products;
                        sourceTree = "<group>";
                                15CB694505C0722B0099E85F /* DeviceOnHold.h */,
                                15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */,
                                15CB694905C0722B0099E85F /* dy_framework.h */,
                                15CB694505C0722B0099E85F /* DeviceOnHold.h */,
                                15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */,
                                15CB694905C0722B0099E85F /* dy_framework.h */,
+                               D61AAEB41522C9BD0066B003 /* scprefs_observer.h */,
                                15CB694305C0722B0099E85F /* moh.h */,
                                15CB694105C0722B0099E85F /* moh_msg.h */,
                        );
                                15CB694305C0722B0099E85F /* moh.h */,
                                15CB694105C0722B0099E85F /* moh_msg.h */,
                        );
                        children = (
                                150607BD075A00A200B147BA /* SCSchemaDefinitions.c */,
                                15CB695005C0722B0099E85F /* SCD.c */,
                        children = (
                                150607BD075A00A200B147BA /* SCSchemaDefinitions.c */,
                                15CB695005C0722B0099E85F /* SCD.c */,
+                               D61AAEAD1522C99C0066B003 /* scprefs_observer.c */,
                                15CB695405C0722B0099E85F /* SCDPrivate.c */,
                                15CB695605C0722B0099E85F /* SCDPlugin.c */,
                                15CB699C05C0722B0099E85F /* SCDConsoleUser.c */,
                                15CB695405C0722B0099E85F /* SCDPrivate.c */,
                                15CB695605C0722B0099E85F /* SCDPlugin.c */,
                                15CB699C05C0722B0099E85F /* SCDConsoleUser.c */,
                15CB6A1805C0722B0099E85F /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                15CB6A1805C0722B0099E85F /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
+                               B0BF3440174594C400961734 /* entitlements-osx.plist */,
                                1540E3600987DA9500157C07 /* com.apple.configd.plist */,
                                1540E3600987DA9500157C07 /* com.apple.configd.plist */,
+                               15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */,
                                15CB6A2005C0722B0099E85F /* configd.8 */,
                                1567333E0DD1FD6500145179 /* entitlements.plist */,
                        );
                                15CB6A2005C0722B0099E85F /* configd.8 */,
                                1567333E0DD1FD6500145179 /* entitlements.plist */,
                        );
                15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */ = {
                        isa = PBXGroup;
                        children = (
                15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */ = {
                        isa = PBXGroup;
                        children = (
-                               158AD9F80754EA2F00124717 /* AppleTalk.framework */,
                                15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */,
                                15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */,
                                1543636A0752D03C00A8EC6C /* IOKit.framework */,
                                1520A3DE0846B2DC0010B584 /* Security.framework */,
                                15BAA32207F0699A00D9EC95 /* libbsm.dylib */,
                                15FEE80D0CCFD341001312F9 /* ApplicationServices.framework */,
                                15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */,
                                1543636A0752D03C00A8EC6C /* IOKit.framework */,
                                1520A3DE0846B2DC0010B584 /* Security.framework */,
                                15BAA32207F0699A00D9EC95 /* libbsm.dylib */,
+                               15AC2D8816C574FE00340E28 /* libcupolicy.dylib */,
                                152CEED0070CF6640050F23C /* libedit.dylib */,
                                152CEED0070CF6640050F23C /* libedit.dylib */,
+                               72C3E82615003E78000D68CB /* MobileInstallation.framework */,
+                               15CAEF381712690500367CE1 /* libcupolicy.dylib */,
                        );
                        name = "External Frameworks and Libraries";
                        sourceTree = "<group>";
                        );
                        name = "External Frameworks and Libraries";
                        sourceTree = "<group>";
                                1514D76D05C08A5F00757DC9 /* config_types.h */,
                                152E0E7E10FE820E00E402F2 /* helper.defs */,
                                152E0E8810FE824000E402F2 /* helper_types.h */,
                                1514D76D05C08A5F00757DC9 /* config_types.h */,
                                152E0E7E10FE820E00E402F2 /* helper.defs */,
                                152E0E8810FE824000E402F2 /* helper_types.h */,
-                               15FCAAD005FD0EBF00CB79E6 /* shared_dns_info.defs */,
-                               15FCAACF05FD0EBF00CB79E6 /* shared_dns_info_types.h */,
                                23C1E2B8062DD45900835B54 /* pppcontroller.defs */,
                                23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */,
                                23C1E2B8062DD45900835B54 /* pppcontroller.defs */,
                                23C1E2B4062DD2C700835B54 /* pppcontroller_types.h */,
+                               1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */,
                        );
                        name = MiG;
                        sourceTree = "<group>";
                };
                        );
                        name = MiG;
                        sourceTree = "<group>";
                };
+               15D3080E16F3E49F00014F82 /* SimulatorSupport */ = {
+                       isa = PBXGroup;
+                       children = (
+                               15D3083816F3EB8600014F82 /* simulator_support.c */,
+                               15D3083616F3EB7200014F82 /* Info.plist */,
+                       );
+                       name = SimulatorSupport;
+                       sourceTree = "<group>";
+               };
                15FF5C390CDF9C4000EEC8AA /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                15FF5C390CDF9C4000EEC8AA /* Supporting Files */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                D6986A781368913C0091C931 /* network_information.h */,
                                D6986A761368911E0091C931 /* network_information_priv.h */,
                        children = (
                                D6986A781368913C0091C931 /* network_information.h */,
                                D6986A761368911E0091C931 /* network_information_priv.h */,
+                               153ACCA714E322D5005029A5 /* network_information_server.h */,
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        );
                        name = Headers;
                        sourceTree = "<group>";
                        children = (
                                D6986A77136891300091C931 /* network_information.c */,
                                D6986A75136891120091C931 /* network_information_priv.c */,
                        children = (
                                D6986A77136891300091C931 /* network_information.c */,
                                D6986A75136891120091C931 /* network_information_priv.c */,
+                               153ACCA614E322D5005029A5 /* network_information_server.c */,
                        );
                        name = Sources;
                        sourceTree = "<group>";
                        );
                        name = Sources;
                        sourceTree = "<group>";
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1528C0001357401900691881 /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                1547001908455B98006787CE /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                1547001908455B98006787CE /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                                1572C4B80CFB55B400E2776E /* SCPreferencesSetSpecific.h in Headers */,
                                1572C4B90CFB55B400E2776E /* SCNetworkConfiguration.h in Headers */,
                                1572C4BA0CFB55B400E2776E /* SCNetworkConfigurationInternal.h in Headers */,
                                1572C4B80CFB55B400E2776E /* SCPreferencesSetSpecific.h in Headers */,
                                1572C4B90CFB55B400E2776E /* SCNetworkConfiguration.h in Headers */,
                                1572C4BA0CFB55B400E2776E /* SCNetworkConfigurationInternal.h in Headers */,
+                               D61AAEB61522C9E60066B003 /* scprefs_observer.h in Headers */,
                                1572C4BB0CFB55B400E2776E /* SCNetwork.h in Headers */,
                                1572C4BC0CFB55B400E2776E /* SCNetworkConnection.h in Headers */,
                                1572C4BD0CFB55B400E2776E /* SCNetworkReachability.h in Headers */,
                                1572C4BB0CFB55B400E2776E /* SCNetwork.h in Headers */,
                                1572C4BC0CFB55B400E2776E /* SCNetworkConnection.h in Headers */,
                                1572C4BD0CFB55B400E2776E /* SCNetworkReachability.h in Headers */,
                                1572C4C00CFB55B400E2776E /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
                                1572C4C10CFB55B400E2776E /* moh_msg.h in Headers */,
                                1572C4C20CFB55B400E2776E /* moh.h in Headers */,
                                1572C4C00CFB55B400E2776E /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
                                1572C4C10CFB55B400E2776E /* moh_msg.h in Headers */,
                                1572C4C20CFB55B400E2776E /* moh.h in Headers */,
+                               C4CDB81A163193AF00819B44 /* VPNFlowPrivate.h in Headers */,
                                1572C4C30CFB55B400E2776E /* DeviceOnHold.h in Headers */,
                                1572C4C50CFB55B400E2776E /* dy_framework.h in Headers */,
                                1572C4C70CFB55B400E2776E /* SCPreferencesPathKey.h in Headers */,
                                1572C4CA0CFB55B400E2776E /* pppcontroller_types.h in Headers */,
                                1572C4C30CFB55B400E2776E /* DeviceOnHold.h in Headers */,
                                1572C4C50CFB55B400E2776E /* dy_framework.h in Headers */,
                                1572C4C70CFB55B400E2776E /* SCPreferencesPathKey.h in Headers */,
                                1572C4CA0CFB55B400E2776E /* pppcontroller_types.h in Headers */,
-                               1572C4CB0CFB55B400E2776E /* pppcontroller.h in Headers */,
+                               1572C581171CD00E00870549 /* pppcontroller_mach_defines.h in Headers */,
                                1572C4CE0CFB55B400E2776E /* SCPreferencesSetSpecificPrivate.h in Headers */,
                                1572C4CE0CFB55B400E2776E /* SCPreferencesSetSpecificPrivate.h in Headers */,
+                               C4CDB819163193AA00819B44 /* VPNFlow.h in Headers */,
                                1572C4CF0CFB55B400E2776E /* SCPreferencesGetSpecificPrivate.h in Headers */,
                                1572C4D00CFB55B400E2776E /* SCNetworkConfigurationPrivate.h in Headers */,
                                1572C4D20CFB55B400E2776E /* SCHelper_client.h in Headers */,
                                1572C4CF0CFB55B400E2776E /* SCPreferencesGetSpecificPrivate.h in Headers */,
                                1572C4D00CFB55B400E2776E /* SCNetworkConfigurationPrivate.h in Headers */,
                                1572C4D20CFB55B400E2776E /* SCHelper_client.h in Headers */,
+                               B0A88CA816397A1200A60B3A /* VPNAppLayerPrivate.h in Headers */,
                                1572C4D40CFB55B400E2776E /* SCNetworkConnectionPrivate.h in Headers */,
                                1572C4D50CFB55B400E2776E /* SCPreferencesKeychainPrivate.h in Headers */,
                                1572C4D60CFB55B400E2776E /* SCSchemaDefinitionsPrivate.h in Headers */,
                                1572C4D70CFB55B400E2776E /* SCNetworkSignature.h in Headers */,
                                1572C4D40CFB55B400E2776E /* SCNetworkConnectionPrivate.h in Headers */,
                                1572C4D50CFB55B400E2776E /* SCPreferencesKeychainPrivate.h in Headers */,
                                1572C4D60CFB55B400E2776E /* SCSchemaDefinitionsPrivate.h in Headers */,
                                1572C4D70CFB55B400E2776E /* SCNetworkSignature.h in Headers */,
+                               B0C9689E174426DD00889853 /* SNHelperPrivate.h in Headers */,
                                1572C4D80CFB55B400E2776E /* SCNetworkSignaturePrivate.h in Headers */,
                                15A1FF3210597F17004C9CC9 /* CaptiveNetwork.h in Headers */,
                                159A751A107FEAA400A57EAB /* VPNPrivate.h in Headers */,
                                159A751C107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
                                15AAA7F5108E310700C2A607 /* VPNTunnel.h in Headers */,
                                15AAA7F4108E310700C2A607 /* VPNTunnelPrivate.h in Headers */,
                                1572C4D80CFB55B400E2776E /* SCNetworkSignaturePrivate.h in Headers */,
                                15A1FF3210597F17004C9CC9 /* CaptiveNetwork.h in Headers */,
                                159A751A107FEAA400A57EAB /* VPNPrivate.h in Headers */,
                                159A751C107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
                                15AAA7F5108E310700C2A607 /* VPNTunnel.h in Headers */,
                                15AAA7F4108E310700C2A607 /* VPNTunnelPrivate.h in Headers */,
-                               15C330C5134B92780028E36B /* rb.h in Headers */,
                                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
                                15D8B22B1450D8450090CECF /* SCD.h in Headers */,
                                15C330D2134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
                                15D8B22B1450D8450090CECF /* SCD.h in Headers */,
+                               B084711016385121006C92A3 /* SCNetworkConnectionInternal.h in Headers */,
+                               1572C4CB0CFB55B400E2776E /* pppcontroller.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               157433DE0D4A8122002ACA73 /* Headers */ = {
+               15732A7716EA503200F3AC4C /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               15732A7816EA503200F3AC4C /* configd.h in Headers */,
+                               15732A7916EA503200F3AC4C /* _SCD.h in Headers */,
+                               15732A7A16EA503200F3AC4C /* configd_server.h in Headers */,
+                               15732A7B16EA503200F3AC4C /* notify_server.h in Headers */,
+                               15732A7C16EA503200F3AC4C /* plugin_support.h in Headers */,
+                               15732A7D16EA503200F3AC4C /* session.h in Headers */,
+                               15732A7E16EA503200F3AC4C /* pattern.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               157433F10D4A8137002ACA73 /* Headers */ = {
+               15732AAE16EA511900F3AC4C /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               157433F20D4A8137002ACA73 /* scutil.h in Headers */,
-                               157433F30D4A8137002ACA73 /* commands.h in Headers */,
-                               157433F40D4A8137002ACA73 /* dictionary.h in Headers */,
-                               157433F50D4A8137002ACA73 /* session.h in Headers */,
-                               157433F60D4A8137002ACA73 /* cache.h in Headers */,
-                               157433F70D4A8137002ACA73 /* notifications.h in Headers */,
-                               157433F80D4A8137002ACA73 /* tests.h in Headers */,
-                               157433F90D4A8137002ACA73 /* prefs.h in Headers */,
-                               157433FA0D4A8137002ACA73 /* net.h in Headers */,
-                               157433FB0D4A8137002ACA73 /* net_interface.h in Headers */,
+                               15732AAF16EA511900F3AC4C /* scutil.h in Headers */,
+                               15732AB016EA511900F3AC4C /* commands.h in Headers */,
+                               15732AB116EA511900F3AC4C /* dictionary.h in Headers */,
+                               15732AB216EA511900F3AC4C /* session.h in Headers */,
+                               15732AB316EA511900F3AC4C /* cache.h in Headers */,
+                               15732AB416EA511900F3AC4C /* notifications.h in Headers */,
+                               15732AB516EA511900F3AC4C /* tests.h in Headers */,
+                               15732AB616EA511900F3AC4C /* prefs.h in Headers */,
+                               15732AB716EA511900F3AC4C /* net.h in Headers */,
+                               15732AB816EA511900F3AC4C /* net_interface.h in Headers */,
+                               15732AB916EA511900F3AC4C /* net_protocol.h in Headers */,
+                               15732ABA16EA511900F3AC4C /* net_service.h in Headers */,
+                               15732ABB16EA511900F3AC4C /* net_set.h in Headers */,
+                               15732ABC16EA511900F3AC4C /* nc.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732AD716EA6B6700F3AC4C /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732AD816EA6B6700F3AC4C /* dnsinfo.h in Headers */,
+                               15732AD916EA6B6700F3AC4C /* network_information.h in Headers */,
+                               15732ADA16EA6B6700F3AC4C /* dnsinfo_private.h in Headers */,
+                               15732ADB16EA6B6700F3AC4C /* libSystemConfiguration_client.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               157433DE0D4A8122002ACA73 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               157433F10D4A8137002ACA73 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               157433F20D4A8137002ACA73 /* scutil.h in Headers */,
+                               157433F30D4A8137002ACA73 /* commands.h in Headers */,
+                               157433F40D4A8137002ACA73 /* dictionary.h in Headers */,
+                               157433F50D4A8137002ACA73 /* session.h in Headers */,
+                               157433F60D4A8137002ACA73 /* cache.h in Headers */,
+                               157433F70D4A8137002ACA73 /* notifications.h in Headers */,
+                               157433F80D4A8137002ACA73 /* tests.h in Headers */,
+                               157433F90D4A8137002ACA73 /* prefs.h in Headers */,
+                               157433FA0D4A8137002ACA73 /* net.h in Headers */,
+                               157433FB0D4A8137002ACA73 /* net_interface.h in Headers */,
                                157433FC0D4A8137002ACA73 /* net_protocol.h in Headers */,
                                157433FD0D4A8137002ACA73 /* net_service.h in Headers */,
                                157433FE0D4A8137002ACA73 /* net_set.h in Headers */,
                                157433FC0D4A8137002ACA73 /* net_protocol.h in Headers */,
                                157433FD0D4A8137002ACA73 /* net_service.h in Headers */,
                                157433FE0D4A8137002ACA73 /* net_set.h in Headers */,
                                157A84DA0D56C63900B6F1A0 /* dnsinfo.h in Headers */,
                                D661C2F21368BB720030B977 /* network_information.h in Headers */,
                                157A84DB0D56C63900B6F1A0 /* dnsinfo_private.h in Headers */,
                                157A84DA0D56C63900B6F1A0 /* dnsinfo.h in Headers */,
                                D661C2F21368BB720030B977 /* network_information.h in Headers */,
                                157A84DB0D56C63900B6F1A0 /* dnsinfo_private.h in Headers */,
+                               153338C014BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E4F211D4137B0ABD00BBB915 /* network_information_priv.h in Headers */,
                                1575FD2812CD15C60003D86E /* proxy-configuration.h in Headers */,
                                157A84F70D56C7E800B6F1A0 /* set-hostname.h in Headers */,
                                E4F211D4137B0ABD00BBB915 /* network_information_priv.h in Headers */,
                                1575FD2812CD15C60003D86E /* proxy-configuration.h in Headers */,
                                157A84F70D56C7E800B6F1A0 /* set-hostname.h in Headers */,
+                               153ACCAC14E322D5005029A5 /* network_information_server.h in Headers */,
+                               1596A7B514EDB73D00798C39 /* libSystemConfiguration_server.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EA05108395BB00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA06108395BB00A3BC0C /* dnsinfo.h in Headers */,
-                               151E0CA31378EE1000C5DA2A /* network_information.h in Headers */,
-                               1583EA07108395BB00A3BC0C /* dnsinfo_private.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EA1A108395BB00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA1B108395BB00A3BC0C /* SCSchemaDefinitions.h in Headers */,
-                               1583EA1C108395BB00A3BC0C /* SystemConfiguration.h in Headers */,
-                               1583EA1D108395BB00A3BC0C /* SCPrivate.h in Headers */,
-                               1583EA1E108395BB00A3BC0C /* SCDPlugin.h in Headers */,
-                               1583EA1F108395BB00A3BC0C /* SCDynamicStoreInternal.h in Headers */,
-                               1583EA20108395BB00A3BC0C /* SCDynamicStore.h in Headers */,
-                               1583EA21108395BB00A3BC0C /* SCDynamicStorePrivate.h in Headers */,
-                               1583EA22108395BB00A3BC0C /* SCDynamicStoreKey.h in Headers */,
-                               1583EA23108395BB00A3BC0C /* SCDynamicStoreCopySpecific.h in Headers */,
-                               1583EA24108395BB00A3BC0C /* SCDynamicStoreCopySpecificPrivate.h in Headers */,
-                               1583EA25108395BB00A3BC0C /* SCDynamicStoreSetSpecificPrivate.h in Headers */,
-                               1583EA26108395BB00A3BC0C /* SCPreferencesInternal.h in Headers */,
-                               1583EA27108395BB00A3BC0C /* SCPreferences.h in Headers */,
-                               1583EA28108395BB00A3BC0C /* SCPreferencesPrivate.h in Headers */,
-                               1583EA29108395BB00A3BC0C /* SCPreferencesPath.h in Headers */,
-                               1583EA2A108395BB00A3BC0C /* SCPreferencesSetSpecific.h in Headers */,
-                               1583EA2B108395BB00A3BC0C /* SCNetworkConfiguration.h in Headers */,
-                               1583EA2C108395BB00A3BC0C /* SCNetworkConfigurationInternal.h in Headers */,
-                               1583EA2D108395BB00A3BC0C /* SCNetwork.h in Headers */,
-                               1583EA2E108395BB00A3BC0C /* SCNetworkConnection.h in Headers */,
-                               1583EA2F108395BB00A3BC0C /* SCNetworkReachability.h in Headers */,
-                               1583EA30108395BB00A3BC0C /* SCValidation.h in Headers */,
-                               1583EA31108395BB00A3BC0C /* DHCPClientPreferences.h in Headers */,
-                               1583EA32108395BB00A3BC0C /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
-                               1583EA33108395BB00A3BC0C /* moh_msg.h in Headers */,
-                               1583EA34108395BB00A3BC0C /* moh.h in Headers */,
-                               1583EA35108395BB00A3BC0C /* DeviceOnHold.h in Headers */,
-                               1583EA36108395BB00A3BC0C /* dy_framework.h in Headers */,
-                               1583EA37108395BB00A3BC0C /* SCPreferencesPathKey.h in Headers */,
-                               1583EA38108395BB00A3BC0C /* pppcontroller_types.h in Headers */,
-                               1583EA39108395BB00A3BC0C /* pppcontroller.h in Headers */,
-                               1583EA3A108395BB00A3BC0C /* SCPreferencesSetSpecificPrivate.h in Headers */,
-                               1583EA3B108395BB00A3BC0C /* SCPreferencesGetSpecificPrivate.h in Headers */,
-                               1583EA3C108395BB00A3BC0C /* SCNetworkConfigurationPrivate.h in Headers */,
-                               1583EA3E108395BB00A3BC0C /* SCHelper_client.h in Headers */,
-                               1583EA3F108395BB00A3BC0C /* SCNetworkConnectionPrivate.h in Headers */,
-                               1583EA40108395BB00A3BC0C /* SCPreferencesKeychainPrivate.h in Headers */,
-                               1583EA41108395BB00A3BC0C /* SCSchemaDefinitionsPrivate.h in Headers */,
-                               1583EA42108395BB00A3BC0C /* SCNetworkSignature.h in Headers */,
-                               1583EA43108395BB00A3BC0C /* SCNetworkSignaturePrivate.h in Headers */,
-                               1583EA44108395BB00A3BC0C /* CaptiveNetwork.h in Headers */,
-                               15C330C7134B92780028E36B /* rb.h in Headers */,
-                               15C330D4134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
-                               15D8B22D1450D8450090CECF /* SCD.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EA9C108395BB00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA9E108395BB00A3BC0C /* SCHelper_client.h in Headers */,
-                               152E0E8B10FE824000E402F2 /* helper_types.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EACB108395BB00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EACC108395BB00A3BC0C /* dns-configuration.h in Headers */,
-                               1583EACE108395BB00A3BC0C /* dnsinfo_create.h in Headers */,
-                               E4F211D6137B0ADB00BBB915 /* network_information_priv.h in Headers */,
-                               1575FD2C12CD15C60003D86E /* proxy-configuration.h in Headers */,
-                               1583EACD108395BB00A3BC0C /* set-hostname.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EAE1108395BB00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EAF0108395BC00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAF1108395BC00A3BC0C /* cache.h in Headers */,
-                               1583EAF2108395BC00A3BC0C /* ev_dlil.h in Headers */,
-                               1583EAF3108395BC00A3BC0C /* ev_ipv4.h in Headers */,
-                               1583EAF4108395BC00A3BC0C /* ev_ipv6.h in Headers */,
-                               1583EAF5108395BC00A3BC0C /* eventmon.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB08108395BC00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB33108395BD00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB4C108395BD00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB4D108395BD00A3BC0C /* configd.h in Headers */,
-                               1583EB4E108395BD00A3BC0C /* _SCD.h in Headers */,
-                               1583EB4F108395BD00A3BC0C /* configd_server.h in Headers */,
-                               1583EB50108395BD00A3BC0C /* notify_server.h in Headers */,
-                               1583EB51108395BD00A3BC0C /* plugin_support.h in Headers */,
-                               1583EB52108395BD00A3BC0C /* session.h in Headers */,
-                               1583EB53108395BD00A3BC0C /* pattern.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB87108395BE00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB93108395BE00A3BC0C /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB94108395BE00A3BC0C /* scutil.h in Headers */,
-                               1583EB95108395BE00A3BC0C /* commands.h in Headers */,
-                               1583EB96108395BE00A3BC0C /* dictionary.h in Headers */,
-                               1583EB97108395BE00A3BC0C /* session.h in Headers */,
-                               1583EB98108395BE00A3BC0C /* cache.h in Headers */,
-                               1583EB99108395BE00A3BC0C /* notifications.h in Headers */,
-                               1583EB9A108395BE00A3BC0C /* tests.h in Headers */,
-                               1583EB9B108395BE00A3BC0C /* prefs.h in Headers */,
-                               1583EB9C108395BE00A3BC0C /* net.h in Headers */,
-                               1583EB9D108395BE00A3BC0C /* net_interface.h in Headers */,
-                               1583EB9E108395BE00A3BC0C /* net_protocol.h in Headers */,
-                               1583EB9F108395BE00A3BC0C /* net_service.h in Headers */,
-                               1583EBA0108395BE00A3BC0C /* net_set.h in Headers */,
-                               15B274A6114467D8003414AD /* nc.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                159D53D007528BDA004F8947 /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                159D53D007528BDA004F8947 /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                                1575FD2A12CD15C60003D86E /* proxy-configuration.h in Headers */,
                                155D223C0AF13A7300D52ED0 /* set-hostname.h in Headers */,
                                155D223D0AF13A7300D52ED0 /* smb-configuration.h in Headers */,
                                1575FD2A12CD15C60003D86E /* proxy-configuration.h in Headers */,
                                155D223C0AF13A7300D52ED0 /* set-hostname.h in Headers */,
                                155D223D0AF13A7300D52ED0 /* smb-configuration.h in Headers */,
+                               153ACCAB14E322D5005029A5 /* network_information_server.h in Headers */,
+                               1596A7B414EDB73D00798C39 /* libSystemConfiguration_server.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                15A5A1FB0D5B94190087BDA0 /* SCNetworkReachability.h in Headers */,
                                15A5A1FC0D5B94190087BDA0 /* SCValidation.h in Headers */,
                                15A5A1FD0D5B94190087BDA0 /* DHCPClientPreferences.h in Headers */,
                                15A5A1FB0D5B94190087BDA0 /* SCNetworkReachability.h in Headers */,
                                15A5A1FC0D5B94190087BDA0 /* SCValidation.h in Headers */,
                                15A5A1FD0D5B94190087BDA0 /* DHCPClientPreferences.h in Headers */,
+                               D61AAEB71522C9EF0066B003 /* scprefs_observer.h in Headers */,
                                15A5A1FE0D5B94190087BDA0 /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
                                15A5A1FF0D5B94190087BDA0 /* moh_msg.h in Headers */,
                                15A5A2000D5B94190087BDA0 /* moh.h in Headers */,
                                15A5A1FE0D5B94190087BDA0 /* SCDynamicStoreCopyDHCPInfo.h in Headers */,
                                15A5A1FF0D5B94190087BDA0 /* moh_msg.h in Headers */,
                                15A5A2000D5B94190087BDA0 /* moh.h in Headers */,
                                15A5A2060D5B94190087BDA0 /* dnsinfo.h in Headers */,
                                15A5A2070D5B94190087BDA0 /* dnsinfo_private.h in Headers */,
                                15A5A2080D5B94190087BDA0 /* pppcontroller_types.h in Headers */,
                                15A5A2060D5B94190087BDA0 /* dnsinfo.h in Headers */,
                                15A5A2070D5B94190087BDA0 /* dnsinfo_private.h in Headers */,
                                15A5A2080D5B94190087BDA0 /* pppcontroller_types.h in Headers */,
-                               15A5A2090D5B94190087BDA0 /* pppcontroller.h in Headers */,
+                               1572C57F171CCFE200870549 /* pppcontroller_mach_defines.h in Headers */,
                                15A5A20C0D5B94190087BDA0 /* SCPreferencesSetSpecificPrivate.h in Headers */,
                                15A5A20D0D5B94190087BDA0 /* SCPreferencesGetSpecificPrivate.h in Headers */,
                                15A5A20E0D5B94190087BDA0 /* SCNetworkConfigurationPrivate.h in Headers */,
                                15A5A20C0D5B94190087BDA0 /* SCPreferencesSetSpecificPrivate.h in Headers */,
                                15A5A20D0D5B94190087BDA0 /* SCPreferencesGetSpecificPrivate.h in Headers */,
                                15A5A20E0D5B94190087BDA0 /* SCNetworkConfigurationPrivate.h in Headers */,
                                15A1FF3410597F17004C9CC9 /* CaptiveNetwork.h in Headers */,
                                159A7528107FEAA400A57EAB /* VPNPrivate.h in Headers */,
                                159A752A107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
                                15A1FF3410597F17004C9CC9 /* CaptiveNetwork.h in Headers */,
                                159A7528107FEAA400A57EAB /* VPNPrivate.h in Headers */,
                                159A752A107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
-                               15C330C6134B92780028E36B /* rb.h in Headers */,
                                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
                                15D8B22C1450D8450090CECF /* SCD.h in Headers */,
                                15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
                                15D8B22C1450D8450090CECF /* SCD.h in Headers */,
+                               15A5A2090D5B94190087BDA0 /* pppcontroller.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15AB751316EBFF3400FAA8CE /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15D3081016F3E4DA00014F82 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15C8C6C0170AAB4E005375CE /* cache.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                15DAD5E1075913CE0084A6ED /* dnsinfo.h in Headers */,
                                D661C2EF1368BB280030B977 /* network_information.h in Headers */,
                                15DAD5E2075913CE0084A6ED /* dnsinfo_private.h in Headers */,
                                15DAD5E1075913CE0084A6ED /* dnsinfo.h in Headers */,
                                D661C2EF1368BB280030B977 /* network_information.h in Headers */,
                                15DAD5E2075913CE0084A6ED /* dnsinfo_private.h in Headers */,
+                               153338BF14BE7978004FCE22 /* libSystemConfiguration_client.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                15DAD65007591A1A0084A6ED /* SCPreferencesPath.h in Headers */,
                                15DAD65107591A1A0084A6ED /* SCPreferencesSetSpecific.h in Headers */,
                                15DAD65207591A1A0084A6ED /* SCNetworkConfiguration.h in Headers */,
                                15DAD65007591A1A0084A6ED /* SCPreferencesPath.h in Headers */,
                                15DAD65107591A1A0084A6ED /* SCPreferencesSetSpecific.h in Headers */,
                                15DAD65207591A1A0084A6ED /* SCNetworkConfiguration.h in Headers */,
+                               D61AAEB51522C9D00066B003 /* scprefs_observer.h in Headers */,
                                15DAD65307591A1A0084A6ED /* SCNetworkConfigurationInternal.h in Headers */,
                                15DAD65407591A1A0084A6ED /* SCNetwork.h in Headers */,
                                15DAD65507591A1A0084A6ED /* SCNetworkConnection.h in Headers */,
                                15DAD65307591A1A0084A6ED /* SCNetworkConfigurationInternal.h in Headers */,
                                15DAD65407591A1A0084A6ED /* SCNetwork.h in Headers */,
                                15DAD65507591A1A0084A6ED /* SCNetworkConnection.h in Headers */,
                                15DAD65A07591A1A0084A6ED /* moh_msg.h in Headers */,
                                15DAD65B07591A1A0084A6ED /* moh.h in Headers */,
                                15DAD65C07591A1A0084A6ED /* DeviceOnHold.h in Headers */,
                                15DAD65A07591A1A0084A6ED /* moh_msg.h in Headers */,
                                15DAD65B07591A1A0084A6ED /* moh.h in Headers */,
                                15DAD65C07591A1A0084A6ED /* DeviceOnHold.h in Headers */,
-                               15DAD65D07591A1A0084A6ED /* LinkConfiguration.h in Headers */,
+                               C4CDB8181631938400819B44 /* VPNFlowPrivate.h in Headers */,
                                15DAD65E07591A1A0084A6ED /* dy_framework.h in Headers */,
                                15DAD66107591A1A0084A6ED /* SCPreferencesPathKey.h in Headers */,
                                15DAD66407591A1A0084A6ED /* pppcontroller_types.h in Headers */,
                                15DAD65E07591A1A0084A6ED /* dy_framework.h in Headers */,
                                15DAD66107591A1A0084A6ED /* SCPreferencesPathKey.h in Headers */,
                                15DAD66407591A1A0084A6ED /* pppcontroller_types.h in Headers */,
-                               15DAD66507591A1A0084A6ED /* pppcontroller.h in Headers */,
+                               1572C580171CCFF000870549 /* pppcontroller_mach_defines.h in Headers */,
+                               B0A88CA716397A1200A60B3A /* VPNAppLayerPrivate.h in Headers */,
                                156BD6BC07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h in Headers */,
                                154CF3F407E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h in Headers */,
                                156BD6BC07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h in Headers */,
                                154CF3F407E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h in Headers */,
+                               C4CDB8171631938000819B44 /* VPNFlow.h in Headers */,
                                155A1E6C081079CC00F70D98 /* SCNetworkConfigurationPrivate.h in Headers */,
                                155B7BF80847776D00F0E262 /* SCHelper_client.h in Headers */,
                                15D8B22A1450D8450090CECF /* SCD.h in Headers */,
                                15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */,
                                152E68C10A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h in Headers */,
                                155A1E6C081079CC00F70D98 /* SCNetworkConfigurationPrivate.h in Headers */,
                                155B7BF80847776D00F0E262 /* SCHelper_client.h in Headers */,
                                15D8B22A1450D8450090CECF /* SCD.h in Headers */,
                                15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */,
                                152E68C10A2C89C70011FDA8 /* SCPreferencesKeychainPrivate.h in Headers */,
+                               B0C967F817441F0E00889853 /* SNHelperPrivate.h in Headers */,
                                157A88890A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h in Headers */,
                                F95B8A460B03E09300993BA3 /* SCNetworkSignature.h in Headers */,
                                F95B8A470B03E09300993BA3 /* SCNetworkSignaturePrivate.h in Headers */,
                                157A88890A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h in Headers */,
                                F95B8A460B03E09300993BA3 /* SCNetworkSignature.h in Headers */,
                                F95B8A470B03E09300993BA3 /* SCNetworkSignaturePrivate.h in Headers */,
                                159A7523107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
                                15AAA7F8108E310700C2A607 /* VPNTunnel.h in Headers */,
                                15AAA7F7108E310700C2A607 /* VPNTunnelPrivate.h in Headers */,
                                159A7523107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
                                15AAA7F8108E310700C2A607 /* VPNTunnel.h in Headers */,
                                15AAA7F7108E310700C2A607 /* VPNTunnelPrivate.h in Headers */,
-                               15C330C4134B92780028E36B /* rb.h in Headers */,
                                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
                                15C330D1134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
+                               B084710F16385121006C92A3 /* SCNetworkConnectionInternal.h in Headers */,
+                               15DAD66507591A1A0084A6ED /* pppcontroller.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15E1B04216EBAE3C00E5F06F /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15E1B04316EBAE3C00E5F06F /* dns-configuration.h in Headers */,
+                               15E1B04416EBAE3C00E5F06F /* dnsinfo_create.h in Headers */,
+                               15E1B04516EBAE3C00E5F06F /* network_information_priv.h in Headers */,
+                               15E1B04616EBAE3C00E5F06F /* proxy-configuration.h in Headers */,
+                               15E1B04816EBAE3C00E5F06F /* network_information_server.h in Headers */,
+                               15E1B04916EBAE3C00E5F06F /* libSystemConfiguration_server.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        productReference = 1528BFFE13573FF500691881 /* SCNetworkReachability.bundle */;
                        productType = "com.apple.product-type.bundle";
                };
                        productReference = 1528BFFE13573FF500691881 /* SCNetworkReachability.bundle */;
                        productType = "com.apple.product-type.bundle";
                };
-               1528BFFF1357401900691881 /* SCNetworkReachability-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1528C0031357401900691881 /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedOther" */;
-                       buildPhases = (
-                               1528C0001357401900691881 /* Headers */,
-                               1528C0011357401900691881 /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "SCNetworkReachability-EmbeddedOther";
-                       productName = PreferencesMonitor;
-                       productReference = 1528C0061357401900691881 /* libSCNetworkReachability.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               1528C0071357401D00691881 /* SCNetworkReachability.bundle-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1528C00A1357401D00691881 /* Build configuration list for PBXNativeTarget "SCNetworkReachability.bundle-EmbeddedOther" */;
-                       buildPhases = (
-                               1528C0081357401D00691881 /* Resources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "SCNetworkReachability.bundle-EmbeddedOther";
-                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
-                       productName = PreferencesMonitor.bundle;
-                       productReference = 1528C00D1357401D00691881 /* SCNetworkReachability.bundle */;
-                       productType = "com.apple.product-type.bundle";
-               };
                1547001808455B98006787CE /* SCHelper */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 156EB5E20905594A00EEF749 /* Build configuration list for PBXNativeTarget "SCHelper" */;
                1547001808455B98006787CE /* SCHelper */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 156EB5E20905594A00EEF749 /* Build configuration list for PBXNativeTarget "SCHelper" */;
                        productReference = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */;
                        productType = "com.apple.product-type.framework";
                };
                        productReference = 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */;
                        productType = "com.apple.product-type.framework";
                };
+               15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 15732AA916EA503200F3AC4C /* Build configuration list for PBXNativeTarget "configd-EmbeddedSimulator" */;
+                       buildPhases = (
+                               15732A7716EA503200F3AC4C /* Headers */,
+                               15732A7F16EA503200F3AC4C /* Sources */,
+                               15732A9B16EA503200F3AC4C /* Frameworks */,
+                               15732AA716EA503200F3AC4C /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               15AB752A16EC254D00FAA8CE /* PBXTargetDependency */,
+                               15AB752C16EC254D00FAA8CE /* PBXTargetDependency */,
+                               15D3083516F3EB2500014F82 /* PBXTargetDependency */,
+                       );
+                       name = "configd-EmbeddedSimulator";
+                       productInstallPath = /usr/sbin;
+                       productName = "configd (Tool)";
+                       productReference = 15732AAC16EA503300F3AC4C /* configd_sim */;
+                       productType = "com.apple.product-type.tool";
+               };
+               15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 15732AD216EA511900F3AC4C /* Build configuration list for PBXNativeTarget "scutil-EmbeddedSimulator" */;
+                       buildPhases = (
+                               15732AAE16EA511900F3AC4C /* Headers */,
+                               15732ABD16EA511900F3AC4C /* Sources */,
+                               15732ACD16EA511900F3AC4C /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "scutil-EmbeddedSimulator";
+                       productInstallPath = /usr/sbin;
+                       productName = "scutil (Tool)";
+                       productReference = 15732AD516EA511900F3AC4C /* scutil_sim */;
+                       productType = "com.apple.product-type.tool";
+               };
+               15732AD616EA6B6700F3AC4C /* libsystem_configuration-EmbeddedSimulator */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 15732AE116EA6B6700F3AC4C /* Build configuration list for PBXNativeTarget "libsystem_configuration-EmbeddedSimulator" */;
+                       buildPhases = (
+                               15732AD716EA6B6700F3AC4C /* Headers */,
+                               15732ADC16EA6B6700F3AC4C /* Sources */,
+                               15732AE016EA6B6700F3AC4C /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "libsystem_configuration-EmbeddedSimulator";
+                       productInstallPath = /usr/local/lib/system;
+                       productName = DNSConfiguration;
+                       productReference = 15732AE416EA6B6700F3AC4C /* libsystem_sim_configuration.dylib */;
+                       productType = "com.apple.product-type.library.dynamic";
+               };
                157433DD0D4A8122002ACA73 /* scselect-Embedded */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 157433E80D4A8122002ACA73 /* Build configuration list for PBXNativeTarget "scselect-Embedded" */;
                157433DD0D4A8122002ACA73 /* scselect-Embedded */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 157433E80D4A8122002ACA73 /* Build configuration list for PBXNativeTarget "scselect-Embedded" */;
                        productReference = 1574341A0D4A8137002ACA73 /* scutil */;
                        productType = "com.apple.product-type.tool";
                };
                        productReference = 1574341A0D4A8137002ACA73 /* scutil */;
                        productType = "com.apple.product-type.tool";
                };
-               157A84D80D56C63900B6F1A0 /* DNSConfiguration-Embedded */ = {
+               157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 157A84E40D56C63900B6F1A0 /* Build configuration list for PBXNativeTarget "DNSConfiguration-Embedded" */;
+                       buildConfigurationList = 157A84E40D56C63900B6F1A0 /* Build configuration list for PBXNativeTarget "libsystem_configuration-Embedded" */;
                        buildPhases = (
                                157A84D90D56C63900B6F1A0 /* Headers */,
                                157A84DD0D56C63900B6F1A0 /* Sources */,
                        buildPhases = (
                                157A84D90D56C63900B6F1A0 /* Headers */,
                                157A84DD0D56C63900B6F1A0 /* Sources */,
                        );
                        dependencies = (
                        );
                        );
                        dependencies = (
                        );
-                       name = "DNSConfiguration-Embedded";
+                       name = "libsystem_configuration-Embedded";
                        productInstallPath = /usr/local/lib/system;
                        productName = DNSConfiguration;
                        productInstallPath = /usr/local/lib/system;
                        productName = DNSConfiguration;
-                       productReference = 157A84E80D56C63900B6F1A0 /* libdnsinfo.dylib */;
+                       productReference = 157A84E80D56C63900B6F1A0 /* libsystem_configuration.dylib */;
                        productType = "com.apple.product-type.library.dynamic";
                };
                157A84F40D56C7E800B6F1A0 /* IPMonitor-Embedded */ = {
                        productType = "com.apple.product-type.library.dynamic";
                };
                157A84F40D56C7E800B6F1A0 /* IPMonitor-Embedded */ = {
                        buildConfigurationList = 158317800CFB85C8006F62B9 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-Embedded" */;
                        buildPhases = (
                                1583177E0CFB85C8006F62B9 /* Resources */,
                        buildConfigurationList = 158317800CFB85C8006F62B9 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-Embedded" */;
                        buildPhases = (
                                1583177E0CFB85C8006F62B9 /* Resources */,
+                               15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                        productReference = 1559C4470D349A4E0098FD59 /* SCHelper */;
                        productType = "com.apple.product-type.tool";
                };
                        productReference = 1559C4470D349A4E0098FD59 /* SCHelper */;
                        productType = "com.apple.product-type.tool";
                };
-               1583EA04108395BB00A3BC0C /* DNSConfiguration-EmbeddedOther */ = {
+               159D53D307528BDA004F8947 /* KernelEventMonitor */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EA0D108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "DNSConfiguration-EmbeddedOther" */;
+                       buildConfigurationList = 156EB6020905594A00EEF749 /* Build configuration list for PBXNativeTarget "KernelEventMonitor" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EA05108395BB00A3BC0C /* Headers */,
-                               1583EA08108395BB00A3BC0C /* Sources */,
-                               1583EA0C108395BB00A3BC0C /* Frameworks */,
+                               159D53D007528BDA004F8947 /* Headers */,
+                               159D53D107528BDA004F8947 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "DNSConfiguration-EmbeddedOther";
-                       productInstallPath = /usr/local/lib/system;
-                       productName = DNSConfiguration;
-                       productReference = 1583EA10108395BB00A3BC0C /* libdnsinfo.dylib */;
-                       productType = "com.apple.product-type.library.dynamic";
+                       name = KernelEventMonitor;
+                       productName = KernelEventMonitor;
+                       productReference = 159D53D407528BDA004F8947 /* libKernelEventMonitor.a */;
+                       productType = "com.apple.product-type.library.static";
                };
                };
-               1583EA19108395BB00A3BC0C /* SystemConfiguration.framework-EmbeddedOther */ = {
+               159D53E407528C4A004F8947 /* InterfaceNamer */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EA96108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedOther" */;
+                       buildConfigurationList = 156EB5F60905594A00EEF749 /* Build configuration list for PBXNativeTarget "InterfaceNamer" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EA1A108395BB00A3BC0C /* Headers */,
-                               1583EA49108395BB00A3BC0C /* Update Headers */,
-                               1583EA4A108395BB00A3BC0C /* Resources */,
-                               1583EA4F108395BB00A3BC0C /* Sources */,
-                               1583EA93108395BB00A3BC0C /* Frameworks */,
-                               1583EA95108395BB00A3BC0C /* get-mobility-info */,
+                               159D53E107528C4A004F8947 /* Headers */,
+                               159D53E207528C4A004F8947 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "SystemConfiguration.framework-EmbeddedOther";
-                       productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                       productName = "SystemConfiguration (Framework)";
-                       productReference = 1583EA99108395BB00A3BC0C /* SystemConfiguration.framework */;
-                       productType = "com.apple.product-type.framework";
+                       name = InterfaceNamer;
+                       productName = InterfaceNamer;
+                       productReference = 159D53E507528C4A004F8947 /* libInterfaceNamer.a */;
+                       productType = "com.apple.product-type.library.static";
                };
                };
-               1583EA9B108395BB00A3BC0C /* SCHelper-EmbeddedOther */ = {
+               159D53EB07528C61004F8947 /* IPMonitor */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EAA7108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SCHelper-EmbeddedOther" */;
+                       buildConfigurationList = 156EB5EE0905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EA9C108395BB00A3BC0C /* Headers */,
-                               1583EA9F108395BB00A3BC0C /* Sources */,
-                               1583EAA1108395BB00A3BC0C /* Frameworks */,
-                               1583EAA5108395BB00A3BC0C /* CopyFiles */,
+                               159D53E807528C61004F8947 /* Headers */,
+                               159D53E907528C61004F8947 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "SCHelper-EmbeddedOther";
-                       productInstallPath = /usr/local/bin;
-                       productName = SCPreferencesHelper;
-                       productReference = 1583EAAA108395BB00A3BC0C /* SCHelper */;
-                       productType = "com.apple.product-type.tool";
+                       name = IPMonitor;
+                       productName = IPMonitor;
+                       productReference = 159D53EC07528C61004F8947 /* libIPMonitor.a */;
+                       productType = "com.apple.product-type.library.static";
                };
                };
-               1583EACA108395BB00A3BC0C /* IPMonitor-EmbeddedOther */ = {
+               159D53F207528C79004F8947 /* LinkConfiguration */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EAD5108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor-EmbeddedOther" */;
+                       buildConfigurationList = 156EB60E0905594A00EEF749 /* Build configuration list for PBXNativeTarget "LinkConfiguration" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EACB108395BB00A3BC0C /* Headers */,
-                               1583EACF108395BB00A3BC0C /* Sources */,
+                               159D53EF07528C79004F8947 /* Headers */,
+                               159D53F007528C79004F8947 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "IPMonitor-EmbeddedOther";
-                       productName = IPMonitor;
-                       productReference = 1583EAD8108395BB00A3BC0C /* libIPMonitor.a */;
+                       name = LinkConfiguration;
+                       productName = LinkConfiguration;
+                       productReference = 159D53F307528C79004F8947 /* libLinkConfiguration.a */;
                        productType = "com.apple.product-type.library.static";
                };
                        productType = "com.apple.product-type.library.static";
                };
-               1583EAD9108395BB00A3BC0C /* IPMonitor.bundle-EmbeddedOther */ = {
+               159D53F907528C95004F8947 /* PreferencesMonitor */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EADB108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedOther" */;
+                       buildConfigurationList = 156EB6160905594A00EEF749 /* Build configuration list for PBXNativeTarget "PreferencesMonitor" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EADA108395BB00A3BC0C /* Resources */,
+                               159D53F607528C95004F8947 /* Headers */,
+                               159D53F707528C95004F8947 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "IPMonitor.bundle-EmbeddedOther";
-                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
-                       productName = IPMonitor.bundle;
-                       productReference = 1583EADE108395BB00A3BC0C /* IPMonitor.bundle */;
-                       productType = "com.apple.product-type.bundle";
+                       name = PreferencesMonitor;
+                       productName = PreferencesMonitor;
+                       productReference = 159D53FA07528C95004F8947 /* libPreferencesMonitor.a */;
+                       productType = "com.apple.product-type.library.static";
                };
                };
-               1583EAE0108395BB00A3BC0C /* InterfaceNamer-EmbeddedOther */ = {
+               159D549F07529FFF004F8947 /* configd */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EAE4108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer-EmbeddedOther" */;
+                       buildConfigurationList = 156EB6220905594A00EEF749 /* Build configuration list for PBXNativeTarget "configd" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EAE1108395BB00A3BC0C /* Headers */,
-                               1583EAE2108395BB00A3BC0C /* Sources */,
+                               159D54A307529FFF004F8947 /* Headers */,
+                               159D54AB07529FFF004F8947 /* Sources */,
+                               159D54CA07529FFF004F8947 /* Frameworks */,
+                               159D54D507529FFF004F8947 /* CopyFiles */,
+                               159D54D707529FFF004F8947 /* CopyFiles */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "InterfaceNamer-EmbeddedOther";
-                       productName = InterfaceNamer;
-                       productReference = 1583EAE7108395BB00A3BC0C /* libInterfaceNamer.a */;
-                       productType = "com.apple.product-type.library.static";
+                       name = configd;
+                       productInstallPath = /usr/sbin;
+                       productName = "configd (Tool)";
+                       productReference = 159D54D907529FFF004F8947 /* configd */;
+                       productType = "com.apple.product-type.tool";
                };
                };
-               1583EAE8108395BC00A3BC0C /* InterfaceNamer.bundle-EmbeddedOther */ = {
+               15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EAEA108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer.bundle-EmbeddedOther" */;
+                       buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EAE9108395BC00A3BC0C /* Resources */,
+                               15A5A1E60D5B94190087BDA0 /* Headers */,
+                               15A5A2170D5B94190087BDA0 /* Update Headers */,
+                               15A5A2180D5B94190087BDA0 /* Resources */,
+                               15A5A21D0D5B94190087BDA0 /* Sources */,
+                               15A5A2620D5B94190087BDA0 /* Frameworks */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "InterfaceNamer.bundle-EmbeddedOther";
-                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
-                       productName = InterfaceNamer.bundle;
-                       productReference = 1583EAED108395BC00A3BC0C /* InterfaceNamer.bundle */;
-                       productType = "com.apple.product-type.bundle";
+                       name = "SystemConfiguration.framework-EmbeddedSimulator";
+                       productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                       productName = "SystemConfiguration (Framework)";
+                       productReference = 15A5A26A0D5B94190087BDA0 /* SystemConfiguration.framework */;
+                       productType = "com.apple.product-type.framework";
                };
                };
-               1583EAEF108395BC00A3BC0C /* KernelEventMonitor-EmbeddedOther */ = {
+               15AB751216EBFF3400FAA8CE /* SCNetworkReachability-EmbeddedSimulator */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EAFC108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor-EmbeddedOther" */;
+                       buildConfigurationList = 15AB751616EBFF3400FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedSimulator" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EAF0108395BC00A3BC0C /* Headers */,
-                               1583EAF6108395BC00A3BC0C /* Sources */,
+                               15AB751316EBFF3400FAA8CE /* Headers */,
+                               15AB751416EBFF3400FAA8CE /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "KernelEventMonitor-EmbeddedOther";
-                       productName = KernelEventMonitor;
-                       productReference = 1583EAFF108395BC00A3BC0C /* libKernelEventMonitor.a */;
+                       name = "SCNetworkReachability-EmbeddedSimulator";
+                       productName = PreferencesMonitor;
+                       productReference = 15AB751916EBFF3400FAA8CE /* libSCNetworkReachability_sim.a */;
                        productType = "com.apple.product-type.library.static";
                };
                        productType = "com.apple.product-type.library.static";
                };
-               1583EB00108395BC00A3BC0C /* KernelEventMonitor.bundle-EmbeddedOther */ = {
+               15AB751A16EBFF8A00FAA8CE /* SCNetworkReachability.bundle-EmbeddedSimulator */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB02108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor.bundle-EmbeddedOther" */;
+                       buildConfigurationList = 15AB751C16EBFF8A00FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability.bundle-EmbeddedSimulator" */;
                        buildPhases = (
                        buildPhases = (
-                               1583EB01108395BC00A3BC0C /* Resources */,
+                               15AB751B16EBFF8A00FAA8CE /* Resources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "KernelEventMonitor.bundle-EmbeddedOther";
-                       productName = KernelEventMonitor.bundle;
-                       productReference = 1583EB05108395BC00A3BC0C /* KernelEventMonitor.bundle */;
-                       productType = "com.apple.product-type.bundle";
-               };
-               1583EB07108395BC00A3BC0C /* LinkConfiguration-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB0B108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "LinkConfiguration-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB08108395BC00A3BC0C /* Headers */,
-                               1583EB09108395BC00A3BC0C /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "LinkConfiguration-EmbeddedOther";
-                       productName = LinkConfiguration;
-                       productReference = 1583EB0E108395BC00A3BC0C /* libLinkConfiguration.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               1583EB0F108395BC00A3BC0C /* LinkConfiguration.bundle-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB11108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "LinkConfiguration.bundle-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB10108395BC00A3BC0C /* Resources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "LinkConfiguration.bundle-EmbeddedOther";
-                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
-                       productName = LinkConfiguration.bundle;
-                       productReference = 1583EB14108395BC00A3BC0C /* LinkConfiguration.bundle */;
-                       productType = "com.apple.product-type.bundle";
-               };
-               1583EB16108395BC00A3BC0C /* Logger.bundle-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB1E108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "Logger.bundle-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB17108395BC00A3BC0C /* Sources */,
-                               1583EB19108395BC00A3BC0C /* Frameworks */,
-                               1583EB1D108395BC00A3BC0C /* Resources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "Logger.bundle-EmbeddedOther";
-                       productName = Logger.bundle;
-                       productReference = 1583EB21108395BC00A3BC0C /* Logger.bundle */;
-                       productType = "com.apple.product-type.bundle";
-               };
-               1583EB32108395BD00A3BC0C /* PreferencesMonitor-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB36108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "PreferencesMonitor-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB33108395BD00A3BC0C /* Headers */,
-                               1583EB34108395BD00A3BC0C /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "PreferencesMonitor-EmbeddedOther";
-                       productName = PreferencesMonitor;
-                       productReference = 1583EB39108395BD00A3BC0C /* libPreferencesMonitor.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               1583EB3A108395BD00A3BC0C /* PreferencesMonitor.bundle-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB3C108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "PreferencesMonitor.bundle-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB3B108395BD00A3BC0C /* Resources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "PreferencesMonitor.bundle-EmbeddedOther";
+                       name = "SCNetworkReachability.bundle-EmbeddedSimulator";
                        productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
                        productName = PreferencesMonitor.bundle;
                        productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
                        productName = PreferencesMonitor.bundle;
-                       productReference = 1583EB3F108395BD00A3BC0C /* PreferencesMonitor.bundle */;
+                       productReference = 15AB751F16EBFF8A00FAA8CE /* SCNetworkReachability.bundle */;
                        productType = "com.apple.product-type.bundle";
                };
                        productType = "com.apple.product-type.bundle";
                };
-               1583EB4B108395BD00A3BC0C /* configd-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB81108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "configd-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB4C108395BD00A3BC0C /* Headers */,
-                               1583EB54108395BD00A3BC0C /* Sources */,
-                               1583EB73108395BD00A3BC0C /* Frameworks */,
-                               1583EB7F108395BD00A3BC0C /* CopyFiles */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "configd-EmbeddedOther";
-                       productInstallPath = /usr/sbin;
-                       productName = "configd (Tool)";
-                       productReference = 1583EB84108395BD00A3BC0C /* configd */;
-                       productType = "com.apple.product-type.tool";
-               };
-               1583EB86108395BE00A3BC0C /* scselect-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EB8D108395BE00A3BC0C /* Build configuration list for PBXNativeTarget "scselect-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB87108395BE00A3BC0C /* Headers */,
-                               1583EB88108395BE00A3BC0C /* Sources */,
-                               1583EB8A108395BE00A3BC0C /* Frameworks */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "scselect-EmbeddedOther";
-                       productInstallPath = /usr/sbin;
-                       productName = "scselect (Tool)";
-                       productReference = 1583EB90108395BE00A3BC0C /* scselect */;
-                       productType = "com.apple.product-type.tool";
-               };
-               1583EB92108395BE00A3BC0C /* scutil-EmbeddedOther */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 1583EBB3108395BE00A3BC0C /* Build configuration list for PBXNativeTarget "scutil-EmbeddedOther" */;
-                       buildPhases = (
-                               1583EB93108395BE00A3BC0C /* Headers */,
-                               1583EBA1108395BE00A3BC0C /* Sources */,
-                               1583EBAF108395BE00A3BC0C /* Frameworks */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = "scutil-EmbeddedOther";
-                       productInstallPath = /usr/sbin;
-                       productName = "scutil (Tool)";
-                       productReference = 1583EBB6108395BE00A3BC0C /* scutil */;
-                       productType = "com.apple.product-type.tool";
-               };
-               159D53D307528BDA004F8947 /* KernelEventMonitor */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB6020905594A00EEF749 /* Build configuration list for PBXNativeTarget "KernelEventMonitor" */;
-                       buildPhases = (
-                               159D53D007528BDA004F8947 /* Headers */,
-                               159D53D107528BDA004F8947 /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = KernelEventMonitor;
-                       productName = KernelEventMonitor;
-                       productReference = 159D53D407528BDA004F8947 /* libKernelEventMonitor.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               159D53E407528C4A004F8947 /* InterfaceNamer */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB5F60905594A00EEF749 /* Build configuration list for PBXNativeTarget "InterfaceNamer" */;
-                       buildPhases = (
-                               159D53E107528C4A004F8947 /* Headers */,
-                               159D53E207528C4A004F8947 /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = InterfaceNamer;
-                       productName = InterfaceNamer;
-                       productReference = 159D53E507528C4A004F8947 /* libInterfaceNamer.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               159D53EB07528C61004F8947 /* IPMonitor */ = {
+               15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB5EE0905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor" */;
+                       buildConfigurationList = 15D3082416F3E4DA00014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport-EmbeddedSimulator" */;
                        buildPhases = (
                        buildPhases = (
-                               159D53E807528C61004F8947 /* Headers */,
-                               159D53E907528C61004F8947 /* Sources */,
+                               15D3081016F3E4DA00014F82 /* Headers */,
+                               15D3081816F3E4DA00014F82 /* Sources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = IPMonitor;
+                       name = "SimulatorSupport-EmbeddedSimulator";
                        productName = IPMonitor;
                        productName = IPMonitor;
-                       productReference = 159D53EC07528C61004F8947 /* libIPMonitor.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               159D53F207528C79004F8947 /* LinkConfiguration */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB60E0905594A00EEF749 /* Build configuration list for PBXNativeTarget "LinkConfiguration" */;
-                       buildPhases = (
-                               159D53EF07528C79004F8947 /* Headers */,
-                               159D53F007528C79004F8947 /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = LinkConfiguration;
-                       productName = LinkConfiguration;
-                       productReference = 159D53F307528C79004F8947 /* libLinkConfiguration.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
-               159D53F907528C95004F8947 /* PreferencesMonitor */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB6160905594A00EEF749 /* Build configuration list for PBXNativeTarget "PreferencesMonitor" */;
-                       buildPhases = (
-                               159D53F607528C95004F8947 /* Headers */,
-                               159D53F707528C95004F8947 /* Sources */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = PreferencesMonitor;
-                       productName = PreferencesMonitor;
-                       productReference = 159D53FA07528C95004F8947 /* libPreferencesMonitor.a */;
+                       productReference = 15D3082716F3E4DA00014F82 /* libSimulatorSupport_sim.a */;
                        productType = "com.apple.product-type.library.static";
                };
                        productType = "com.apple.product-type.library.static";
                };
-               159D549F07529FFF004F8947 /* configd */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB6220905594A00EEF749 /* Build configuration list for PBXNativeTarget "configd" */;
-                       buildPhases = (
-                               159D54A307529FFF004F8947 /* Headers */,
-                               159D54AB07529FFF004F8947 /* Sources */,
-                               159D54CA07529FFF004F8947 /* Frameworks */,
-                               159D54D507529FFF004F8947 /* CopyFiles */,
-                               159D54D707529FFF004F8947 /* CopyFiles */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                       );
-                       name = configd;
-                       productInstallPath = /usr/sbin;
-                       productName = "configd (Tool)";
-                       productReference = 159D54D907529FFF004F8947 /* configd */;
-                       productType = "com.apple.product-type.tool";
-               };
-               15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */ = {
+               15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */;
+                       buildConfigurationList = 15D3082A16F3E4E100014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport.bundle-EmbeddedSimulator" */;
                        buildPhases = (
                        buildPhases = (
-                               15A5A1E60D5B94190087BDA0 /* Headers */,
-                               15A5A2170D5B94190087BDA0 /* Update Headers */,
-                               15A5A2180D5B94190087BDA0 /* Resources */,
-                               15A5A21D0D5B94190087BDA0 /* Sources */,
-                               15A5A2620D5B94190087BDA0 /* Frameworks */,
+                               15D3082916F3E4E100014F82 /* Resources */,
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
                        );
                        buildRules = (
                        );
                        dependencies = (
                        );
-                       name = "SystemConfiguration.framework-EmbeddedSimulator";
-                       productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                       productName = "SystemConfiguration (Framework)";
-                       productReference = 15A5A26A0D5B94190087BDA0 /* SystemConfiguration.framework */;
-                       productType = "com.apple.product-type.framework";
+                       name = "SimulatorSupport.bundle-EmbeddedSimulator";
+                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+                       productName = IPMonitor.bundle;
+                       productReference = 15D3082D16F3E4E100014F82 /* SimulatorSupport.bundle */;
+                       productType = "com.apple.product-type.bundle";
                };
                };
-               15DAD5DF075913CE0084A6ED /* DNSConfiguration */ = {
+               15DAD5DF075913CE0084A6ED /* libsystem_configuration */ = {
                        isa = PBXNativeTarget;
                        isa = PBXNativeTarget;
-                       buildConfigurationList = 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "DNSConfiguration" */;
+                       buildConfigurationList = 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "libsystem_configuration" */;
                        buildPhases = (
                                15DAD5E0075913CE0084A6ED /* Headers */,
                                15DAD5E4075913CE0084A6ED /* Sources */,
                        buildPhases = (
                                15DAD5E0075913CE0084A6ED /* Headers */,
                                15DAD5E4075913CE0084A6ED /* Sources */,
                        );
                        dependencies = (
                        );
                        );
                        dependencies = (
                        );
-                       name = DNSConfiguration;
+                       name = libsystem_configuration;
                        productInstallPath = /usr/local/lib/system;
                        productName = DNSConfiguration;
                        productInstallPath = /usr/local/lib/system;
                        productName = DNSConfiguration;
-                       productReference = 15DAD5EE075913CE0084A6ED /* libdnsinfo.dylib */;
+                       productReference = 15DAD5EE075913CE0084A6ED /* libsystem_configuration.dylib */;
                        productType = "com.apple.product-type.library.dynamic";
                };
                15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */ = {
                        productType = "com.apple.product-type.library.dynamic";
                };
                15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */ = {
                                15DAD66C07591A1A0084A6ED /* Sources */,
                                15DAD6AD07591A1A0084A6ED /* Frameworks */,
                                15DAD6B007591A1A0084A6ED /* get-mobility-info */,
                                15DAD66C07591A1A0084A6ED /* Sources */,
                                15DAD6AD07591A1A0084A6ED /* Frameworks */,
                                15DAD6B007591A1A0084A6ED /* get-mobility-info */,
-                               15D9DCF910DD909F004E545D /* CopyFiles */,
+                               15D9DCF910DD909F004E545D /* AppWorkaround.plist */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                        productReference = 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */;
                        productType = "com.apple.product-type.framework";
                };
                        productReference = 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */;
                        productType = "com.apple.product-type.framework";
                };
+               15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 15E1B05616EBAE3C00E5F06F /* Build configuration list for PBXNativeTarget "IPMonitor-EmbeddedSimulator" */;
+                       buildPhases = (
+                               15E1B04216EBAE3C00E5F06F /* Headers */,
+                               15E1B04A16EBAE3C00E5F06F /* Sources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "IPMonitor-EmbeddedSimulator";
+                       productName = IPMonitor;
+                       productReference = 15E1B05916EBAE3C00E5F06F /* libIPMonitor_sim.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 15E1B05E16EBAE7800E5F06F /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedSimulator" */;
+                       buildPhases = (
+                               15E1B05B16EBAE7800E5F06F /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "IPMonitor.bundle-EmbeddedSimulator";
+                       productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
+                       productName = IPMonitor.bundle;
+                       productReference = 15E1B06116EBAE7800E5F06F /* IPMonitor.bundle */;
+                       productType = "com.apple.product-type.bundle";
+               };
                15FD72930754DA2B001CC321 /* InterfaceNamer.bundle */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 156EB5FA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "InterfaceNamer.bundle" */;
                15FD72930754DA2B001CC321 /* InterfaceNamer.bundle */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 156EB5FA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "InterfaceNamer.bundle" */;
                        buildConfigurationList = 156EB5F20905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle" */;
                        buildPhases = (
                                15FD72A20754DA4C001CC321 /* Resources */,
                        buildConfigurationList = 156EB5F20905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle" */;
                        buildPhases = (
                                15FD72A20754DA4C001CC321 /* Resources */,
+                               15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                15CB6A7705C0722B0099E85F /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                15CB6A7705C0722B0099E85F /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0430;
+                               LastUpgradeCheck = 0500;
                        };
                        buildConfigurationList = 156EB63E0905594A00EEF749 /* Build configuration list for PBXProject "configd" */;
                        compatibilityVersion = "Xcode 3.2";
                        };
                        buildConfigurationList = 156EB63E0905594A00EEF749 /* Build configuration list for PBXProject "configd" */;
                        compatibilityVersion = "Xcode 3.2";
                        targets = (
                                15CB690005C0722A0099E85F /* All */,
                                15C64A1E0F684C3300D78394 /* configd_libSystem */,
                        targets = (
                                15CB690005C0722A0099E85F /* All */,
                                15C64A1E0F684C3300D78394 /* configd_libSystem */,
-                               15DAD5DF075913CE0084A6ED /* DNSConfiguration */,
+                               15DAD5DF075913CE0084A6ED /* libsystem_configuration */,
                                157BB8AE075924360025DA7A /* configd_base */,
                                15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */,
                                1547001808455B98006787CE /* SCHelper */,
                                157BB8AE075924360025DA7A /* configd_base */,
                                15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */,
                                1547001808455B98006787CE /* SCHelper */,
                                151F5D990CCE98E50093AC3B /* SCMonitor */,
                                151C1CC60CFB487000C5AFD6 /* All-Embedded */,
                                15C64A280F684C6B00D78394 /* configd_libSystem-Embedded */,
                                151F5D990CCE98E50093AC3B /* SCMonitor */,
                                151C1CC60CFB487000C5AFD6 /* All-Embedded */,
                                15C64A280F684C6B00D78394 /* configd_libSystem-Embedded */,
-                               157A84D80D56C63900B6F1A0 /* DNSConfiguration-Embedded */,
+                               157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */,
                                158316CF0CFB774B006F62B9 /* configd_base-Embedded */,
                                1572C4A60CFB55B400E2776E /* SystemConfiguration.framework-Embedded */,
                                158337990CFB6B9E0033AB93 /* SCHelper-Embedded */,
                                158316CF0CFB774B006F62B9 /* configd_base-Embedded */,
                                1572C4A60CFB55B400E2776E /* SystemConfiguration.framework-Embedded */,
                                158337990CFB6B9E0033AB93 /* SCHelper-Embedded */,
                                157433DD0D4A8122002ACA73 /* scselect-Embedded */,
                                157433F00D4A8137002ACA73 /* scutil-Embedded */,
                                15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */,
                                157433DD0D4A8122002ACA73 /* scselect-Embedded */,
                                157433F00D4A8137002ACA73 /* scutil-Embedded */,
                                15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */,
+                               157FDE3B164A075F0040D6A8 /* configd_libSystem-EmbeddedSimulator */,
+                               15732AD616EA6B6700F3AC4C /* libsystem_configuration-EmbeddedSimulator */,
                                151FE2DD0D5B7046000D6DB1 /* configd_base-EmbeddedSimulator */,
                                15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */,
                                151FE2DD0D5B7046000D6DB1 /* configd_base-EmbeddedSimulator */,
                                15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */,
+                               15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */,
+                               15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */,
+                               15AB751216EBFF3400FAA8CE /* SCNetworkReachability-EmbeddedSimulator */,
+                               15AB751A16EBFF8A00FAA8CE /* SCNetworkReachability.bundle-EmbeddedSimulator */,
+                               15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */,
+                               15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */,
+                               15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */,
+                               15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */,
                                151F63DA09328A3C0096DCC9 /* Schema */,
                                151F63DA09328A3C0096DCC9 /* Schema */,
-                               1583E9E01083959E00A3BC0C /* All-EmbeddedOther */,
-                               1583E9FD108395BB00A3BC0C /* configd_libSystem-EmbeddedOther */,
-                               1583EA04108395BB00A3BC0C /* DNSConfiguration-EmbeddedOther */,
-                               1583EA11108395BB00A3BC0C /* configd_base-EmbeddedOther */,
-                               1583EA19108395BB00A3BC0C /* SystemConfiguration.framework-EmbeddedOther */,
-                               1583EA9B108395BB00A3BC0C /* SCHelper-EmbeddedOther */,
-                               1583EAAC108395BB00A3BC0C /* configd_plugins-EmbeddedOther */,
-                               1583EACA108395BB00A3BC0C /* IPMonitor-EmbeddedOther */,
-                               1583EAD9108395BB00A3BC0C /* IPMonitor.bundle-EmbeddedOther */,
-                               1583EAE0108395BB00A3BC0C /* InterfaceNamer-EmbeddedOther */,
-                               1583EAE8108395BC00A3BC0C /* InterfaceNamer.bundle-EmbeddedOther */,
-                               1583EAEF108395BC00A3BC0C /* KernelEventMonitor-EmbeddedOther */,
-                               1583EB00108395BC00A3BC0C /* KernelEventMonitor.bundle-EmbeddedOther */,
-                               1583EB07108395BC00A3BC0C /* LinkConfiguration-EmbeddedOther */,
-                               1583EB0F108395BC00A3BC0C /* LinkConfiguration.bundle-EmbeddedOther */,
-                               1583EB16108395BC00A3BC0C /* Logger.bundle-EmbeddedOther */,
-                               1583EB32108395BD00A3BC0C /* PreferencesMonitor-EmbeddedOther */,
-                               1583EB3A108395BD00A3BC0C /* PreferencesMonitor.bundle-EmbeddedOther */,
-                               1528BFFF1357401900691881 /* SCNetworkReachability-EmbeddedOther */,
-                               1528C0071357401D00691881 /* SCNetworkReachability.bundle-EmbeddedOther */,
-                               1583EB41108395BD00A3BC0C /* configd_executables-EmbeddedOther */,
-                               1583EB4B108395BD00A3BC0C /* configd-EmbeddedOther */,
-                               1583EB86108395BE00A3BC0C /* scselect-EmbeddedOther */,
-                               1583EB92108395BE00A3BC0C /* scutil-EmbeddedOther */,
+                               15E83104167F9AF600FD51EC /* EVERYTHING */,
                        );
                };
 /* End PBXProject section */
                        );
                };
 /* End PBXProject section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1528C0081357401D00691881 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                156CA4810EF853BB00C59A18 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                156CA4810EF853BB00C59A18 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EA4A108395BB00A3BC0C /* Resources */ = {
+               15A5A2180D5B94190087BDA0 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               1583EA4B108395BB00A3BC0C /* Localizable.strings in Resources */,
-                               1583EA4C108395BB00A3BC0C /* NetworkInterface.strings in Resources */,
-                               1583EA4D108395BB00A3BC0C /* NetworkConfiguration.plist in Resources */,
-                               1583EA4E108395BB00A3BC0C /* get-mobility-info in Resources */,
+                               15A5A2190D5B94190087BDA0 /* Localizable.strings in Resources */,
+                               15A5A21A0D5B94190087BDA0 /* NetworkInterface.strings in Resources */,
+                               15A5A21B0D5B94190087BDA0 /* NetworkConfiguration.plist in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EADA108395BB00A3BC0C /* Resources */ = {
+               15AB751B16EBFF8A00FAA8CE /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EAE9108395BC00A3BC0C /* Resources */ = {
+               15D3082916F3E4E100014F82 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EB01108395BC00A3BC0C /* Resources */ = {
+               15DAD66807591A1A0084A6ED /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               15A6F7C40A4B266D00B907EA /* Localizable.strings in Resources */,
+                               15DAD66B07591A1A0084A6ED /* NetworkInterface.strings in Resources */,
+                               15DAD66907591A1A0084A6ED /* NetworkConfiguration.plist in Resources */,
+                               15DAD66A07591A1A0084A6ED /* get-mobility-info in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EB10108395BC00A3BC0C /* Resources */ = {
+               15E1B05B16EBAE7800E5F06F /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EB1D108395BC00A3BC0C /* Resources */ = {
+               15FD72940754DA2B001CC321 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EB3B108395BD00A3BC0C /* Resources */ = {
+               15FD72A20754DA4C001CC321 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               15A5A2180D5B94190087BDA0 /* Resources */ = {
+               15FD72B20754DA69001CC321 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               15A5A2190D5B94190087BDA0 /* Localizable.strings in Resources */,
-                               15A5A21A0D5B94190087BDA0 /* NetworkInterface.strings in Resources */,
-                               15A5A21B0D5B94190087BDA0 /* NetworkConfiguration.plist in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               15DAD66807591A1A0084A6ED /* Resources */ = {
+               15FD72C60754DA7E001CC321 /* Resources */ = {
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               15A6F7C40A4B266D00B907EA /* Localizable.strings in Resources */,
-                               15DAD66B07591A1A0084A6ED /* NetworkInterface.strings in Resources */,
-                               15DAD66907591A1A0084A6ED /* NetworkConfiguration.plist in Resources */,
-                               15DAD66A07591A1A0084A6ED /* get-mobility-info in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               15FD72940754DA2B001CC321 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               151F63DB09328A3C0096DCC9 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        );
                        buildActionMask = 2147483647;
                        files = (
                        );
+                       inputPaths = (
+                               SystemConfiguration.fproj/genSCPreferences.c,
+                       );
+                       outputPaths = (
+                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.h",
+                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitionsPrivate.h",
+                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.c",
+                       );
                        runOnlyForDeploymentPostprocessing = 0;
                        runOnlyForDeploymentPostprocessing = 0;
-               };
-               15FD72A20754DA4C001CC321 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               15FD72B20754DA69001CC321 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               15FD72C60754DA7E001CC321 /* Resources */ = {
-                       isa = PBXResourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
-               151F63DB09328A3C0096DCC9 /* ShellScript */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                               SystemConfiguration.fproj/genSCPreferences.c,
-                       );
-                       outputPaths = (
-                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.h",
-                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitionsPrivate.h",
-                               "${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.c",
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "echo ${BUILT_PRODUCTS_DIR}\ncc -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} ${SRCROOT}/SystemConfiguration.fproj/genSCPreferences.c || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} header   > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.h        || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} private  > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitionsPrivate.h || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} cfile    > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.c        || exit 1\nexit 0";
+                       shellPath = /bin/sh;
+                       shellScript = "echo ${BUILT_PRODUCTS_DIR}\ncc -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} ${SRCROOT}/SystemConfiguration.fproj/genSCPreferences.c || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} header   > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.h        || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} private  > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitionsPrivate.h || exit 1\n${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME} cfile    > ${BUILT_PRODUCTS_DIR}/SCSchemaDefinitions.c        || exit 1\nexit 0";
                };
                153393E40D34999D00FE74E7 /* Update Headers */ = {
                        isa = PBXShellScriptBuildPhase;
                };
                153393E40D34999D00FE74E7 /* Update Headers */ = {
                        isa = PBXShellScriptBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} split\nfi\n";
+                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} split\nfi";
                };
                1572C5270CFB55B400E2776E /* get-mobility-info */ = {
                        isa = PBXShellScriptBuildPhase;
                };
                1572C5270CFB55B400E2776E /* get-mobility-info */ = {
                        isa = PBXShellScriptBuildPhase;
                        shellScript = "mkdir -p \"${DSTROOT}/usr/local/bin\"\nln -fs \"${INSTALL_PATH}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/get-mobility-info\" \"${DSTROOT}/usr/local/bin/\"\n";
                        showEnvVarsInLog = 0;
                };
                        shellScript = "mkdir -p \"${DSTROOT}/usr/local/bin\"\nln -fs \"${INSTALL_PATH}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/get-mobility-info\" \"${DSTROOT}/usr/local/bin/\"\n";
                        showEnvVarsInLog = 0;
                };
-               1583EA49108395BB00A3BC0C /* Update Headers */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                               "$(SRCROOT)/SystemConfiguration.fproj/update-headers",
-                       );
-                       name = "Update Headers";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} split\nfi\n";
-               };
-               1583EA95108395BB00A3BC0C /* get-mobility-info */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 8;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       name = "get-mobility-info";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-                       shellPath = /bin/sh;
-                       shellScript = "mkdir -p \"${DSTROOT}/usr/local/bin\"\nln -fs \"${INSTALL_PATH}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/get-mobility-info\" \"${DSTROOT}/usr/local/bin/\"\n";
-                       showEnvVarsInLog = 0;
-               };
                15A5A2170D5B94190087BDA0 /* Update Headers */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                15A5A2170D5B94190087BDA0 /* Update Headers */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} split\nfi\n";
+                       shellScript = "if [ -x ${SCRIPT_INPUT_FILE_0} ]; then\n\t${SCRIPT_INPUT_FILE_0} split\nfi";
                        showEnvVarsInLog = 0;
                };
                15AC82480D376E2400A579D0 /* Update Headers */ = {
                        showEnvVarsInLog = 0;
                };
                15AC82480D376E2400A579D0 /* Update Headers */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1528C0011357401900691881 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1528C0021357401900691881 /* SCNetworkReachabilityServer_server.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                1547001A08455B98006787CE /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                1547001A08455B98006787CE /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                155847600754FDCD0046C2E9 /* net_service.c in Sources */,
                                155847610754FDCD0046C2E9 /* net_set.c in Sources */,
                                72B43729113C7BFC00EBF1B6 /* nc.c in Sources */,
                                155847600754FDCD0046C2E9 /* net_service.c in Sources */,
                                155847610754FDCD0046C2E9 /* net_set.c in Sources */,
                                72B43729113C7BFC00EBF1B6 /* nc.c in Sources */,
+                               F9B50FF316A4CBB200CA274E /* IPMonitorControlPrefs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               1572C5140CFB55B400E2776E /* config.defs in Sources */,
                                1572C4DF0CFB55B400E2776E /* SCSchemaDefinitions.c in Sources */,
                                1572C4E00CFB55B400E2776E /* SCD.c in Sources */,
                                1572C4E10CFB55B400E2776E /* SCDKeys.c in Sources */,
                                1572C4DF0CFB55B400E2776E /* SCSchemaDefinitions.c in Sources */,
                                1572C4E00CFB55B400E2776E /* SCD.c in Sources */,
                                1572C4E10CFB55B400E2776E /* SCDKeys.c in Sources */,
                                1572C4F90CFB55B400E2776E /* SCP.c in Sources */,
                                1572C4FA0CFB55B400E2776E /* SCPOpen.c in Sources */,
                                1572C4FB0CFB55B400E2776E /* SCPLock.c in Sources */,
                                1572C4F90CFB55B400E2776E /* SCP.c in Sources */,
                                1572C4FA0CFB55B400E2776E /* SCPOpen.c in Sources */,
                                1572C4FB0CFB55B400E2776E /* SCPLock.c in Sources */,
+                               B0C9689D174426D100889853 /* SNHelper.c in Sources */,
                                1572C4FC0CFB55B400E2776E /* SCPUnlock.c in Sources */,
                                1572C4FD0CFB55B400E2776E /* SCPList.c in Sources */,
                                1572C4FE0CFB55B400E2776E /* SCPGet.c in Sources */,
                                1572C4FC0CFB55B400E2776E /* SCPUnlock.c in Sources */,
                                1572C4FD0CFB55B400E2776E /* SCPList.c in Sources */,
                                1572C4FE0CFB55B400E2776E /* SCPGet.c in Sources */,
                                1572C5000CFB55B400E2776E /* SCPSet.c in Sources */,
                                1572C5010CFB55B400E2776E /* SCPRemove.c in Sources */,
                                1572C5020CFB55B400E2776E /* SCPCommit.c in Sources */,
                                1572C5000CFB55B400E2776E /* SCPSet.c in Sources */,
                                1572C5010CFB55B400E2776E /* SCPRemove.c in Sources */,
                                1572C5020CFB55B400E2776E /* SCPCommit.c in Sources */,
-                               1572C5030CFB55B400E2776E /* SCPApply.c in Sources */,
                                1572C5040CFB55B400E2776E /* SCPPath.c in Sources */,
                                1572C5040CFB55B400E2776E /* SCPPath.c in Sources */,
+                               1572C5030CFB55B400E2776E /* SCPApply.c in Sources */,
                                1572C5060CFB55B400E2776E /* SCDHostName.c in Sources */,
                                1572C5070CFB55B400E2776E /* SCLocation.c in Sources */,
                                1572C5080CFB55B400E2776E /* SCNetwork.c in Sources */,
                                1572C5060CFB55B400E2776E /* SCDHostName.c in Sources */,
                                1572C5070CFB55B400E2776E /* SCLocation.c in Sources */,
                                1572C5080CFB55B400E2776E /* SCNetwork.c in Sources */,
                                1572C5100CFB55B400E2776E /* DeviceOnHold.c in Sources */,
                                1572C5110CFB55B400E2776E /* LinkConfiguration.c in Sources */,
                                1572C5120CFB55B400E2776E /* dy_framework.c in Sources */,
                                1572C5100CFB55B400E2776E /* DeviceOnHold.c in Sources */,
                                1572C5110CFB55B400E2776E /* LinkConfiguration.c in Sources */,
                                1572C5120CFB55B400E2776E /* dy_framework.c in Sources */,
-                               1572C5140CFB55B400E2776E /* config.defs in Sources */,
                                1572C5150CFB55B400E2776E /* SCPreferencesPathKey.c in Sources */,
                                1572C5150CFB55B400E2776E /* SCPreferencesPathKey.c in Sources */,
-                               1572C5180CFB55B400E2776E /* shared_dns_info.defs in Sources */,
                                1572C5190CFB55B400E2776E /* SCNetworkConfigurationInternal.c in Sources */,
                                1572C51A0CFB55B400E2776E /* SCNetworkInterface.c in Sources */,
                                1572C51B0CFB55B400E2776E /* SCNetworkProtocol.c in Sources */,
                                1572C5190CFB55B400E2776E /* SCNetworkConfigurationInternal.c in Sources */,
                                1572C51A0CFB55B400E2776E /* SCNetworkInterface.c in Sources */,
                                1572C51B0CFB55B400E2776E /* SCNetworkProtocol.c in Sources */,
                                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */,
                                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */,
                                15C330BD134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
                                152691DB1129EEA6006BD2D5 /* BridgeConfiguration.c in Sources */,
                                152691DE1129EEC2006BD2D5 /* VLANConfiguration.c in Sources */,
                                15C330BD134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
-                               15C330C1134B92780028E36B /* rb.c in Sources */,
+                               D61AAEB01522C99C0066B003 /* scprefs_observer.c in Sources */,
+                               C4F1848116237AFC00D97043 /* VPNService.c in Sources */,
+                               C4CDB8161631935700819B44 /* VPNFlow.c in Sources */,
+                               B03FEFB716376D2800A1B88F /* VPNAppLayer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732A7F16EA503200F3AC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732A8016EA503200F3AC4C /* configd.m in Sources */,
+                               15732A8116EA503200F3AC4C /* _SCD.c in Sources */,
+                               15732A8216EA503200F3AC4C /* configd_server.c in Sources */,
+                               15732A8316EA503200F3AC4C /* notify_server.c in Sources */,
+                               15732A8416EA503200F3AC4C /* plugin_support.c in Sources */,
+                               15732A8516EA503200F3AC4C /* session.c in Sources */,
+                               15732A8616EA503200F3AC4C /* pattern.c in Sources */,
+                               15732A8716EA503200F3AC4C /* _configopen.c in Sources */,
+                               15732A8816EA503200F3AC4C /* _configclose.c in Sources */,
+                               15732A8916EA503200F3AC4C /* _configunlock.c in Sources */,
+                               15732A8A16EA503200F3AC4C /* _configlist.c in Sources */,
+                               15732A8B16EA503200F3AC4C /* _configadd.c in Sources */,
+                               15732A8C16EA503200F3AC4C /* _configget.c in Sources */,
+                               15732A8D16EA503200F3AC4C /* _configset.c in Sources */,
+                               15732A8E16EA503200F3AC4C /* _configremove.c in Sources */,
+                               15732A8F16EA503200F3AC4C /* _confignotify.c in Sources */,
+                               15732A9016EA503200F3AC4C /* _notifyadd.c in Sources */,
+                               15732A9116EA503200F3AC4C /* _notifyremove.c in Sources */,
+                               15732A9216EA503200F3AC4C /* _notifychanges.c in Sources */,
+                               15732A9316EA503200F3AC4C /* _notifyviaport.c in Sources */,
+                               15732A9416EA503200F3AC4C /* _notifyviafd.c in Sources */,
+                               15732A9516EA503200F3AC4C /* _notifyviasignal.c in Sources */,
+                               15732A9616EA503200F3AC4C /* _notifycancel.c in Sources */,
+                               15732A9716EA503200F3AC4C /* _snapshot.c in Sources */,
+                               15732A9816EA503200F3AC4C /* config.defs in Sources */,
+                               15732A9916EA503200F3AC4C /* dnsinfo_server.c in Sources */,
+                               15732A9A16EA503200F3AC4C /* SCNetworkReachabilityServer_server.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732ABD16EA511900F3AC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732ABE16EA511900F3AC4C /* scutil.c in Sources */,
+                               15732ABF16EA511900F3AC4C /* commands.c in Sources */,
+                               15732AC016EA511900F3AC4C /* dictionary.c in Sources */,
+                               15732AC116EA511900F3AC4C /* session.c in Sources */,
+                               15732AC216EA511900F3AC4C /* cache.c in Sources */,
+                               15732AC316EA511900F3AC4C /* notifications.c in Sources */,
+                               15732AC416EA511900F3AC4C /* tests.c in Sources */,
+                               15732AC516EA511900F3AC4C /* prefs.c in Sources */,
+                               15732AC616EA511900F3AC4C /* net.c in Sources */,
+                               15732AC716EA511900F3AC4C /* net_interface.c in Sources */,
+                               15732AC816EA511900F3AC4C /* net_protocol.c in Sources */,
+                               15732AC916EA511900F3AC4C /* net_service.c in Sources */,
+                               15732ACA16EA511900F3AC4C /* net_set.c in Sources */,
+                               15732ACB16EA511900F3AC4C /* nc.c in Sources */,
+                               15732ACC16EA511900F3AC4C /* IPMonitorControlPrefs.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15732ADC16EA6B6700F3AC4C /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15732ADD16EA6B6700F3AC4C /* dnsinfo_copy.c in Sources */,
+                               15732ADE16EA6B6700F3AC4C /* network_information.c in Sources */,
+                               15732ADF16EA6B6700F3AC4C /* libSystemConfiguration_client.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1574340B0D4A8137002ACA73 /* net_service.c in Sources */,
                                1574340C0D4A8137002ACA73 /* net_set.c in Sources */,
                                72B4372B113C7BFC00EBF1B6 /* nc.c in Sources */,
                                1574340B0D4A8137002ACA73 /* net_service.c in Sources */,
                                1574340C0D4A8137002ACA73 /* net_set.c in Sources */,
                                72B4372B113C7BFC00EBF1B6 /* nc.c in Sources */,
+                               F9B50FF416A4CBB800CA274E /* IPMonitorControlPrefs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               157A84DE0D56C63900B6F1A0 /* shared_dns_info.defs in Sources */,
                                157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */,
                                157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */,
-                               157A84E00D56C63900B6F1A0 /* dnsinfo_private.c in Sources */,
                                D661C2F11368BB600030B977 /* network_information.c in Sources */,
                                D661C2F11368BB600030B977 /* network_information.c in Sources */,
+                               153338BD14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        files = (
                                157A84FB0D56C7E800B6F1A0 /* dns-configuration.c in Sources */,
                                15D48EC10F67061F00B4711E /* dnsinfo_create.c in Sources */,
                        files = (
                                157A84FB0D56C7E800B6F1A0 /* dns-configuration.c in Sources */,
                                15D48EC10F67061F00B4711E /* dnsinfo_create.c in Sources */,
+                               150BEC1A14CA252200237116 /* dnsinfo_server.c in Sources */,
                                155281020E3E4A0F00C54315 /* ip_plugin.c in Sources */,
                                E4F211D3137B0AB900BBB915 /* network_information_priv.c in Sources */,
                                155281020E3E4A0F00C54315 /* ip_plugin.c in Sources */,
                                E4F211D3137B0AB900BBB915 /* network_information_priv.c in Sources */,
+                               153ACCA914E322D5005029A5 /* network_information_server.c in Sources */,
                                1575FD2712CD15C60003D86E /* proxy-configuration.c in Sources */,
                                157A84FC0D56C7E800B6F1A0 /* set-hostname.c in Sources */,
                                1575FD2712CD15C60003D86E /* proxy-configuration.c in Sources */,
                                157A84FC0D56C7E800B6F1A0 /* set-hostname.c in Sources */,
-                               15D48ED40F6707A600B4711E /* shared_dns_info.defs in Sources */,
+                               1596A7B214EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */,
+                               D61AAEB11522C99C0066B003 /* scprefs_observer.c in Sources */,
+                               F9A3781116A4849100C57CDC /* IPMonitorControlPrefs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                158317450CFB80A1006F62B9 /* _notifycancel.c in Sources */,
                                158317460CFB80A1006F62B9 /* _snapshot.c in Sources */,
                                158317470CFB80A1006F62B9 /* config.defs in Sources */,
                                158317450CFB80A1006F62B9 /* _notifycancel.c in Sources */,
                                158317460CFB80A1006F62B9 /* _snapshot.c in Sources */,
                                158317470CFB80A1006F62B9 /* config.defs in Sources */,
-                               158317480CFB80A1006F62B9 /* dnsinfo_private.c in Sources */,
                                158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */,
                                158317490CFB80A1006F62B9 /* dnsinfo_server.c in Sources */,
-                               1583174A0CFB80A1006F62B9 /* shared_dns_info.defs in Sources */,
                                15C330E5134BD2AC0028E36B /* SCNetworkReachabilityServer_server.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                15C330E5134BD2AC0028E36B /* SCNetworkReachabilityServer_server.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               1583EA08108395BB00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA09108395BB00A3BC0C /* shared_dns_info.defs in Sources */,
-                               1583EA0A108395BB00A3BC0C /* dnsinfo_copy.c in Sources */,
-                               1583EA0B108395BB00A3BC0C /* dnsinfo_private.c in Sources */,
-                               151E0CA51378EE3B00C5DA2A /* network_information.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EA4F108395BB00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EA50108395BB00A3BC0C /* SCSchemaDefinitions.c in Sources */,
-                               1583EA51108395BB00A3BC0C /* SCD.c in Sources */,
-                               1583EA52108395BB00A3BC0C /* SCDKeys.c in Sources */,
-                               1583EA53108395BB00A3BC0C /* SCDPrivate.c in Sources */,
-                               1583EA54108395BB00A3BC0C /* SCDPlugin.c in Sources */,
-                               1583EA55108395BB00A3BC0C /* SCDOpen.c in Sources */,
-                               1583EA58108395BB00A3BC0C /* SCDList.c in Sources */,
-                               1583EA59108395BB00A3BC0C /* SCDAdd.c in Sources */,
-                               1583EA5A108395BB00A3BC0C /* SCDGet.c in Sources */,
-                               1583EA5B108395BB00A3BC0C /* SCDSet.c in Sources */,
-                               1583EA5C108395BB00A3BC0C /* SCDRemove.c in Sources */,
-                               1583EA5E108395BB00A3BC0C /* SCDNotify.c in Sources */,
-                               1583EA5F108395BB00A3BC0C /* SCDNotifierSetKeys.c in Sources */,
-                               1583EA60108395BB00A3BC0C /* SCDNotifierAdd.c in Sources */,
-                               1583EA61108395BB00A3BC0C /* SCDNotifierRemove.c in Sources */,
-                               1583EA62108395BB00A3BC0C /* SCDNotifierGetChanges.c in Sources */,
-                               1583EA63108395BB00A3BC0C /* SCDNotifierWait.c in Sources */,
-                               1583EA64108395BB00A3BC0C /* SCDNotifierInformViaCallback.c in Sources */,
-                               1583EA66108395BB00A3BC0C /* SCDNotifierInformViaFD.c in Sources */,
-                               1583EA67108395BB00A3BC0C /* SCDNotifierInformViaSignal.c in Sources */,
-                               1583EA68108395BB00A3BC0C /* SCDNotifierCancel.c in Sources */,
-                               1583EA69108395BB00A3BC0C /* SCDSnapshot.c in Sources */,
-                               1583EA6A108395BB00A3BC0C /* SCP.c in Sources */,
-                               1583EA6B108395BB00A3BC0C /* SCPOpen.c in Sources */,
-                               1583EA6C108395BB00A3BC0C /* SCPLock.c in Sources */,
-                               1583EA6D108395BB00A3BC0C /* SCPUnlock.c in Sources */,
-                               1583EA6E108395BB00A3BC0C /* SCPList.c in Sources */,
-                               1583EA6F108395BB00A3BC0C /* SCPGet.c in Sources */,
-                               1583EA70108395BB00A3BC0C /* SCPAdd.c in Sources */,
-                               1583EA71108395BB00A3BC0C /* SCPSet.c in Sources */,
-                               1583EA72108395BB00A3BC0C /* SCPRemove.c in Sources */,
-                               1583EA73108395BB00A3BC0C /* SCPCommit.c in Sources */,
-                               1583EA74108395BB00A3BC0C /* SCPApply.c in Sources */,
-                               1583EA75108395BB00A3BC0C /* SCPPath.c in Sources */,
-                               1583EA76108395BB00A3BC0C /* SCDHostName.c in Sources */,
-                               1583EA77108395BB00A3BC0C /* SCLocation.c in Sources */,
-                               1583EA78108395BB00A3BC0C /* SCNetwork.c in Sources */,
-                               1583EA79108395BB00A3BC0C /* pppcontroller.defs in Sources */,
-                               1583EA7A108395BB00A3BC0C /* SCNetworkConnection.c in Sources */,
-                               1583EA7B108395BB00A3BC0C /* SCNetworkConnectionPrivate.c in Sources */,
-                               1583EA7C108395BB00A3BC0C /* SCNetworkReachability.c in Sources */,
-                               1583EA7D108395BB00A3BC0C /* SCProxies.c in Sources */,
-                               1583EA7E108395BB00A3BC0C /* DHCP.c in Sources */,
-                               1583EA7F108395BB00A3BC0C /* moh.c in Sources */,
-                               1583EA80108395BB00A3BC0C /* DeviceOnHold.c in Sources */,
-                               1583EA81108395BB00A3BC0C /* LinkConfiguration.c in Sources */,
-                               1583EA82108395BB00A3BC0C /* dy_framework.c in Sources */,
-                               1583EA83108395BB00A3BC0C /* config.defs in Sources */,
-                               1583EA84108395BB00A3BC0C /* SCPreferencesPathKey.c in Sources */,
-                               1583EA85108395BB00A3BC0C /* shared_dns_info.defs in Sources */,
-                               1583EA86108395BB00A3BC0C /* SCNetworkConfigurationInternal.c in Sources */,
-                               1583EA87108395BB00A3BC0C /* SCNetworkInterface.c in Sources */,
-                               1583EA88108395BB00A3BC0C /* SCNetworkProtocol.c in Sources */,
-                               1583EA89108395BB00A3BC0C /* SCNetworkService.c in Sources */,
-                               1583EA8A108395BB00A3BC0C /* SCNetworkSet.c in Sources */,
-                               1583EA8C108395BB00A3BC0C /* SCHelper_client.c in Sources */,
-                               1583EA8D108395BB00A3BC0C /* SCPreferencesKeychainPrivate.c in Sources */,
-                               1583EA8E108395BB00A3BC0C /* SCNetworkSignature.c in Sources */,
-                               1583EA8F108395BB00A3BC0C /* CaptiveNetwork.c in Sources */,
-                               158E59601107CAF10062081E /* helper.defs in Sources */,
-                               152691DD1129EEB1006BD2D5 /* BridgeConfiguration.c in Sources */,
-                               152691E01129EECB006BD2D5 /* VLANConfiguration.c in Sources */,
-                               15C330BF134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
-                               15C330C3134B92780028E36B /* rb.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EA9F108395BB00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAA0108395BB00A3BC0C /* SCHelper_server.c in Sources */,
-                               152E0E8110FE820E00E402F2 /* helper.defs in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EACF108395BB00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAD1108395BB00A3BC0C /* dns-configuration.c in Sources */,
-                               1583EAD3108395BB00A3BC0C /* dnsinfo_create.c in Sources */,
-                               1583EAD0108395BB00A3BC0C /* ip_plugin.c in Sources */,
-                               E4F211D5137B0AD700BBB915 /* network_information_priv.c in Sources */,
-                               1575FD2B12CD15C60003D86E /* proxy-configuration.c in Sources */,
-                               1583EAD2108395BB00A3BC0C /* set-hostname.c in Sources */,
-                               1583EAD4108395BB00A3BC0C /* shared_dns_info.defs in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EAE2108395BB00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAE3108395BB00A3BC0C /* ifnamer.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EAF6108395BC00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EAF7108395BC00A3BC0C /* cache.c in Sources */,
-                               1583EAF8108395BC00A3BC0C /* ev_dlil.c in Sources */,
-                               1583EAF9108395BC00A3BC0C /* ev_ipv4.c in Sources */,
-                               1583EAFA108395BC00A3BC0C /* ev_ipv6.c in Sources */,
-                               1583EAFB108395BC00A3BC0C /* eventmon.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB09108395BC00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB0A108395BC00A3BC0C /* linkconfig.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB17108395BC00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB18108395BC00A3BC0C /* logger.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB34108395BD00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB35108395BD00A3BC0C /* prefsmon.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB54108395BD00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB55108395BD00A3BC0C /* configd.m in Sources */,
-                               1583EB56108395BD00A3BC0C /* _SCD.c in Sources */,
-                               1583EB57108395BD00A3BC0C /* configd_server.c in Sources */,
-                               1583EB58108395BD00A3BC0C /* notify_server.c in Sources */,
-                               1583EB59108395BD00A3BC0C /* plugin_support.c in Sources */,
-                               1583EB5A108395BD00A3BC0C /* session.c in Sources */,
-                               1583EB5B108395BD00A3BC0C /* pattern.c in Sources */,
-                               1583EB5C108395BD00A3BC0C /* _configopen.c in Sources */,
-                               1583EB5D108395BD00A3BC0C /* _configclose.c in Sources */,
-                               1583EB5F108395BD00A3BC0C /* _configunlock.c in Sources */,
-                               1583EB60108395BD00A3BC0C /* _configlist.c in Sources */,
-                               1583EB61108395BD00A3BC0C /* _configadd.c in Sources */,
-                               1583EB62108395BD00A3BC0C /* _configget.c in Sources */,
-                               1583EB63108395BD00A3BC0C /* _configset.c in Sources */,
-                               1583EB64108395BD00A3BC0C /* _configremove.c in Sources */,
-                               1583EB66108395BD00A3BC0C /* _confignotify.c in Sources */,
-                               1583EB67108395BD00A3BC0C /* _notifyadd.c in Sources */,
-                               1583EB68108395BD00A3BC0C /* _notifyremove.c in Sources */,
-                               1583EB69108395BD00A3BC0C /* _notifychanges.c in Sources */,
-                               1583EB6A108395BD00A3BC0C /* _notifyviaport.c in Sources */,
-                               1583EB6B108395BD00A3BC0C /* _notifyviafd.c in Sources */,
-                               1583EB6C108395BD00A3BC0C /* _notifyviasignal.c in Sources */,
-                               1583EB6D108395BD00A3BC0C /* _notifycancel.c in Sources */,
-                               1583EB6E108395BD00A3BC0C /* _snapshot.c in Sources */,
-                               1583EB6F108395BD00A3BC0C /* config.defs in Sources */,
-                               1583EB70108395BD00A3BC0C /* dnsinfo_private.c in Sources */,
-                               1583EB71108395BD00A3BC0C /* dnsinfo_server.c in Sources */,
-                               1583EB72108395BD00A3BC0C /* shared_dns_info.defs in Sources */,
-                               15C330E6134BD2BB0028E36B /* SCNetworkReachabilityServer_server.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EB88108395BE00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EB89108395BE00A3BC0C /* scselect.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               1583EBA1108395BE00A3BC0C /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               1583EBA2108395BE00A3BC0C /* scutil.c in Sources */,
-                               1583EBA3108395BE00A3BC0C /* commands.c in Sources */,
-                               1583EBA4108395BE00A3BC0C /* dictionary.c in Sources */,
-                               1583EBA5108395BE00A3BC0C /* session.c in Sources */,
-                               1583EBA6108395BE00A3BC0C /* cache.c in Sources */,
-                               1583EBA7108395BE00A3BC0C /* notifications.c in Sources */,
-                               1583EBA8108395BE00A3BC0C /* tests.c in Sources */,
-                               1583EBA9108395BE00A3BC0C /* prefs.c in Sources */,
-                               1583EBAA108395BE00A3BC0C /* net.c in Sources */,
-                               1583EBAB108395BE00A3BC0C /* net_interface.c in Sources */,
-                               1583EBAC108395BE00A3BC0C /* net_protocol.c in Sources */,
-                               1583EBAD108395BE00A3BC0C /* net_service.c in Sources */,
-                               1583EBAE108395BE00A3BC0C /* net_set.c in Sources */,
-                               15B274A5114467CD003414AD /* nc.c in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                159D53D107528BDA004F8947 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                159D53D107528BDA004F8947 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                                159D541807528E09004F8947 /* dns-configuration.c in Sources */,
                                15D48EBF0F67061600B4711E /* dnsinfo_create.c in Sources */,
                                1522FCFB0FA7FE4B00B24128 /* dnsinfo_flatfile.c in Sources */,
                                159D541807528E09004F8947 /* dns-configuration.c in Sources */,
                                15D48EBF0F67061600B4711E /* dnsinfo_create.c in Sources */,
                                1522FCFB0FA7FE4B00B24128 /* dnsinfo_flatfile.c in Sources */,
+                               150BEC1814CA24F900237116 /* dnsinfo_server.c in Sources */,
                                159D541707528E05004F8947 /* ip_plugin.c in Sources */,
                                E49173E1137C4E4F0000089F /* network_information_priv.c in Sources */,
                                159D541707528E05004F8947 /* ip_plugin.c in Sources */,
                                E49173E1137C4E4F0000089F /* network_information_priv.c in Sources */,
+                               153ACCA814E322D5005029A5 /* network_information_server.c in Sources */,
                                1575FD2912CD15C60003D86E /* proxy-configuration.c in Sources */,
                                154361E00752C81800A8EC6C /* set-hostname.c in Sources */,
                                1572EB7B0A506D3B00D02459 /* smb-configuration.c in Sources */,
                                1575FD2912CD15C60003D86E /* proxy-configuration.c in Sources */,
                                154361E00752C81800A8EC6C /* set-hostname.c in Sources */,
                                1572EB7B0A506D3B00D02459 /* smb-configuration.c in Sources */,
-                               15D48ED30F67079B00B4711E /* shared_dns_info.defs in Sources */,
+                               1596A7B114EDB73D00798C39 /* libSystemConfiguration_server.c in Sources */,
+                               D61AAEAF1522C99C0066B003 /* scprefs_observer.c in Sources */,
+                               F9A3781016A4847700C57CDC /* IPMonitorControlPrefs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                159D54C407529FFF004F8947 /* _notifycancel.c in Sources */,
                                159D54C507529FFF004F8947 /* _snapshot.c in Sources */,
                                159D54C607529FFF004F8947 /* config.defs in Sources */,
                                159D54C407529FFF004F8947 /* _notifycancel.c in Sources */,
                                159D54C507529FFF004F8947 /* _snapshot.c in Sources */,
                                159D54C607529FFF004F8947 /* config.defs in Sources */,
-                               159D54C707529FFF004F8947 /* dnsinfo_private.c in Sources */,
                                159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */,
                                159D54C807529FFF004F8947 /* dnsinfo_server.c in Sources */,
-                               159D54C907529FFF004F8947 /* shared_dns_info.defs in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                15A5A2510D5B94190087BDA0 /* dy_framework.c in Sources */,
                                15A5A2530D5B94190087BDA0 /* config.defs in Sources */,
                                15A5A2540D5B94190087BDA0 /* SCPreferencesPathKey.c in Sources */,
                                15A5A2510D5B94190087BDA0 /* dy_framework.c in Sources */,
                                15A5A2530D5B94190087BDA0 /* config.defs in Sources */,
                                15A5A2540D5B94190087BDA0 /* SCPreferencesPathKey.c in Sources */,
-                               15A5A2550D5B94190087BDA0 /* dnsinfo_private.c in Sources */,
-                               15A5A2560D5B94190087BDA0 /* dnsinfo_copy.c in Sources */,
-                               15A5A2570D5B94190087BDA0 /* shared_dns_info.defs in Sources */,
                                15A5A2580D5B94190087BDA0 /* SCNetworkConfigurationInternal.c in Sources */,
                                15A5A2590D5B94190087BDA0 /* SCNetworkInterface.c in Sources */,
                                15A5A25A0D5B94190087BDA0 /* SCNetworkProtocol.c in Sources */,
                                15A5A2580D5B94190087BDA0 /* SCNetworkConfigurationInternal.c in Sources */,
                                15A5A2590D5B94190087BDA0 /* SCNetworkInterface.c in Sources */,
                                15A5A25A0D5B94190087BDA0 /* SCNetworkProtocol.c in Sources */,
                                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */,
                                152691DF1129EEC8006BD2D5 /* VLANConfiguration.c in Sources */,
                                15C330BE134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
                                152691DC1129EEAD006BD2D5 /* BridgeConfiguration.c in Sources */,
                                152691DF1129EEC8006BD2D5 /* VLANConfiguration.c in Sources */,
                                15C330BE134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
-                               15C330C2134B92780028E36B /* rb.c in Sources */,
+                               D61AAEB21522C99C0066B003 /* scprefs_observer.c in Sources */,
+                               C4F1848316237B1400D97043 /* VPNService.c in Sources */,
+                               B0FEF41B1644089200174B99 /* VPNAppLayer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15AB751416EBFF3400FAA8CE /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15AB751516EBFF3400FAA8CE /* SCNetworkReachabilityServer_server.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15D3081816F3E4DA00014F82 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15D3083916F3EB8600014F82 /* simulator_support.c in Sources */,
+                               15C8C6BF170AAB4E005375CE /* cache.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               15DAD5E5075913CE0084A6ED /* shared_dns_info.defs in Sources */,
                                15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */,
                                15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */,
-                               15DAD5E7075913CE0084A6ED /* dnsinfo_private.c in Sources */,
                                D6986A79136891650091C931 /* network_information.c in Sources */,
                                D6986A79136891650091C931 /* network_information.c in Sources */,
+                               153338BC14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                15DAD68807591A1A0084A6ED /* SCPLock.c in Sources */,
                                15DAD68907591A1A0084A6ED /* SCPUnlock.c in Sources */,
                                15DAD68A07591A1A0084A6ED /* SCPList.c in Sources */,
                                15DAD68807591A1A0084A6ED /* SCPLock.c in Sources */,
                                15DAD68907591A1A0084A6ED /* SCPUnlock.c in Sources */,
                                15DAD68A07591A1A0084A6ED /* SCPList.c in Sources */,
+                               B0C9689C174426C600889853 /* SNHelper.c in Sources */,
                                15DAD68B07591A1A0084A6ED /* SCPGet.c in Sources */,
                                15DAD68C07591A1A0084A6ED /* SCPAdd.c in Sources */,
                                15DAD68D07591A1A0084A6ED /* SCPSet.c in Sources */,
                                15DAD68B07591A1A0084A6ED /* SCPGet.c in Sources */,
                                15DAD68C07591A1A0084A6ED /* SCPAdd.c in Sources */,
                                15DAD68D07591A1A0084A6ED /* SCPSet.c in Sources */,
                                15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */,
                                15DAD6A007591A1A0084A6ED /* config.defs in Sources */,
                                15DAD6A207591A1A0084A6ED /* SCPreferencesPathKey.c in Sources */,
                                15DAD69F07591A1A0084A6ED /* VLANConfiguration.c in Sources */,
                                15DAD6A007591A1A0084A6ED /* config.defs in Sources */,
                                15DAD6A207591A1A0084A6ED /* SCPreferencesPathKey.c in Sources */,
-                               15DAD6A507591A1A0084A6ED /* shared_dns_info.defs in Sources */,
                                15DAD6A607591A1A0084A6ED /* SCNetworkConfigurationInternal.c in Sources */,
                                15DAD6A707591A1A0084A6ED /* SCNetworkInterface.c in Sources */,
                                15DAD6A807591A1A0084A6ED /* SCNetworkProtocol.c in Sources */,
                                15DAD6A607591A1A0084A6ED /* SCNetworkConfigurationInternal.c in Sources */,
                                15DAD6A707591A1A0084A6ED /* SCNetworkInterface.c in Sources */,
                                15DAD6A807591A1A0084A6ED /* SCNetworkProtocol.c in Sources */,
                                15AAA7F9108E310700C2A607 /* VPNTunnel.c in Sources */,
                                158E595E1107CAE40062081E /* helper.defs in Sources */,
                                15C330BC134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
                                15AAA7F9108E310700C2A607 /* VPNTunnel.c in Sources */,
                                158E595E1107CAE40062081E /* helper.defs in Sources */,
                                15C330BC134B92780028E36B /* SCNetworkReachabilityServer_client.c in Sources */,
-                               15C330C0134B92780028E36B /* rb.c in Sources */,
+                               D61AAEAE1522C99C0066B003 /* scprefs_observer.c in Sources */,
+                               C4F1848016237AFC00D97043 /* VPNService.c in Sources */,
+                               C4CDB8151631935700819B44 /* VPNFlow.c in Sources */,
+                               B03FEFB616376D2800A1B88F /* VPNAppLayer.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               15E1B04A16EBAE3C00E5F06F /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               15E1B04B16EBAE3C00E5F06F /* dns-configuration.c in Sources */,
+                               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 */,
+                               15E1B05016EBAE3C00E5F06F /* network_information_server.c in Sources */,
+                               15E1B05116EBAE3C00E5F06F /* proxy-configuration.c in Sources */,
+                               15E1B05316EBAE3C00E5F06F /* libSystemConfiguration_server.c in Sources */,
+                               15E1B05416EBAE3C00E5F06F /* scprefs_observer.c in Sources */,
+                               15E1B05516EBAE3C00E5F06F /* IPMonitorControlPrefs.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        target = 1528BFF813573FF500691881 /* SCNetworkReachability.bundle-Embedded */;
                        targetProxy = 1528C010135741C300691881 /* PBXContainerItemProxy */;
                };
                        target = 1528BFF813573FF500691881 /* SCNetworkReachability.bundle-Embedded */;
                        targetProxy = 1528C010135741C300691881 /* PBXContainerItemProxy */;
                };
-               1528C0131357420300691881 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1528BFFF1357401900691881 /* SCNetworkReachability-EmbeddedOther */;
-                       targetProxy = 1528C0121357420300691881 /* PBXContainerItemProxy */;
-               };
-               1528C0151357420300691881 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1528C0071357401D00691881 /* SCNetworkReachability.bundle-EmbeddedOther */;
-                       targetProxy = 1528C0141357420300691881 /* PBXContainerItemProxy */;
-               };
                1558480607550D470046C2E9 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 159D549F07529FFF004F8947 /* configd */;
                1558480607550D470046C2E9 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 159D549F07529FFF004F8947 /* configd */;
                        target = 156CA4790EF853BB00C59A18 /* Logger.bundle-Embedded */;
                        targetProxy = 156CA4A70EF8550800C59A18 /* PBXContainerItemProxy */;
                };
                        target = 156CA4790EF853BB00C59A18 /* Logger.bundle-Embedded */;
                        targetProxy = 156CA4A70EF8550800C59A18 /* PBXContainerItemProxy */;
                };
+               15732AE616EA6BCE00F3AC4C /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 15732AD616EA6B6700F3AC4C /* libsystem_configuration-EmbeddedSimulator */;
+                       targetProxy = 15732AE516EA6BCE00F3AC4C /* PBXContainerItemProxy */;
+               };
                1574341F0D4A815E002ACA73 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 157433F00D4A8137002ACA73 /* scutil-Embedded */;
                1574341F0D4A815E002ACA73 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 157433F00D4A8137002ACA73 /* scutil-Embedded */;
                        target = 157BB8AE075924360025DA7A /* configd_base */;
                        targetProxy = 157BB8C30759244B0025DA7A /* PBXContainerItemProxy */;
                };
                        target = 157BB8AE075924360025DA7A /* configd_base */;
                        targetProxy = 157BB8C30759244B0025DA7A /* PBXContainerItemProxy */;
                };
+               157FDE44164A079B0040D6A8 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 157FDE3B164A075F0040D6A8 /* configd_libSystem-EmbeddedSimulator */;
+                       targetProxy = 157FDE43164A079B0040D6A8 /* PBXContainerItemProxy */;
+               };
                15828B070753B77E00AD4710 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15828AE60753B5F900AD4710 /* KernelEventMonitor.bundle */;
                15828B070753B77E00AD4710 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 15828AE60753B5F900AD4710 /* KernelEventMonitor.bundle */;
                        target = 15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */;
                        targetProxy = 15A5A2700D5B942D0087BDA0 /* PBXContainerItemProxy */;
                };
                        target = 15A5A1E40D5B94190087BDA0 /* SystemConfiguration.framework-EmbeddedSimulator */;
                        targetProxy = 15A5A2700D5B942D0087BDA0 /* PBXContainerItemProxy */;
                };
-               15AC515810839608004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583E9FD108395BB00A3BC0C /* configd_libSystem-EmbeddedOther */;
-                       targetProxy = 15AC515710839608004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC515B1083960E004A9ED5 /* PBXTargetDependency */ = {
+               15AB752216EC005A00FAA8CE /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EA11108395BB00A3BC0C /* configd_base-EmbeddedOther */;
-                       targetProxy = 15AC515A1083960E004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15AB751216EBFF3400FAA8CE /* SCNetworkReachability-EmbeddedSimulator */;
+                       targetProxy = 15AB752116EC005A00FAA8CE /* PBXContainerItemProxy */;
                };
                };
-               15AC515D10839613004A9ED5 /* PBXTargetDependency */ = {
+               15AB752416EC005A00FAA8CE /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EAAC108395BB00A3BC0C /* configd_plugins-EmbeddedOther */;
-                       targetProxy = 15AC515C10839613004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15AB751A16EBFF8A00FAA8CE /* SCNetworkReachability.bundle-EmbeddedSimulator */;
+                       targetProxy = 15AB752316EC005A00FAA8CE /* PBXContainerItemProxy */;
                };
                };
-               15AC515F1083961E004A9ED5 /* PBXTargetDependency */ = {
+               15AB752A16EC254D00FAA8CE /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB41108395BD00A3BC0C /* configd_executables-EmbeddedOther */;
-                       targetProxy = 15AC515E1083961E004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */;
+                       targetProxy = 15AB752916EC254D00FAA8CE /* PBXContainerItemProxy */;
                };
                };
-               15AC516110839649004A9ED5 /* PBXTargetDependency */ = {
+               15AB752C16EC254D00FAA8CE /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EA04108395BB00A3BC0C /* DNSConfiguration-EmbeddedOther */;
-                       targetProxy = 15AC516010839649004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15AB751216EBFF3400FAA8CE /* SCNetworkReachability-EmbeddedSimulator */;
+                       targetProxy = 15AB752B16EC254D00FAA8CE /* PBXContainerItemProxy */;
                };
                };
-               15AC516310839666004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EA19108395BB00A3BC0C /* SystemConfiguration.framework-EmbeddedOther */;
-                       targetProxy = 15AC516210839666004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC51651083966B004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EA9B108395BB00A3BC0C /* SCHelper-EmbeddedOther */;
-                       targetProxy = 15AC51641083966B004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC516A108396B7004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EB92108395BE00A3BC0C /* scutil-EmbeddedOther */;
-                       targetProxy = 15AC5169108396B7004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC516C108396B7004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EB86108395BE00A3BC0C /* scselect-EmbeddedOther */;
-                       targetProxy = 15AC516B108396B7004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC516E108396B7004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EB4B108395BD00A3BC0C /* configd-EmbeddedOther */;
-                       targetProxy = 15AC516D108396B7004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC5171108396D2004A9ED5 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 1583EB3A108395BD00A3BC0C /* PreferencesMonitor.bundle-EmbeddedOther */;
-                       targetProxy = 15AC5170108396D2004A9ED5 /* PBXContainerItemProxy */;
-               };
-               15AC5173108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15C64A220F684C4900D78394 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB32108395BD00A3BC0C /* PreferencesMonitor-EmbeddedOther */;
-                       targetProxy = 15AC5172108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15DAD5DF075913CE0084A6ED /* libsystem_configuration */;
+                       targetProxy = 15C64A210F684C4900D78394 /* PBXContainerItemProxy */;
                };
                };
-               15AC5179108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15C64A240F684C5700D78394 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB16108395BC00A3BC0C /* Logger.bundle-EmbeddedOther */;
-                       targetProxy = 15AC5178108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15C64A1E0F684C3300D78394 /* configd_libSystem */;
+                       targetProxy = 15C64A230F684C5700D78394 /* PBXContainerItemProxy */;
                };
                };
-               15AC517B108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15C64A2F0F684C8300D78394 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB0F108395BC00A3BC0C /* LinkConfiguration.bundle-EmbeddedOther */;
-                       targetProxy = 15AC517A108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15C64A280F684C6B00D78394 /* configd_libSystem-Embedded */;
+                       targetProxy = 15C64A2E0F684C8300D78394 /* PBXContainerItemProxy */;
                };
                };
-               15AC517D108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15C64A310F684C8F00D78394 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB07108395BC00A3BC0C /* LinkConfiguration-EmbeddedOther */;
-                       targetProxy = 15AC517C108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */;
+                       targetProxy = 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */;
                };
                };
-               15AC517F108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15D3083016F3EAD000014F82 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EB00108395BC00A3BC0C /* KernelEventMonitor.bundle-EmbeddedOther */;
-                       targetProxy = 15AC517E108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */;
+                       targetProxy = 15D3082F16F3EAD000014F82 /* PBXContainerItemProxy */;
                };
                };
-               15AC5181108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15D3083216F3EAD000014F82 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EAEF108395BC00A3BC0C /* KernelEventMonitor-EmbeddedOther */;
-                       targetProxy = 15AC5180108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */;
+                       targetProxy = 15D3083116F3EAD000014F82 /* PBXContainerItemProxy */;
                };
                };
-               15AC5183108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15D3083516F3EB2500014F82 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EAE8108395BC00A3BC0C /* InterfaceNamer.bundle-EmbeddedOther */;
-                       targetProxy = 15AC5182108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */;
+                       targetProxy = 15D3083416F3EB2500014F82 /* PBXContainerItemProxy */;
                };
                };
-               15AC5185108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EAE0108395BB00A3BC0C /* InterfaceNamer-EmbeddedOther */;
-                       targetProxy = 15AC5184108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */;
+                       targetProxy = 15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */;
                };
                };
-               15AC5187108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15E1B04016EBAB9400E5F06F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EAD9108395BB00A3BC0C /* IPMonitor.bundle-EmbeddedOther */;
-                       targetProxy = 15AC5186108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */;
+                       targetProxy = 15E1B03F16EBAB9400E5F06F /* PBXContainerItemProxy */;
                };
                };
-               15AC5189108396D2004A9ED5 /* PBXTargetDependency */ = {
+               15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 1583EACA108395BB00A3BC0C /* IPMonitor-EmbeddedOther */;
-                       targetProxy = 15AC5188108396D2004A9ED5 /* PBXContainerItemProxy */;
+                       target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */;
+                       targetProxy = 15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */;
                };
                };
-               15C64A220F684C4900D78394 /* PBXTargetDependency */ = {
+               15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 15DAD5DF075913CE0084A6ED /* DNSConfiguration */;
-                       targetProxy = 15C64A210F684C4900D78394 /* PBXContainerItemProxy */;
+                       target = 15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */;
+                       targetProxy = 15E1B06516EBAF2A00E5F06F /* PBXContainerItemProxy */;
                };
                };
-               15C64A240F684C5700D78394 /* PBXTargetDependency */ = {
+               15E83109167F9B0600FD51EC /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 15C64A1E0F684C3300D78394 /* configd_libSystem */;
-                       targetProxy = 15C64A230F684C5700D78394 /* PBXContainerItemProxy */;
+                       target = 15CB690005C0722A0099E85F /* All */;
+                       targetProxy = 15E83108167F9B0600FD51EC /* PBXContainerItemProxy */;
                };
                };
-               15C64A2F0F684C8300D78394 /* PBXTargetDependency */ = {
+               15E8310B167F9B0C00FD51EC /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 15C64A280F684C6B00D78394 /* configd_libSystem-Embedded */;
-                       targetProxy = 15C64A2E0F684C8300D78394 /* PBXContainerItemProxy */;
+                       target = 151C1CC60CFB487000C5AFD6 /* All-Embedded */;
+                       targetProxy = 15E8310A167F9B0C00FD51EC /* PBXContainerItemProxy */;
                };
                };
-               15C64A310F684C8F00D78394 /* PBXTargetDependency */ = {
+               15E8310D167F9B1200FD51EC /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        isa = PBXTargetDependency;
-                       target = 157A84D80D56C63900B6F1A0 /* DNSConfiguration-Embedded */;
-                       targetProxy = 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */;
+                       target = 15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */;
+                       targetProxy = 15E8310C167F9B1200FD51EC /* PBXContainerItemProxy */;
                };
                D6DDAC3D147A24BC00A2E902 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                };
                D6DDAC3D147A24BC00A2E902 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
 /* Begin XCBuildConfiguration section */
                151C1CC70CFB487000C5AFD6 /* Debug */ = {
                        isa = XCBuildConfiguration;
 /* Begin XCBuildConfiguration section */
                151C1CC70CFB487000C5AFD6 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd (Aggregate/Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd (Aggregate/Embedded)";
                        };
                };
                151C1CC80CFB487000C5AFD6 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                151C1CC80CFB487000C5AFD6 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd (Aggregate/Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd (Aggregate/Embedded)";
                        };
                151F5D9C0CCE98E60093AC3B /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                151F5D9C0CCE98E60093AC3B /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /System/Library/UserEventPlugins;
                                PRODUCT_NAME = SCMonitor;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /System/Library/UserEventPlugins;
                                PRODUCT_NAME = SCMonitor;
+                               PROVISIONING_PROFILE = "";
                                WRAPPER_EXTENSION = plugin;
                        };
                        name = Debug;
                                WRAPPER_EXTENSION = plugin;
                        };
                        name = Debug;
                151F5D9D0CCE98E60093AC3B /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                151F5D9D0CCE98E60093AC3B /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               CODE_SIGN_IDENTITY = "-";
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /System/Library/UserEventPlugins;
                                PRODUCT_NAME = SCMonitor;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /System/Library/UserEventPlugins;
                                PRODUCT_NAME = SCMonitor;
+                               PROVISIONING_PROFILE = "";
                                WRAPPER_EXTENSION = plugin;
                        };
                        name = Release;
                                WRAPPER_EXTENSION = plugin;
                        };
                        name = Release;
                };
                1528BFF513573FEE00691881 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                1528BFF513573FEE00691881 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = SCNetworkReachability;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = SCNetworkReachability;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                1528BFF613573FEE00691881 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                1528BFF613573FEE00691881 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = SCNetworkReachability;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = SCNetworkReachability;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                1528BFFC13573FF500691881 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                1528BFFC13573FF500691881 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = SCNetworkReachability;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = SCNetworkReachability;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                1528BFFD13573FF500691881 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                1528BFFD13573FF500691881 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = SCNetworkReachability;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = SCNetworkReachability;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1528C0041357401900691881 /* Debug */ = {
+               156CA4830EF853BB00C59A18 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = SCNetworkReachability;
-                               STRIP_INSTALLED_PRODUCT = NO;
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+                               PRODUCT_NAME = Logger;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1528C0051357401900691881 /* Release */ = {
+               156CA4840EF853BB00C59A18 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = SCNetworkReachability;
-                               STRIP_INSTALLED_PRODUCT = NO;
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
+                               PRODUCT_NAME = Logger;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1528C00B1357401D00691881 /* Debug */ = {
+               156EB5DB0905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = SCNetworkReachability;
-                       };
-                       name = Debug;
-               };
-               1528C00C1357401D00691881 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = SCNetworkReachability;
-                       };
-                       name = Release;
-               };
-               156CA4830EF853BB00C59A18 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = Logger;
-                       };
-                       name = Debug;
-               };
-               156CA4840EF853BB00C59A18 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = Logger;
-                       };
-                       name = Release;
-               };
-               156EB5DB0905594A00EEF749 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               BUILD_VARIANTS = (
-                                       normal,
-                                       debug,
-                                       profile,
-                               );
-                               GENERATE_PROFILING_CODE_profile = YES;
-                               INSTALLHDRS_COPY_PHASE = YES;
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       debug,
+                                       profile,
+                               );
+                               GENERATE_PROFILING_CODE_profile = YES;
+                               INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_configuration.dylib;
+                               LINK_WITH_STANDARD_LIBRARIES = NO;
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_LDFLAGS = (
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
+                                       "-Wl,-umbrella,System",
+                                       "-L/usr/lib/system",
+                                       "-lcompiler_rt",
+                                       "-ldispatch",
+                                       "-ldyld",
+                                       "-lsystem_asl",
+                                       "-lsystem_blocks",
+                                       "-lsystem_c",
+                                       "-lsystem_kernel",
+                                       "-lsystem_malloc",
+                                       "-lsystem_notify",
+                                       "-lsystem_platform",
+                                       "-lsystem_pthread",
+                                       "-lxpc",
                                );
                                );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
+                               PRODUCT_NAME = libsystem_configuration;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_configuration.dylib;
+                               LINK_WITH_STANDARD_LIBRARIES = NO;
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
+                                       "-Wl,-umbrella,System",
+                                       "-L/usr/lib/system",
+                                       "-lcompiler_rt",
+                                       "-ldispatch",
+                                       "-ldyld",
+                                       "-lsystem_asl",
+                                       "-lsystem_blocks",
+                                       "-lsystem_c",
+                                       "-lsystem_kernel",
+                                       "-lsystem_malloc",
+                                       "-lsystem_notify",
+                                       "-lsystem_platform",
+                                       "-lsystem_pthread",
+                                       "-lxpc",
                                );
                                );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
+                               PRODUCT_NAME = libsystem_configuration;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
                                );
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
                                );
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
                                INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
                                );
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
                                        "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
                                );
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
                                INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework/Versions/A/Resources";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework/Versions/A/Helpers";
                                PRODUCT_NAME = SCHelper;
                        };
                        name = Debug;
                                PRODUCT_NAME = SCHelper;
                        };
                        name = Debug;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework/Versions/A/Resources";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework/Versions/A/Helpers";
                                PRODUCT_NAME = SCHelper;
                        };
                        name = Release;
                                PRODUCT_NAME = SCHelper;
                        };
                        name = Release;
                156EB6230905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB6230905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                156EB6240905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB6240905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                156EB6270905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB6270905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                        };
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                        };
                156EB6280905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB6280905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                        };
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                        };
                156EB62B0905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB62B0905594A00EEF749 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                156EB62C0905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                156EB62C0905594A00EEF749 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                GCC_DYNAMIC_NO_PIC = NO;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                GCC_OPTIMIZATION_LEVEL = 0;
                                INSTALL_GROUP = wheel;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                GCC_OPTIMIZATION_LEVEL = 0;
                                INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = "u+s,ugo-w,o+rX";
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
                                OTHER_CFLAGS = (
                                        "-fconstant-cfstrings",
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
                                OTHER_CFLAGS = (
                                        "-fconstant-cfstrings",
-                                       "-fstack-protector",
+                                       "-fstack-protector-all",
                                        "-D_FORTIFY_SOURCE=2",
                                );
                                RUN_CLANG_STATIC_ANALYZER = YES;
                                        "-D_FORTIFY_SOURCE=2",
                                );
                                RUN_CLANG_STATIC_ANALYZER = YES;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                INSTALL_GROUP = wheel;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
                                INSTALL_GROUP = wheel;
-                               INSTALL_MODE_FLAG = "u+s,ugo-w,o+rX";
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
                                OTHER_CFLAGS = (
                                        "-fconstant-cfstrings",
                                INSTALL_OWNER = root;
                                INSTALL_PATH = /usr/sbin;
                                OTHER_CFLAGS = (
                                        "-fconstant-cfstrings",
-                                       "-fstack-protector",
+                                       "-fstack-protector-all",
                                        "-D_FORTIFY_SOURCE=2",
                                );
                                VERSIONING_SYSTEM = "apple-generic";
                                        "-D_FORTIFY_SOURCE=2",
                                );
                                VERSIONING_SYSTEM = "apple-generic";
                };
                1572C52A0CFB55B400E2776E /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                1572C52A0CFB55B400E2776E /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
                                PRODUCT_NAME = SystemConfiguration;
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
                                PRODUCT_NAME = SystemConfiguration;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Debug;
                };
                1572C52B0CFB55B400E2776E /* Release */ = {
                        isa = XCBuildConfiguration;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Debug;
                };
                1572C52B0CFB55B400E2776E /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
                                PRODUCT_NAME = SystemConfiguration;
                                INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
                                INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
                                LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
                                PRODUCT_NAME = SystemConfiguration;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Release;
                };
                                WRAPPER_EXTENSION = framework;
                        };
                        name = Release;
                };
+               15732AAA16EA503200F3AC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               APPLY_RULES_IN_COPY_FILES = YES;
+                               CODE_SIGN_IDENTITY = "-";
+                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/libexec;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
+                               );
+                               PRODUCT_NAME = configd_sim;
+                       };
+                       name = Debug;
+               };
+               15732AAB16EA503200F3AC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               APPLY_RULES_IN_COPY_FILES = YES;
+                               CODE_SIGN_IDENTITY = "-";
+                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/libexec;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
+                               );
+                               PRODUCT_NAME = configd_sim;
+                       };
+                       name = Release;
+               };
+               15732AD316EA511900F3AC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/bin;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
+                               );
+                               PRODUCT_NAME = scutil_sim;
+                       };
+                       name = Debug;
+               };
+               15732AD416EA511900F3AC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/bin;
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
+                               );
+                               PRODUCT_NAME = scutil_sim;
+                       };
+                       name = Release;
+               };
+               15732AE216EA6B6700F3AC4C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       debug,
+                                       profile,
+                               );
+                               FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+                               GENERATE_PROFILING_CODE_profile = YES;
+                               INSTALLHDRS_COPY_PHASE = YES;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/lib/system;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_sim_configuration.dylib;
+                               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$(INDIGO_INSTALL_PATH_PREFIX)/usr/lib/system",
+                                       "-lcompiler_rt_sim",
+                                       "-ldispatch",
+                                       "-ldyld_sim",
+                                       "-lsystem_sim_blocks",
+                                       "-lsystem_sim_c",
+                                       "-lxpc",
+                                       "-Wl,-upward-lSystem",
+                               );
+                               PRIVATE_HEADERS_FOLDER_PATH = "$(SDKROOT)/usr/local/include";
+                               PRODUCT_NAME = libsystem_sim_configuration;
+                               PUBLIC_HEADERS_FOLDER_PATH = "$(SDKROOT)/usr/local/include";
+                               STRIP_INSTALLED_PRODUCT_debug = NO;
+                               STRIP_INSTALLED_PRODUCT_normal = YES;
+                               STRIP_INSTALLED_PRODUCT_profile = NO;
+                       };
+                       name = Debug;
+               };
+               15732AE316EA6B6700F3AC4C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       debug,
+                                       profile,
+                               );
+                               FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+                               GENERATE_PROFILING_CODE_profile = YES;
+                               INSTALLHDRS_COPY_PHASE = YES;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/lib/system;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_sim_configuration.dylib;
+                               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$(INDIGO_INSTALL_PATH_PREFIX)/usr/lib/system",
+                                       "-lcompiler_rt_sim",
+                                       "-ldispatch",
+                                       "-ldyld_sim",
+                                       "-lsystem_sim_blocks",
+                                       "-lsystem_sim_c",
+                                       "-lxpc",
+                                       "-Wl,-upward-lSystem",
+                               );
+                               PRIVATE_HEADERS_FOLDER_PATH = "$(SDKROOT)/usr/local/include";
+                               PRODUCT_NAME = libsystem_sim_configuration;
+                               PUBLIC_HEADERS_FOLDER_PATH = "$(SDKROOT)/usr/local/include";
+                               STRIP_INSTALLED_PRODUCT_debug = NO;
+                               STRIP_INSTALLED_PRODUCT_normal = YES;
+                               STRIP_INSTALLED_PRODUCT_profile = NO;
+                       };
+                       name = Release;
+               };
                157433E90D4A8122002ACA73 /* Debug */ = {
                        isa = XCBuildConfiguration;
                157433E90D4A8122002ACA73 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157433EA0D4A8122002ACA73 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157433EA0D4A8122002ACA73 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
                                INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = scselect;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157434170D4A8137002ACA73 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157434170D4A8137002ACA73 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = (
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = scutil;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = scutil;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157434180D4A8137002ACA73 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157434180D4A8137002ACA73 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(SYMROOT)",
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = (
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = scutil;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = scutil;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A84E50D56C63900B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A84E50D56C63900B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                BUILD_VARIANTS = (
                                        normal,
                        buildSettings = {
                                BUILD_VARIANTS = (
                                        normal,
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_configuration.dylib;
+                               LINK_WITH_STANDARD_LIBRARIES = NO;
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
+                                       "-Wl,-umbrella,System",
+                                       "-L/usr/lib/system",
+                                       "-lcompiler_rt",
+                                       "-ldispatch",
+                                       "-ldyld",
+                                       "-lsystem_asl",
+                                       "-lsystem_blocks",
+                                       "-lsystem_c",
+                                       "-lsystem_kernel",
+                                       "-lsystem_malloc",
+                                       "-lsystem_notify",
+                                       "-lsystem_platform",
+                                       "-lsystem_pthread",
+                                       "-lxpc",
+                                       "-Wl,-upward-lSystem",
                                );
                                );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
+                               PRODUCT_NAME = libsystem_configuration;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A84E60D56C63900B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A84E60D56C63900B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                BUILD_VARIANTS = (
                                        normal,
                        buildSettings = {
                                BUILD_VARIANTS = (
                                        normal,
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
                                INSTALLHDRS_COPY_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
+                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libsystem_configuration.dylib;
+                               LINK_WITH_STANDARD_LIBRARIES = NO;
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
                                OTHER_CFLAGS_debug = "-O0";
                                OTHER_CFLAGS_normal = "";
                                OTHER_CFLAGS_profile = "";
                                OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
+                                       "-Wl,-umbrella,System",
+                                       "-L/usr/lib/system",
+                                       "-lcompiler_rt",
+                                       "-ldispatch",
+                                       "-ldyld",
+                                       "-lsystem_asl",
+                                       "-lsystem_blocks",
+                                       "-lsystem_c",
+                                       "-lsystem_kernel",
+                                       "-lsystem_malloc",
+                                       "-lsystem_notify",
+                                       "-lsystem_platform",
+                                       "-lsystem_pthread",
+                                       "-lxpc",
+                                       "-Wl,-upward-lSystem",
                                );
                                );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
+                               PRODUCT_NAME = libsystem_configuration;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
                                STRIP_INSTALLED_PRODUCT_debug = NO;
                                STRIP_INSTALLED_PRODUCT_normal = YES;
                                STRIP_INSTALLED_PRODUCT_profile = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A84FF0D56C7E800B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A84FF0D56C7E800B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = IPMonitor;
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = IPMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A85000D56C7E800B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A85000D56C7E800B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = IPMonitor;
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = IPMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A850A0D56C8AA00B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A850A0D56C8AA00B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = InterfaceNamer;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = InterfaceNamer;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A850B0D56C8AA00B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A850B0D56C8AA00B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = InterfaceNamer;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = InterfaceNamer;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A85200D56C8E000B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A85200D56C8E000B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = KernelEventMonitor;
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = KernelEventMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A85210D56C8E000B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A85210D56C8E000B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = KernelEventMonitor;
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = KernelEventMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A852B0D56C91100B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A852B0D56C91100B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = LinkConfiguration;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = LinkConfiguration;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A852C0D56C91100B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A852C0D56C91100B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = LinkConfiguration;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = LinkConfiguration;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                157A85410D56C96F00B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                157A85410D56C96F00B6F1A0 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = PreferencesMonitor;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = PreferencesMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                157A85420D56C96F00B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                157A85420D56C96F00B6F1A0 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = PreferencesMonitor;
                        buildSettings = {
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/local/lib/SystemConfiguration;
                                LIBRARY_STYLE = STATIC;
                                PRODUCT_NAME = PreferencesMonitor;
+                               SDKROOT = iphoneos.internal;
                                STRIP_INSTALLED_PRODUCT = NO;
                                STRIP_INSTALLED_PRODUCT = NO;
+                               SUPPORTED_PLATFORMS = iphoneos;
+                       };
+                       name = Release;
+               };
+               157FDE3F164A075F0040D6A8 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               INSTALLHDRS_COPY_PHASE = YES;
+                               PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
+                       };
+                       name = Debug;
+               };
+               157FDE40164A075F0040D6A8 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
+                       buildSettings = {
+                               INSTALLHDRS_COPY_PHASE = YES;
+                               PRODUCT_NAME = "configd_libSystem (EmbeddedSimulator)";
                        };
                        name = Release;
                };
                158316D90CFB774B006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                158316D90CFB774B006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (Embedded)";
                        };
                };
                158316DA0CFB774B006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                158316DA0CFB774B006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_base (Embedded)";
                        };
                };
                158317010CFB7761006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                158317010CFB7761006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_plugins (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_plugins (Embedded)";
                        };
                };
                158317020CFB7761006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                158317020CFB7761006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_plugins (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_plugins (Embedded)";
                        };
                };
                1583170C0CFB7782006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                1583170C0CFB7782006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (Embedded)";
                        };
                };
                1583170D0CFB7782006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                };
                1583170D0CFB7782006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (Embedded)";
                        };
                        buildSettings = {
                                PRODUCT_NAME = "configd_executables (Embedded)";
                        };
                };
                1583175E0CFB80A1006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                };
                1583175E0CFB80A1006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/libexec;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/libexec;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = configd;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = configd;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                1583175F0CFB80A1006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                1583175F0CFB80A1006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
+                               CODE_SIGN_IDENTITY = "-";
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/libexec;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = /usr/libexec;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = configd;
                                        "$(SDKROOT)/usr/local/lib/SystemConfiguration",
                                );
                                PRODUCT_NAME = configd;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                158317810CFB85C8006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                158317810CFB85C8006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = IPMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = IPMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                158317820CFB85C8006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                158317820CFB85C8006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = IPMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = IPMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                1583178A0CFB85DD006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                1583178A0CFB85DD006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = InterfaceNamer;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = InterfaceNamer;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                1583178B0CFB85DD006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                1583178B0CFB85DD006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = InterfaceNamer;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = InterfaceNamer;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                158317930CFB85F7006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                158317930CFB85F7006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = KernelEventMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = KernelEventMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                158317940CFB85F7006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                158317940CFB85F7006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = KernelEventMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = KernelEventMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                1583179B0CFB860C006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                1583179B0CFB860C006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = LinkConfiguration;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = LinkConfiguration;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                1583179C0CFB860C006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                1583179C0CFB860C006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = LinkConfiguration;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = LinkConfiguration;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                158317AB0CFB8639006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                158317AB0CFB8639006F62B9 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = PreferencesMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = PreferencesMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                158317AC0CFB8639006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                158317AC0CFB8639006F62B9 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = PreferencesMonitor;
                        buildSettings = {
                                INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
                                PRODUCT_NAME = PreferencesMonitor;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                158337A70CFB6B9E0033AB93 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Release;
                };
                158337A70CFB6B9E0033AB93 /* Debug */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Debug;
                };
                158337A80CFB6B9E0033AB93 /* Release */ = {
                        isa = XCBuildConfiguration;
                        };
                        name = Debug;
                };
                158337A80CFB6B9E0033AB93 /* Release */ = {
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
                        buildSettings = {
                                APPLY_RULES_IN_COPY_FILES = YES;
                                FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
                                PRODUCT_NAME = SCHelper;
+                               SDKROOT = iphoneos.internal;
+                               SUPPORTED_PLATFORMS = iphoneos;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583E9EA1083959E00A3BC0C /* Debug */ = {
+               15A5A2670D5B94190087BDA0 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               PRODUCT_NAME = "configd (Aggregate/EmbeddedOther)";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
+                               INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
+                               OTHER_CFLAGS = (
+                                       "-idirafter",
+                                       "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                               );
+                               PRODUCT_NAME = SystemConfiguration;
+                               WRAPPER_EXTENSION = framework;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583E9EB1083959E00A3BC0C /* Release */ = {
+               15A5A2680D5B94190087BDA0 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               PRODUCT_NAME = "configd (Aggregate/EmbeddedOther)";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                                       "$(SDKROOT)/usr/local/include/ppp",
+                               );
+                               INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
+                               OTHER_CFLAGS = (
+                                       "-idirafter",
+                                       "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
+                               );
+                               PRODUCT_NAME = SystemConfiguration;
+                               WRAPPER_EXTENSION = framework;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EA02108395BB00A3BC0C /* Debug */ = {
+               15AB751716EBFF3400FAA8CE /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = "configd_libSystem (EmbeddedOther)";
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = SCNetworkReachability_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EA03108395BB00A3BC0C /* Release */ = {
+               15AB751816EBFF3400FAA8CE /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = "configd_libSystem (EmbeddedOther)";
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = SCNetworkReachability_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EA0E108395BB00A3BC0C /* Debug */ = {
+               15AB751D16EBFF8A00FAA8CE /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               BUILD_VARIANTS = (
-                                       normal,
-                                       debug,
-                                       profile,
-                               );
-                               GENERATE_PROFILING_CODE_profile = YES;
-                               INSTALLHDRS_COPY_PHASE = YES;
+                               INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
-                               OTHER_CFLAGS_debug = "-O0";
-                               OTHER_CFLAGS_normal = "";
-                               OTHER_CFLAGS_profile = "";
-                               OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
-                               );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
-                               STRIP_INSTALLED_PRODUCT_debug = NO;
-                               STRIP_INSTALLED_PRODUCT_normal = YES;
-                               STRIP_INSTALLED_PRODUCT_profile = NO;
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = SCNetworkReachability;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EA0F108395BB00A3BC0C /* Release */ = {
+               15AB751E16EBFF8A00FAA8CE /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               BUILD_VARIANTS = (
-                                       normal,
-                                       debug,
-                                       profile,
-                               );
-                               GENERATE_PROFILING_CODE_profile = YES;
-                               INSTALLHDRS_COPY_PHASE = YES;
+                               INFOPLIST_FILE = Plugins/SCNetworkReachability/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/lib/system;
-                               LD_DYLIB_INSTALL_NAME = /usr/lib/system/libdnsinfo.dylib;
-                               MACH_O_TYPE = mh_dylib;
-                               OTHER_CFLAGS_debug = "-O0";
-                               OTHER_CFLAGS_normal = "";
-                               OTHER_CFLAGS_profile = "";
-                               OTHER_LDFLAGS = (
-                                       "-umbrella",
-                                       System,
-                               );
-                               OTHER_MIGFLAGS = "-DLIBDNSINFO";
-                               PRODUCT_NAME = libdnsinfo;
-                               STRIP_INSTALLED_PRODUCT_debug = NO;
-                               STRIP_INSTALLED_PRODUCT_normal = YES;
-                               STRIP_INSTALLED_PRODUCT_profile = NO;
-                       };
-                       name = Release;
-               };
-               1583EA17108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               PRODUCT_NAME = "configd_base (EmbeddedOther)";
-                       };
-                       name = Debug;
-               };
-               1583EA18108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               PRODUCT_NAME = "configd_base (EmbeddedOther)";
-                       };
-                       name = Release;
-               };
-               1583EA97108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = TARGET_OS_EMBEDDED_OTHER;
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
-                               INSTALLHDRS_SCRIPT_PHASE = YES;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
-                               PRODUCT_NAME = SystemConfiguration;
-                               WRAPPER_EXTENSION = framework;
-                       };
-                       name = Debug;
-               };
-               1583EA98108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               GCC_PREPROCESSOR_DEFINITIONS = TARGET_OS_EMBEDDED_OTHER;
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INFOPLIST_FILE = SystemConfiguration.fproj/Info.plist;
-                               INSTALLHDRS_SCRIPT_PHASE = YES;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
-                               PRODUCT_NAME = SystemConfiguration;
-                               WRAPPER_EXTENSION = framework;
-                       };
-                       name = Release;
-               };
-               1583EAA8108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               PRODUCT_NAME = SCHelper;
-                       };
-                       name = Debug;
-               };
-               1583EAA9108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/SystemConfiguration.framework";
-                               PRODUCT_NAME = SCHelper;
-                       };
-                       name = Release;
-               };
-               1583EAC8108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               PRODUCT_NAME = "configd_plugins (EmbeddedOther)";
-                       };
-                       name = Debug;
-               };
-               1583EAC9108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               PRODUCT_NAME = "configd_plugins (EmbeddedOther)";
-                       };
-                       name = Release;
-               };
-               1583EAD6108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = IPMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Debug;
-               };
-               1583EAD7108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = IPMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Release;
-               };
-               1583EADC108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = IPMonitor;
-                       };
-                       name = Debug;
-               };
-               1583EADD108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = IPMonitor;
-                       };
-                       name = Release;
-               };
-               1583EAE5108395BB00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = InterfaceNamer;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Debug;
-               };
-               1583EAE6108395BB00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = InterfaceNamer;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Release;
-               };
-               1583EAEB108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = InterfaceNamer;
-                       };
-                       name = Debug;
-               };
-               1583EAEC108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/InterfaceNamer/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = InterfaceNamer;
-                       };
-                       name = Release;
-               };
-               1583EAFD108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = KernelEventMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Debug;
-               };
-               1583EAFE108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = KernelEventMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Release;
-               };
-               1583EB03108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = KernelEventMonitor;
-                       };
-                       name = Debug;
-               };
-               1583EB04108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/KernelEventMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = KernelEventMonitor;
-                       };
-                       name = Release;
-               };
-               1583EB0C108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = LinkConfiguration;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Debug;
-               };
-               1583EB0D108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = LinkConfiguration;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Release;
-               };
-               1583EB12108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = LinkConfiguration;
-                       };
-                       name = Debug;
-               };
-               1583EB13108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/LinkConfiguration/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = LinkConfiguration;
-                       };
-                       name = Release;
-               };
-               1583EB1F108395BC00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = Logger;
-                       };
-                       name = Debug;
-               };
-               1583EB20108395BC00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist";
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = Logger;
-                       };
-                       name = Release;
-               };
-               1583EB37108395BD00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = PreferencesMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Debug;
-               };
-               1583EB38108395BD00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               DEBUG_INFORMATION_FORMAT = dwarf;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/local/lib/SystemConfiguration;
-                               LIBRARY_STYLE = STATIC;
-                               PRODUCT_NAME = PreferencesMonitor;
-                               STRIP_INSTALLED_PRODUCT = NO;
-                       };
-                       name = Release;
-               };
-               1583EB3D108395BD00A3BC0C /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = PreferencesMonitor;
-                       };
-                       name = Debug;
-               };
-               1583EB3E108395BD00A3BC0C /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
-                       buildSettings = {
-                               INFOPLIST_FILE = Plugins/PreferencesMonitor/Info.plist;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/SystemConfiguration";
-                               PRODUCT_NAME = PreferencesMonitor;
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = SCNetworkReachability;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EB49108395BD00A3BC0C /* Debug */ = {
+               15C64A1F0F684C3300D78394 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               PRODUCT_NAME = "configd_executables (EmbeddedOther)";
+                               INSTALL_PATH = /usr/local/lib/system;
+                               PRODUCT_NAME = configd_libSystem;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EB4A108395BD00A3BC0C /* Release */ = {
+               15C64A200F684C3300D78394 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               PRODUCT_NAME = "configd_executables (EmbeddedOther)";
+                               INSTALL_PATH = /usr/local/lib/system;
+                               PRODUCT_NAME = configd_libSystem;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EB82108395BD00A3BC0C /* Debug */ = {
+               15C64A2C0F684C6B00D78394 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
-                               CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               GCC_PREPROCESSOR_DEFINITIONS = TARGET_OS_EMBEDDED_OTHER;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/libexec;
-                               LIBRARY_SEARCH_PATHS = (
-                                       "$(SYMROOT)",
-                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
-                               );
-                               PRODUCT_NAME = configd;
+                               INSTALL_PATH = /usr/local/lib/system;
+                               PRODUCT_NAME = "configd_libSystem (Embedded)";
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EB83108395BD00A3BC0C /* Release */ = {
+               15C64A2D0F684C6B00D78394 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               APPLY_RULES_IN_COPY_FILES = YES;
-                               CODE_SIGN_ENTITLEMENTS = configd.tproj/entitlements.plist;
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               GCC_PREPROCESSOR_DEFINITIONS = TARGET_OS_EMBEDDED_OTHER;
-                               INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/libexec;
-                               LIBRARY_SEARCH_PATHS = (
-                                       "$(SYMROOT)",
-                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
-                               );
-                               PRODUCT_NAME = configd;
+                               INSTALL_PATH = /usr/local/lib/system;
+                               PRODUCT_NAME = "configd_libSystem (Embedded)";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EB8E108395BE00A3BC0C /* Debug */ = {
+               15D3082516F3E4DA00014F82 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
-                               INSTALL_PATH = /usr/sbin;
-                               PRODUCT_NAME = scselect;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = SimulatorSupport_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EB8F108395BE00A3BC0C /* Release */ = {
+               15D3082616F3E4DA00014F82 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
-                               INSTALL_MODE_FLAG = "a-w,a+rX,u+s";
-                               INSTALL_PATH = /usr/sbin;
-                               PRODUCT_NAME = scselect;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = SimulatorSupport_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               1583EBB4108395BE00A3BC0C /* Debug */ = {
+               15D3082B16F3E4E100014F82 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/sbin;
-                               LIBRARY_SEARCH_PATHS = (
-                                       "$(SYMROOT)",
-                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
-                               );
-                               PRODUCT_NAME = scutil;
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = SimulatorSupport;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               1583EBB5108395BE00A3BC0C /* Release */ = {
+               15D3082C16F3E4E100014F82 /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+                               INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH = /usr/sbin;
-                               LIBRARY_SEARCH_PATHS = (
-                                       "$(SYMROOT)",
-                                       "$(SDKROOT)/usr/local/lib/SystemConfiguration",
-                               );
-                               PRODUCT_NAME = scutil;
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = SimulatorSupport;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               15A5A2670D5B94190087BDA0 /* Debug */ = {
+               15E1B05716EBAE3C00E5F06F /* Debug */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
-                               INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH_ACTUAL = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
-                               OTHER_CFLAGS = (
-                                       "-idirafter",
-                                       "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
-                               );
-                               PRODUCT_NAME = SystemConfiguration;
-                               WRAPPER_EXTENSION = framework;
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = IPMonitor_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               15A5A2680D5B94190087BDA0 /* Release */ = {
+               15E1B05816EBAE3C00E5F06F /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
                                HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
-                               INFOPLIST_FILE = "SystemConfiguration.fproj/Info-Embedded.plist";
-                               INSTALLHDRS_SCRIPT_PHASE = YES;
                                INSTALL_MODE_FLAG = "a-w,a+rX";
                                INSTALL_MODE_FLAG = "a-w,a+rX";
-                               INSTALL_PATH_ACTUAL = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
-                               LIBRARY_SEARCH_PATHS = "$(SYMROOT)";
-                               OTHER_CFLAGS = (
-                                       "-idirafter",
-                                       "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders",
-                               );
-                               PRODUCT_NAME = SystemConfiguration;
-                               WRAPPER_EXTENSION = framework;
+                               INSTALL_PATH_ACTUAL = /usr/local/lib/SystemConfiguration;
+                               LIBRARY_STYLE = STATIC;
+                               PRODUCT_NAME = IPMonitor_sim;
+                               STRIP_INSTALLED_PRODUCT = NO;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               15C64A1F0F684C3300D78394 /* Debug */ = {
+               15E1B05F16EBAE7800E5F06F /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = configd_libSystem;
+                               INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = IPMonitor;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               15C64A200F684C3300D78394 /* Release */ = {
+               15E1B06016EBAE7800E5F06F /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
+                       baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = configd_libSystem;
+                               INFOPLIST_FILE = Plugins/IPMonitor/Info.plist;
+                               INSTALL_MODE_FLAG = "a-w,a+rX";
+                               INSTALL_PATH_ACTUAL = /System/Library/SystemConfiguration;
+                               PRODUCT_NAME = IPMonitor;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
-               15C64A2C0F684C6B00D78394 /* Debug */ = {
+               15E83105167F9AF600FD51EC /* Debug */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = "configd_libSystem (Embedded)";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
-               15C64A2D0F684C6B00D78394 /* Release */ = {
+               15E83106167F9AF600FD51EC /* Release */ = {
                        isa = XCBuildConfiguration;
                        isa = XCBuildConfiguration;
-                       baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */;
                        buildSettings = {
                        buildSettings = {
-                               INSTALL_PATH = /usr/local/lib/system;
-                               PRODUCT_NAME = "configd_libSystem (Embedded)";
+                               PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1528C0031357401900691881 /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1528C0041357401900691881 /* Debug */,
-                               1528C0051357401900691881 /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1528C00A1357401D00691881 /* Build configuration list for PBXNativeTarget "SCNetworkReachability.bundle-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1528C00B1357401D00691881 /* Debug */,
-                               1528C00C1357401D00691881 /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
                156CA4820EF853BB00C59A18 /* Build configuration list for PBXNativeTarget "Logger.bundle-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                156CA4820EF853BB00C59A18 /* Build configuration list for PBXNativeTarget "Logger.bundle-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "DNSConfiguration" */ = {
+               156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "libsystem_configuration" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                                156EB5DB0905594A00EEF749 /* Debug */,
                        isa = XCConfigurationList;
                        buildConfigurations = (
                                156EB5DB0905594A00EEF749 /* Debug */,
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               15732AA916EA503200F3AC4C /* Build configuration list for PBXNativeTarget "configd-EmbeddedSimulator" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               15732AAA16EA503200F3AC4C /* Debug */,
+                               15732AAB16EA503200F3AC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               15732AD216EA511900F3AC4C /* Build configuration list for PBXNativeTarget "scutil-EmbeddedSimulator" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               15732AD316EA511900F3AC4C /* Debug */,
+                               15732AD416EA511900F3AC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               15732AE116EA6B6700F3AC4C /* Build configuration list for PBXNativeTarget "libsystem_configuration-EmbeddedSimulator" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               15732AE216EA6B6700F3AC4C /* Debug */,
+                               15732AE316EA6B6700F3AC4C /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                157433E80D4A8122002ACA73 /* Build configuration list for PBXNativeTarget "scselect-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                157433E80D4A8122002ACA73 /* Build configuration list for PBXNativeTarget "scselect-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               157A84E40D56C63900B6F1A0 /* Build configuration list for PBXNativeTarget "DNSConfiguration-Embedded" */ = {
+               157A84E40D56C63900B6F1A0 /* Build configuration list for PBXNativeTarget "libsystem_configuration-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                                157A84E50D56C63900B6F1A0 /* Debug */,
                        isa = XCConfigurationList;
                        buildConfigurations = (
                                157A84E50D56C63900B6F1A0 /* Debug */,
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               157FDE3E164A075F0040D6A8 /* Build configuration list for PBXAggregateTarget "configd_libSystem-EmbeddedSimulator" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               157FDE3F164A075F0040D6A8 /* Debug */,
+                               157FDE40164A075F0040D6A8 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                158316D80CFB774B006F62B9 /* Build configuration list for PBXAggregateTarget "configd_base-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                158316D80CFB774B006F62B9 /* Build configuration list for PBXAggregateTarget "configd_base-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583E9E91083959E00A3BC0C /* Build configuration list for PBXAggregateTarget "All-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583E9EA1083959E00A3BC0C /* Debug */,
-                               1583E9EB1083959E00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EA01108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_libSystem-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EA02108395BB00A3BC0C /* Debug */,
-                               1583EA03108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EA0D108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "DNSConfiguration-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EA0E108395BB00A3BC0C /* Debug */,
-                               1583EA0F108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EA16108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_base-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EA17108395BB00A3BC0C /* Debug */,
-                               1583EA18108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EA96108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EA97108395BB00A3BC0C /* Debug */,
-                               1583EA98108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAA7108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SCHelper-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAA8108395BB00A3BC0C /* Debug */,
-                               1583EAA9108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAC7108395BB00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_plugins-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAC8108395BB00A3BC0C /* Debug */,
-                               1583EAC9108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAD5108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAD6108395BB00A3BC0C /* Debug */,
-                               1583EAD7108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EADB108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EADC108395BB00A3BC0C /* Debug */,
-                               1583EADD108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAE4108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAE5108395BB00A3BC0C /* Debug */,
-                               1583EAE6108395BB00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAEA108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer.bundle-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAEB108395BC00A3BC0C /* Debug */,
-                               1583EAEC108395BC00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EAFC108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EAFD108395BC00A3BC0C /* Debug */,
-                               1583EAFE108395BC00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EB02108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor.bundle-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EB03108395BC00A3BC0C /* Debug */,
-                               1583EB04108395BC00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EB0B108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "LinkConfiguration-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EB0C108395BC00A3BC0C /* Debug */,
-                               1583EB0D108395BC00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EB11108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "LinkConfiguration.bundle-EmbeddedOther" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1583EB12108395BC00A3BC0C /* Debug */,
-                               1583EB13108395BC00A3BC0C /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1583EB1E108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "Logger.bundle-EmbeddedOther" */ = {
+               15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB1F108395BC00A3BC0C /* Debug */,
-                               1583EB20108395BC00A3BC0C /* Release */,
+                               15A5A2670D5B94190087BDA0 /* Debug */,
+                               15A5A2680D5B94190087BDA0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EB36108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "PreferencesMonitor-EmbeddedOther" */ = {
+               15AB751616EBFF3400FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB37108395BD00A3BC0C /* Debug */,
-                               1583EB38108395BD00A3BC0C /* Release */,
+                               15AB751716EBFF3400FAA8CE /* Debug */,
+                               15AB751816EBFF3400FAA8CE /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EB3C108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "PreferencesMonitor.bundle-EmbeddedOther" */ = {
+               15AB751C16EBFF8A00FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability.bundle-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB3D108395BD00A3BC0C /* Debug */,
-                               1583EB3E108395BD00A3BC0C /* Release */,
+                               15AB751D16EBFF8A00FAA8CE /* Debug */,
+                               15AB751E16EBFF8A00FAA8CE /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EB48108395BD00A3BC0C /* Build configuration list for PBXAggregateTarget "configd_executables-EmbeddedOther" */ = {
+               15C64A270F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB49108395BD00A3BC0C /* Debug */,
-                               1583EB4A108395BD00A3BC0C /* Release */,
+                               15C64A1F0F684C3300D78394 /* Debug */,
+                               15C64A200F684C3300D78394 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EB81108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "configd-EmbeddedOther" */ = {
+               15C64A2B0F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem-Embedded" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB82108395BD00A3BC0C /* Debug */,
-                               1583EB83108395BD00A3BC0C /* Release */,
+                               15C64A2C0F684C6B00D78394 /* Debug */,
+                               15C64A2D0F684C6B00D78394 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EB8D108395BE00A3BC0C /* Build configuration list for PBXNativeTarget "scselect-EmbeddedOther" */ = {
+               15D3082416F3E4DA00014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EB8E108395BE00A3BC0C /* Debug */,
-                               1583EB8F108395BE00A3BC0C /* Release */,
+                               15D3082516F3E4DA00014F82 /* Debug */,
+                               15D3082616F3E4DA00014F82 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1583EBB3108395BE00A3BC0C /* Build configuration list for PBXNativeTarget "scutil-EmbeddedOther" */ = {
+               15D3082A16F3E4E100014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport.bundle-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               1583EBB4108395BE00A3BC0C /* Debug */,
-                               1583EBB5108395BE00A3BC0C /* Release */,
+                               15D3082B16F3E4E100014F82 /* Debug */,
+                               15D3082C16F3E4E100014F82 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */ = {
+               15E1B05616EBAE3C00E5F06F /* Build configuration list for PBXNativeTarget "IPMonitor-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               15A5A2670D5B94190087BDA0 /* Debug */,
-                               15A5A2680D5B94190087BDA0 /* Release */,
+                               15E1B05716EBAE3C00E5F06F /* Debug */,
+                               15E1B05816EBAE3C00E5F06F /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               15C64A270F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem" */ = {
+               15E1B05E16EBAE7800E5F06F /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedSimulator" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               15C64A1F0F684C3300D78394 /* Debug */,
-                               15C64A200F684C3300D78394 /* Release */,
+                               15E1B05F16EBAE7800E5F06F /* Debug */,
+                               15E1B06016EBAE7800E5F06F /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               15C64A2B0F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem-Embedded" */ = {
+               15E83107167F9AF600FD51EC /* Build configuration list for PBXAggregateTarget "EVERYTHING" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        isa = XCConfigurationList;
                        buildConfigurations = (
-                               15C64A2C0F684C6B00D78394 /* Debug */,
-                               15C64A2D0F684C6B00D78394 /* Release */,
+                               15E83105167F9AF600FD51EC /* Debug */,
+                               15E83106167F9AF600FD51EC /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                        );
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
index 020e51afc7516ee92c8eff4ec36b46fa48298447..60be01a7582ce886e8c5002bd3c669a6d825d885 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2006, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006, 2008, 2009, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,7 +35,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
 #include <sys/socket.h>
 #include <netinet/in.h>
 
-#define        DNSINFO_VERSION         20111104
+#define        DNSINFO_VERSION         20130402
 
 #define DEFAULT_SEARCH_ORDER    200000   /* search order for the "default" resolver domain name */
 
 
 #define DEFAULT_SEARCH_ORDER    200000   /* search order for the "default" resolver domain name */
 
@@ -73,13 +73,19 @@ typedef struct {
        DNS_VAR(uint32_t,               if_index);
        DNS_VAR(uint32_t,               flags);
        DNS_VAR(uint32_t,               reach_flags);   /* SCNetworkReachabilityFlags */
        DNS_VAR(uint32_t,               if_index);
        DNS_VAR(uint32_t,               flags);
        DNS_VAR(uint32_t,               reach_flags);   /* SCNetworkReachabilityFlags */
-       DNS_VAR(uint32_t,               reserved[5]);
+       DNS_VAR(uint32_t,               service_identifier);
+       DNS_VAR(uint32_t,               reserved[4]);
 } dns_resolver_t;
 #pragma pack()
 
 
 } dns_resolver_t;
 #pragma pack()
 
 
-#define DNS_RESOLVER_FLAGS_SCOPED      1               /* configuration is for scoped questions */
+#define DNS_RESOLVER_FLAGS_SCOPED              1               /* configuration is for scoped questions */
+#define DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS   2               /* always requesting for A dns records in queries */
+#define DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS        4               /* always requesting for AAAA dns records in queries */
+#define DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC    8               /* configuration is service-specific */
 
 
+#define        DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS  \
+       (DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS | DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS)
 
 #pragma pack(4)
 typedef struct {
 
 #pragma pack(4)
 typedef struct {
@@ -87,7 +93,9 @@ typedef struct {
        DNS_PTR(dns_resolver_t **,      resolver);
        DNS_VAR(int32_t,                n_scoped_resolver);     /* "scoped" resolver configurations */
        DNS_PTR(dns_resolver_t **,      scoped_resolver);
        DNS_PTR(dns_resolver_t **,      resolver);
        DNS_VAR(int32_t,                n_scoped_resolver);     /* "scoped" resolver configurations */
        DNS_PTR(dns_resolver_t **,      scoped_resolver);
-       DNS_VAR(uint32_t,               reserved[5]);
+       DNS_VAR(uint64_t,               generation);
+       DNS_VAR(int32_t,                n_service_specific_resolver);
+       DNS_PTR(dns_resolver_t **,      service_specific_resolver);
 } dns_config_t;
 #pragma pack()
 
 } dns_config_t;
 #pragma pack()
 
index 26b1e9de3f17a3eed069fc0532f12c796c4d18e9..ee0a17a7501a3c2672ac9928a747758547c8f2fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004, 2006, 2008-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2006, 2008-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <pthread.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <pthread.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
 
 
+#include "libSystemConfiguration_client.h"
 #include "dnsinfo.h"
 #include "dnsinfo_private.h"
 #include "dnsinfo.h"
 #include "dnsinfo_private.h"
-#include "shared_dns_info.h"
-#include "network_information_priv.h"
-
-
-static pthread_once_t  _dns_initialized        = PTHREAD_ONCE_INIT;
-static pthread_mutex_t _dns_lock               = PTHREAD_MUTEX_INITIALIZER;
-static mach_port_t     _dns_server             = MACH_PORT_NULL;
-
-enum {
-       get_dns_info    = 1,
-       get_nwi_state   = 2,
-};
 
 typedef uint32_t getflags;
 
 
 typedef uint32_t getflags;
 
-static void
-__dns_fork_handler()
-{
-       // the process has forked (and we are the child process)
-       _dns_server = MACH_PORT_NULL;
-       return;
-}
-
-
-static void
-__dns_initialize(void)
-{
-       // add handler to cleanup after fork()
-       (void) pthread_atfork(NULL, NULL, __dns_fork_handler);
-
-       return;
-}
-
-
 static boolean_t
 add_list(void **padding, uint32_t *n_padding, int32_t count, int32_t size, void **list)
 {
 static boolean_t
 add_list(void **padding, uint32_t *n_padding, int32_t count, int32_t size, void **list)
 {
@@ -90,138 +62,6 @@ add_list(void **padding, uint32_t *n_padding, int32_t count, int32_t size, void
 #define        DNS_CONFIG_BUF_MAX      1024*1024
 
 
 #define        DNS_CONFIG_BUF_MAX      1024*1024
 
 
-static kern_return_t
-_dns_server_copy(void* dataRef, mach_msg_type_number_t* dataLen, getflags flags){
-       mach_port_t     server;
-       kern_return_t   status  = KERN_FAILURE;
-
-       // initialize runtime
-       pthread_once(&_dns_initialized, __dns_initialize);
-
-       // open a new session with the DNS configuration server
-       server = _dns_server;
-       while (TRUE) {
-               if (server != MACH_PORT_NULL) {
-                       if (flags == get_dns_info) {
-                               status = shared_dns_infoGet(server, dataRef, dataLen);
-                       } else {
-                               status = shared_nwi_stateGet(server, dataRef, dataLen);
-                       }
-                       if (status == KERN_SUCCESS) {
-                               break;
-                       }
-
-                       // our [cached] server port is not valid
-                       if ((status != MACH_SEND_INVALID_DEST) && (status != MIG_SERVER_DIED)) {
-                               // if we got an unexpected error, don't retry
-                               fprintf(stderr,
-                                       "dns_configuration_copy shared_dns_infoGet(): %s\n",
-                                       mach_error_string(status));
-                               break;
-                       }
-               }
-
-               pthread_mutex_lock(&_dns_lock);
-               if (_dns_server != MACH_PORT_NULL) {
-                       if (server == _dns_server) {
-                               // if the server we tried returned the error
-                               (void)mach_port_deallocate(mach_task_self(), server);
-                               _dns_server = _dns_configuration_server_port();
-                       } else {
-                               // another thread has refreshed the DNS server port
-                       }
-               } else {
-                       _dns_server = _dns_configuration_server_port();
-               }
-               server = _dns_server;
-               pthread_mutex_unlock(&_dns_lock);
-
-               if (server == MACH_PORT_NULL) {
-                       // if server not available
-                       break;
-               }
-       }
-
-       return status;
-}
-
-
-__private_extern__
-nwi_state*
-_nwi_state_copy() {
-       dnsDataOut_t            dataRef         = NULL;
-       mach_msg_type_number_t  dataLen         = 0;
-       kern_return_t           status;
-       nwi_state*              state           = NULL;
-
-       status = _dns_server_copy(&dataRef, &dataLen, get_nwi_state);
-       if (status != KERN_SUCCESS) {
-               return NULL;
-       }
-
-       if (dataRef != NULL) {
-               state = malloc(dataLen);
-               if (state == NULL) {
-                       vm_deallocate(mach_task_self(), (vm_address_t)dataRef,
-                                     dataLen);
-                       return NULL;
-               }
-               memcpy((void*) state, (void*) dataRef, dataLen);
-               state->ref = 0;
-               status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
-               if (status != KERN_SUCCESS) {
-                       mach_error("vm_deallocate():", status);
-                       free(state);
-                       return NULL;
-               }
-       }
-
-       return state;
-}
-
-
-static _dns_config_buf_t *
-copy_dns_info()
-{
-       uint8_t                 *buf    = NULL;
-       dnsDataOut_t            dataRef = NULL;
-       mach_msg_type_number_t  dataLen = 0;
-       kern_return_t           status;
-
-       status = _dns_server_copy(&dataRef, &dataLen, get_dns_info);
-       if (status != KERN_SUCCESS) {
-               return NULL;
-       }
-
-       if (dataRef != NULL) {
-               if ((dataLen >= sizeof(_dns_config_buf_t)) && (dataLen <= DNS_CONFIG_BUF_MAX)) {
-                       /* ALIGN: cast okay since _dns_config_buf_t is int aligned */
-                       _dns_config_buf_t       *config         = (_dns_config_buf_t *)(void *)dataRef;
-                       uint32_t                n_padding       = ntohl(config->n_padding);
-
-                       if (n_padding <= (DNS_CONFIG_BUF_MAX - dataLen)) {
-                               uint32_t        len;
-
-                               len = dataLen + n_padding;
-                               buf = malloc(len);
-                               bcopy((void *)dataRef, buf, dataLen);
-                               bzero(&buf[dataLen], n_padding);
-                       }
-               }
-
-               status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
-               if (status != KERN_SUCCESS) {
-                       mach_error("vm_deallocate():", status);
-                       free(buf);
-                       return NULL;
-               }
-       }
-
-       /* ALIGN: buf malloc'ed, should be aligned >8 bytes */
-       return (_dns_config_buf_t *)(void *)buf;
-}
-
-
 static dns_resolver_t *
 expand_resolver(_dns_resolver_buf_t *buf, uint32_t n_buf, void **padding, uint32_t *n_padding)
 {
 static dns_resolver_t *
 expand_resolver(_dns_resolver_buf_t *buf, uint32_t n_buf, void **padding, uint32_t *n_padding)
 {
@@ -293,6 +133,10 @@ expand_resolver(_dns_resolver_buf_t *buf, uint32_t n_buf, void **padding, uint32
 
        resolver->if_index = ntohl(resolver->if_index);
 
 
        resolver->if_index = ntohl(resolver->if_index);
 
+       // initialize service_identifier
+
+       resolver->service_identifier = ntohl(resolver->service_identifier);
+
        // initialize flags
 
        resolver->flags = ntohl(resolver->flags);
        // initialize flags
 
        resolver->flags = ntohl(resolver->flags);
@@ -311,7 +155,7 @@ expand_resolver(_dns_resolver_buf_t *buf, uint32_t n_buf, void **padding, uint32
        }
 
        while (n_attribute >= sizeof(dns_attribute_t)) {
        }
 
        while (n_attribute >= sizeof(dns_attribute_t)) {
-               int32_t attribute_length        = ntohl(attribute->length);
+               uint32_t        attribute_length        = ntohl(attribute->length);
 
                switch (ntohl(attribute->type)) {
                        case RESOLVER_ATTRIBUTE_DOMAIN :
 
                switch (ntohl(attribute->type)) {
                        case RESOLVER_ATTRIBUTE_DOMAIN :
@@ -365,6 +209,7 @@ expand_config(_dns_config_buf_t *buf)
        uint32_t                n_padding;
        int32_t                 n_resolver              = 0;
        int32_t                 n_scoped_resolver       = 0;
        uint32_t                n_padding;
        int32_t                 n_resolver              = 0;
        int32_t                 n_scoped_resolver       = 0;
+       int32_t                 n_service_specific_resolver     = 0;
        void                    *padding;
 
        // establish padding
        void                    *padding;
 
        // establish padding
@@ -392,6 +237,15 @@ expand_config(_dns_config_buf_t *buf)
                goto error;
        }
 
                goto error;
        }
 
+       config->n_service_specific_resolver = ntohl(config->n_service_specific_resolver);
+       if (!add_list(&padding,
+                     &n_padding,
+                     config->n_service_specific_resolver,
+                     sizeof(DNS_PTR(dns_resolver_t *, x)),
+                     (void **)&config->service_specific_resolver)) {
+               goto error;
+       }
+
        // process configuration buffer "attribute" data
 
        n_attribute = ntohl(buf->n_attribute);
        // process configuration buffer "attribute" data
 
        n_attribute = ntohl(buf->n_attribute);
@@ -403,7 +257,8 @@ expand_config(_dns_config_buf_t *buf)
 
                switch (attribute_type) {
                        case CONFIG_ATTRIBUTE_RESOLVER :
 
                switch (attribute_type) {
                        case CONFIG_ATTRIBUTE_RESOLVER :
-                       case CONFIG_ATTRIBUTE_SCOPED_RESOLVER   : {
+                       case CONFIG_ATTRIBUTE_SCOPED_RESOLVER   :
+                       case CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER : {
                                dns_resolver_t  *resolver;
 
                                // expand resolver buffer
                                dns_resolver_t  *resolver;
 
                                // expand resolver buffer
@@ -420,8 +275,10 @@ expand_config(_dns_config_buf_t *buf)
 
                                if (attribute_type == CONFIG_ATTRIBUTE_RESOLVER) {
                                        config->resolver[n_resolver++] = resolver;
 
                                if (attribute_type == CONFIG_ATTRIBUTE_RESOLVER) {
                                        config->resolver[n_resolver++] = resolver;
-                               } else {
+                               } else if (attribute_type == CONFIG_ATTRIBUTE_SCOPED_RESOLVER) {
                                        config->scoped_resolver[n_scoped_resolver++] = resolver;
                                        config->scoped_resolver[n_scoped_resolver++] = resolver;
+                               } else if (attribute_type == CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER) {
+                                       config->service_specific_resolver[n_service_specific_resolver++] = resolver;
                                }
 
                                break;
                                }
 
                                break;
@@ -443,6 +300,10 @@ expand_config(_dns_config_buf_t *buf)
                goto error;
        }
 
                goto error;
        }
 
+       if (n_service_specific_resolver != config->n_service_specific_resolver) {
+               goto error;
+       }
+
        return config;
 
     error :
        return config;
 
     error :
@@ -456,29 +317,124 @@ dns_configuration_notify_key()
 {
        const char      *key;
 
 {
        const char      *key;
 
-       // initialize runtime
-       pthread_once(&_dns_initialized, __dns_initialize);
-
-       key = _dns_configuration_notify_key();
+#if    !TARGET_IPHONE_SIMULATOR
+       key = "com.apple.system.SystemConfiguration.dns_configuration";
+#else  // !TARGET_IPHONE_SIMULATOR
+       key = "com.apple.iOS_Simulator.SystemConfiguration.dns_configuration";
+#endif // !TARGET_IPHONE_SIMULATOR
        return key;
 }
 
 
        return key;
 }
 
 
+#pragma mark -
+#pragma mark DNS configuration [dnsinfo] client support
+
+
+// Note: protected by __dns_configuration_queue()
+static int                     dnsinfo_active  = 0;
+static libSC_info_client_t     *dnsinfo_client = NULL;
+
+
+static dispatch_queue_t
+__dns_configuration_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(DNSINFO_SERVICE_NAME, NULL);
+       });
+
+       return q;
+}
+
+
 dns_config_t *
 dns_configuration_copy()
 {
 dns_config_t *
 dns_configuration_copy()
 {
-       _dns_config_buf_t       *buf;
-       dns_config_t            *config;
+       uint8_t                 *buf            = NULL;
+       dns_config_t            *config         = NULL;
+       static const char       *proc_name      = NULL;
+       xpc_object_t            reqdict;
+       xpc_object_t            reply;
+
+       dispatch_sync(__dns_configuration_queue(), ^{
+               if ((dnsinfo_active++ == 0) || (dnsinfo_client == NULL)) {
+                       static dispatch_once_t  once;
+                       static const char       *service_name   = DNSINFO_SERVICE_NAME;
+
+                       dispatch_once(&once, ^{
+                               const char      *name;
+
+                               // get [XPC] service name
+                               name = getenv(service_name);
+                               if ((name != NULL) && (issetugid() == 0)) {
+                                       service_name = strdup(name);
+                               }
+
+                               // get process name
+                               proc_name = getprogname();
+                       });
 
 
-       buf = copy_dns_info();
-       if (buf == NULL) {
+                       dnsinfo_client =
+                               libSC_info_client_create(__dns_configuration_queue(),   // dispatch queue
+                                                        service_name,                  // XPC service name
+                                                        "DNS configuration");          // service description
+                       if (dnsinfo_client == NULL) {
+                               --dnsinfo_active;
+                       }
+               }
+       });
+
+       if ((dnsinfo_client == NULL) || !dnsinfo_client->active) {
+               // if DNS configuration server not available
                return NULL;
        }
 
                return NULL;
        }
 
-       config = expand_config(buf);
-       if (config == NULL) {
-               free(buf);
-               return NULL;
+       // create message
+       reqdict = xpc_dictionary_create(NULL, NULL, 0);
+
+       // set process name
+       if (proc_name != NULL) {
+               xpc_dictionary_set_string(reqdict, DNSINFO_PROC_NAME, proc_name);
+       }
+
+       // set request
+       xpc_dictionary_set_int64(reqdict, DNSINFO_REQUEST, DNSINFO_REQUEST_COPY);
+
+       // send request to the DNS configuration server
+       reply = libSC_send_message_with_reply_sync(dnsinfo_client, reqdict);
+       xpc_release(reqdict);
+
+       if (reply != NULL) {
+               const void      *dataRef;
+               size_t          dataLen = 0;
+
+               dataRef = xpc_dictionary_get_data(reply, DNSINFO_CONFIGURATION, &dataLen);
+               if ((dataRef != NULL) &&
+                   ((dataLen >= sizeof(_dns_config_buf_t)) && (dataLen <= DNS_CONFIG_BUF_MAX))) {
+                       _dns_config_buf_t       *config         = (_dns_config_buf_t *)(void *)dataRef;
+                       uint32_t                n_padding       = ntohl(config->n_padding);
+
+                       if (n_padding <= (DNS_CONFIG_BUF_MAX - dataLen)) {
+                               uint32_t        len;
+
+                               len = dataLen + n_padding;
+                               buf = malloc(len);
+                               bcopy((void *)dataRef, buf, dataLen);
+                               bzero(&buf[dataLen], n_padding);
+                       }
+               }
+
+               xpc_release(reply);
+       }
+
+       if (buf != NULL) {
+               /* ALIGN: cast okay since _dns_config_buf_t is int aligned */
+               config = expand_config((_dns_config_buf_t *)(void *)buf);
+               if (config == NULL) {
+                       free(buf);
+               }
        }
 
        return config;
        }
 
        return config;
@@ -489,9 +445,17 @@ void
 dns_configuration_free(dns_config_t *config)
 {
        if (config == NULL) {
 dns_configuration_free(dns_config_t *config)
 {
        if (config == NULL) {
-               return;
+               return; // ASSERT
        }
 
        }
 
+       dispatch_sync(__dns_configuration_queue(), ^{
+               if (--dnsinfo_active == 0) {
+                       // if last reference, drop connection
+                       libSC_info_client_release(dnsinfo_client);
+                       dnsinfo_client = NULL;
+               }
+       });
+
        free((void *)config);
        return;
 }
        free((void *)config);
        return;
 }
@@ -500,6 +464,34 @@ dns_configuration_free(dns_config_t *config)
 void
 _dns_configuration_ack(dns_config_t *config, const char *bundle_id)
 {
 void
 _dns_configuration_ack(dns_config_t *config, const char *bundle_id)
 {
+       xpc_object_t    reqdict;
+
+       if (config == NULL) {
+               return; // ASSERT
+       }
+
+       if ((dnsinfo_client == NULL) || !dnsinfo_client->active) {
+               // if DNS configuration server not available
+               return;
+       }
+
+       dispatch_sync(__dns_configuration_queue(), ^{
+               dnsinfo_active++;       // keep connection active (for the life of the process)
+       });
+
+       // create message
+       reqdict = xpc_dictionary_create(NULL, NULL, 0);
+
+       // set request
+       xpc_dictionary_set_int64(reqdict, DNSINFO_REQUEST, DNSINFO_REQUEST_ACKNOWLEDGE);
+
+       // set generation
+       xpc_dictionary_set_uint64(reqdict, DNSINFO_GENERATION, config->generation);
+
+       // send acknowledgement to the DNS configuration server
+       xpc_connection_send_message(dnsinfo_client->connection, reqdict);
+
+       xpc_release(reqdict);
        return;
 }
 
        return;
 }
 
@@ -512,7 +504,7 @@ main(int argc, char **argv)
 
        config = dns_configuration_copy();
        if (config != NULL) {
 
        config = dns_configuration_copy();
        if (config != NULL) {
-               dns_configuration_free(&config);
+               dns_configuration_free(config);
        }
 
        exit(0);
        }
 
        exit(0);
index db361d5931fe1bc8ea279770560d0a14a00e89bb..9bc5499f839fe143304c9a96ce017e8a33fa5e64 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004, 2006, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2006, 2009, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <strings.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <strings.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
+#include <mach/mach_time.h>
 #include <CommonCrypto/CommonDigest.h>
 #include <CommonCrypto/CommonDigest.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
 
 #include "dnsinfo_create.h"
 #include "dnsinfo_private.h"
 
 #include "dnsinfo_create.h"
 #include "dnsinfo_private.h"
-#include "shared_dns_info.h"
 #include "network_information_priv.h"
 
 #include "network_information_priv.h"
 
+#include "ip_plugin.h"
+
 
 #define ROUNDUP(a, size) \
        (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
 
 #define ROUNDUP(a, size) \
        (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
  */
 
 
  */
 
 
+__private_extern__
 dns_create_config_t
 _dns_configuration_create()
 {
        _dns_config_buf_t       *config;
 
        config = calloc(1, INITIAL_CONFIGURATION_BUF_SIZE);
 dns_create_config_t
 _dns_configuration_create()
 {
        _dns_config_buf_t       *config;
 
        config = calloc(1, INITIAL_CONFIGURATION_BUF_SIZE);
+       config->config.generation = mach_absolute_time();
 //     config->n_attribute = 0;
 //     config->n_padding = 0;
        return (dns_create_config_t)config;
 //     config->n_attribute = 0;
 //     config->n_padding = 0;
        return (dns_create_config_t)config;
@@ -111,6 +118,11 @@ config_add_attribute(dns_create_config_t   *_config,
 }
 
 
 }
 
 
+static void
+_dns_resolver_set_reach_flags(dns_create_resolver_t _resolver);
+
+
+__private_extern__
 void
 _dns_configuration_add_resolver(dns_create_config_t     *_config,
                                dns_create_resolver_t   _resolver)
 void
 _dns_configuration_add_resolver(dns_create_config_t     *_config,
                                dns_create_resolver_t   _resolver)
@@ -119,6 +131,11 @@ _dns_configuration_add_resolver(dns_create_config_t     *_config,
        uint32_t                padding         = 0;
        _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)_resolver;
 
        uint32_t                padding         = 0;
        _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)_resolver;
 
+       /*
+        * add reachability flags for this resovler configuration
+        */
+       _dns_resolver_set_reach_flags(_resolver);
+
        /*
         * compute the amount of space that will be needed for
         * pointers to the resolver, the nameservers, the search
        /*
         * compute the amount of space that will be needed for
         * pointers to the resolver, the nameservers, the search
@@ -135,17 +152,24 @@ _dns_configuration_add_resolver(dns_create_config_t     *_config,
                padding += ntohl(resolver->resolver.n_sortaddr) * sizeof(DNS_PTR(dns_sortaddr_t *, x));
        }
 
                padding += ntohl(resolver->resolver.n_sortaddr) * sizeof(DNS_PTR(dns_sortaddr_t *, x));
        }
 
-       if ((ntohl(resolver->resolver.flags) & DNS_RESOLVER_FLAGS_SCOPED) == 0) {
-               config->config.n_resolver = htonl(ntohl(config->config.n_resolver) + 1);
+       if ((ntohl(resolver->resolver.flags) & DNS_RESOLVER_FLAGS_SCOPED)) {
+               config->config.n_scoped_resolver = htonl(ntohl(config->config.n_scoped_resolver) + 1);
                config_add_attribute(_config,
                config_add_attribute(_config,
-                                    CONFIG_ATTRIBUTE_RESOLVER,
+                                    CONFIG_ATTRIBUTE_SCOPED_RESOLVER,
+                                    sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute),
+                                    (void *)resolver,
+                                    padding);
+       } else if ((ntohl(resolver->resolver.flags) & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC)) {
+               config->config.n_service_specific_resolver = htonl(ntohl(config->config.n_service_specific_resolver) + 1);
+               config_add_attribute(_config,
+                                    CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER,
                                     sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute),
                                     (void *)resolver,
                                     padding);
        } else {
                                     sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute),
                                     (void *)resolver,
                                     padding);
        } else {
-               config->config.n_scoped_resolver = htonl(ntohl(config->config.n_scoped_resolver) + 1);
+               config->config.n_resolver = htonl(ntohl(config->config.n_resolver) + 1);
                config_add_attribute(_config,
                config_add_attribute(_config,
-                                    CONFIG_ATTRIBUTE_SCOPED_RESOLVER,
+                                    CONFIG_ATTRIBUTE_RESOLVER,
                                     sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute),
                                     (void *)resolver,
                                     padding);
                                     sizeof(_dns_resolver_buf_t) + ntohl(resolver->n_attribute),
                                     (void *)resolver,
                                     padding);
@@ -154,31 +178,8 @@ _dns_configuration_add_resolver(dns_create_config_t     *_config,
        return;
 }
 
        return;
 }
 
-_Bool
-_nwi_state_store(nwi_state* state)
-{
-       mach_port_t             server;
-       kern_return_t           status;
-       dnsDataOut_t            dataRef = (dnsDataOut_t) state;
-       mach_msg_type_number_t  dataLen = state->size;
-
-       server = _dns_configuration_server_port();
-       if (server == MACH_PORT_NULL) {
-               return FALSE;
-       }
-
-       status = shared_nwi_stateSet(server, dataRef, dataLen);
-
-       (void) mach_port_deallocate(mach_task_self(), server);
-
-       if (status != KERN_SUCCESS) {
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
 
 
+__private_extern__
 void
 _dns_configuration_signature(dns_create_config_t       *_config,
                             unsigned char              *signature,
 void
 _dns_configuration_signature(dns_create_config_t       *_config,
                             unsigned char              *signature,
@@ -191,9 +192,13 @@ _dns_configuration_signature(dns_create_config_t   *_config,
 
                if (config != NULL) {
                        CC_SHA1_CTX     ctx;
 
                if (config != NULL) {
                        CC_SHA1_CTX     ctx;
+                       uint64_t        generation_save;
                        unsigned char   *sha1;
                        unsigned char   sha1_buf[CC_SHA1_DIGEST_LENGTH];
 
                        unsigned char   *sha1;
                        unsigned char   sha1_buf[CC_SHA1_DIGEST_LENGTH];
 
+                       generation_save = config->config.generation;
+                       config->config.generation = 0;
+
                        sha1 = (signature_len >= CC_SHA1_DIGEST_LENGTH) ? signature : sha1_buf;
                        CC_SHA1_Init(&ctx);
                        CC_SHA1_Update(&ctx,
                        sha1 = (signature_len >= CC_SHA1_DIGEST_LENGTH) ? signature : sha1_buf;
                        CC_SHA1_Init(&ctx);
                        CC_SHA1_Update(&ctx,
@@ -203,46 +208,16 @@ _dns_configuration_signature(dns_create_config_t  *_config,
                        if (sha1 != signature) {
                                bcopy(sha1, signature, signature_len);
                        }
                        if (sha1 != signature) {
                                bcopy(sha1, signature, signature_len);
                        }
-               }
-       }
-
-       return;
-}
-
-
-_Bool
-_dns_configuration_store(dns_create_config_t *_config)
-{
-       dnsDataOut_t            dataRef = NULL;
-       mach_msg_type_number_t  dataLen = 0;
-       mach_port_t             server;
-       kern_return_t           status;
-
-       server = _dns_configuration_server_port();
-       if (server == MACH_PORT_NULL) {
-               return FALSE;
-       }
-
-       if (_config != NULL) {
-               _dns_config_buf_t       *config = (_dns_config_buf_t *)*_config;
 
 
-               if (config != NULL) {
-                       dataRef = (dnsDataOut_t)config;
-                       dataLen = sizeof(_dns_config_buf_t) + ntohl(config->n_attribute);
+                       config->config.generation = generation_save;
                }
        }
 
                }
        }
 
-       status = shared_dns_infoSet(server, dataRef, dataLen);
-       (void) mach_port_deallocate(mach_task_self(), server);
-       if (status != KERN_SUCCESS) {
-               mach_error("shared_dns_infoSet():", status);
-               return FALSE;
-       }
-
-       return TRUE;
+       return;
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_configuration_free(dns_create_config_t *_config)
 {
 void
 _dns_configuration_free(dns_create_config_t *_config)
 {
@@ -258,6 +233,7 @@ _dns_configuration_free(dns_create_config_t *_config)
  * DNS resolver configuration functions
  */
 
  * DNS resolver configuration functions
  */
 
+__private_extern__
 dns_create_resolver_t
 _dns_resolver_create()
 {
 dns_create_resolver_t
 _dns_resolver_create()
 {
@@ -296,7 +272,7 @@ _dns_resolver_add_attribute(dns_create_resolver_t   *_resolver,
 
        // add attribute [header]
 
 
        // add attribute [header]
 
-       /* ALIGN: _dns_config_buf_t is int aligned */
+       /* ALIGN: _dns_resolver_buf_t is int aligned */
        header = (dns_attribute_t *)(void *)&resolver->attribute[oldLen];
        header->type   = htonl(attribute_type);
        header->length = htonl(newLen);
        header = (dns_attribute_t *)(void *)&resolver->attribute[oldLen];
        header->type   = htonl(attribute_type);
        header->length = htonl(newLen);
@@ -313,17 +289,44 @@ _dns_resolver_add_attribute(dns_create_resolver_t *_resolver,
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_add_nameserver(dns_create_resolver_t *_resolver, struct sockaddr *nameserver)
 {
 void
 _dns_resolver_add_nameserver(dns_create_resolver_t *_resolver, struct sockaddr *nameserver)
 {
+       uint32_t                new_flags       = 0;
+       uint32_t                old_flags;
        _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)*_resolver;
 
        _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)*_resolver;
 
+       old_flags = ntohl(resolver->resolver.flags);
+
+       switch (nameserver->sa_family) {
+               case AF_INET:
+                       if (ntohl(((struct sockaddr_in*)(void *)nameserver)->sin_addr.s_addr) == INADDR_LOOPBACK) {
+                               new_flags = DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS;
+                       }
+                       break;
+               case AF_INET6:
+                       if (IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6 *)(void *)nameserver)->sin6_addr)){
+                               new_flags = DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS;
+                       }
+                       break;
+               default:
+                       break;
+       }
+
        resolver->resolver.n_nameserver = htonl(ntohl(resolver->resolver.n_nameserver) + 1);
        _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_ADDRESS, nameserver->sa_len, (void *)nameserver);
        resolver->resolver.n_nameserver = htonl(ntohl(resolver->resolver.n_nameserver) + 1);
        _dns_resolver_add_attribute(_resolver, RESOLVER_ATTRIBUTE_ADDRESS, nameserver->sa_len, (void *)nameserver);
+
+       if (new_flags != 0) {
+               // if DNS request flags not explicitly set and we are
+               // adding a LOOPBACK resolver address
+               _dns_resolver_set_flags(_resolver, old_flags | new_flags);
+       }
        return;
 }
 
 
        return;
 }
 
 
+__private_extern__
 void
 _dns_resolver_add_search(dns_create_resolver_t *_resolver, const char *search)
 {
 void
 _dns_resolver_add_search(dns_create_resolver_t *_resolver, const char *search)
 {
@@ -335,6 +338,7 @@ _dns_resolver_add_search(dns_create_resolver_t *_resolver, const char *search)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_add_sortaddr(dns_create_resolver_t *_resolver, dns_sortaddr_t *sortaddr)
 {
 void
 _dns_resolver_add_sortaddr(dns_create_resolver_t *_resolver, dns_sortaddr_t *sortaddr)
 {
@@ -346,6 +350,7 @@ _dns_resolver_add_sortaddr(dns_create_resolver_t *_resolver, dns_sortaddr_t *sor
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_domain(dns_create_resolver_t *_resolver, const char *domain)
 {
 void
 _dns_resolver_set_domain(dns_create_resolver_t *_resolver, const char *domain)
 {
@@ -354,6 +359,7 @@ _dns_resolver_set_domain(dns_create_resolver_t *_resolver, const char *domain)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_flags(dns_create_resolver_t *_resolver, uint32_t flags)
 {
 void
 _dns_resolver_set_flags(dns_create_resolver_t *_resolver, uint32_t flags)
 {
@@ -364,6 +370,7 @@ _dns_resolver_set_flags(dns_create_resolver_t *_resolver, uint32_t flags)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_if_index(dns_create_resolver_t *_resolver, uint32_t if_index)
 {
 void
 _dns_resolver_set_if_index(dns_create_resolver_t *_resolver, uint32_t if_index)
 {
@@ -374,6 +381,7 @@ _dns_resolver_set_if_index(dns_create_resolver_t *_resolver, uint32_t if_index)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_options(dns_create_resolver_t *_resolver, const char *options)
 {
 void
 _dns_resolver_set_options(dns_create_resolver_t *_resolver, const char *options)
 {
@@ -382,6 +390,7 @@ _dns_resolver_set_options(dns_create_resolver_t *_resolver, const char *options)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_order(dns_create_resolver_t *_resolver, uint32_t order)
 {
 void
 _dns_resolver_set_order(dns_create_resolver_t *_resolver, uint32_t order)
 {
@@ -392,6 +401,7 @@ _dns_resolver_set_order(dns_create_resolver_t *_resolver, uint32_t order)
 }
 
 
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_port(dns_create_resolver_t *_resolver, uint16_t port)
 {
 void
 _dns_resolver_set_port(dns_create_resolver_t *_resolver, uint16_t port)
 {
@@ -402,16 +412,124 @@ _dns_resolver_set_port(dns_create_resolver_t *_resolver, uint16_t port)
 }
 
 
 }
 
 
-void
-_dns_resolver_set_reach_flags(dns_create_resolver_t *_resolver, uint32_t reach_flags)
+/*
+ * rankReachability()
+ *   Not reachable       == 0
+ *   Connection Required == 1
+ *   Reachable           == 2
+ */
+static int
+rankReachability(SCNetworkReachabilityFlags flags)
 {
 {
-       _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)*_resolver;
+       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)
+{
+       _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)_resolver;
+
+       if (resolver->resolver.n_nameserver != 0) {
+               dns_attribute_t                 *attribute;
+               SCNetworkReachabilityFlags      flags           = kSCNetworkReachabilityFlagsReachable;
+               uint32_t                        n_attribute;
+               uint32_t                        n_nameserver    = 0;
+               CFMutableDictionaryRef          targetOptions;
+
+               targetOptions = CFDictionaryCreateMutable(NULL,
+                                                         0,
+                                                         &kCFTypeDictionaryKeyCallBacks,
+                                                         &kCFTypeDictionaryValueCallBacks);
+               CFDictionarySetValue(targetOptions,
+                                    kSCNetworkReachabilityOptionServerBypass,
+                                    kCFBooleanTrue);
+               if (resolver->resolver.if_index != 0) {
+                       char            if_name[IFNAMSIZ];
+
+                       if (if_indextoname(ntohl(resolver->resolver.if_index), if_name) != NULL) {
+                               CFStringRef     targetInterface;
+
+                               targetInterface = CFStringCreateWithCString(NULL,
+                                                                           if_name,
+                                                                           kCFStringEncodingASCII);
+                               CFDictionarySetValue(targetOptions,
+                                                    kSCNetworkReachabilityOptionInterface,
+                                                    targetInterface);
+                               CFRelease(targetInterface);
+                       }
+               }
+
+               attribute   = (dns_attribute_t *)(void *)&resolver->attribute[0];
+               n_attribute = ntohl(resolver->n_attribute);
+
+               while (n_attribute >= sizeof(dns_attribute_t)) {
+                       uint32_t        attribute_length        = ntohl(attribute->length);
+                       uint32_t        attribute_type          = ntohl(attribute->type);
+
+                       if (attribute_type == RESOLVER_ATTRIBUTE_ADDRESS) {
+                               struct sockaddr                 *addr;
+                               CFDataRef                       addrData;
+                               SCNetworkReachabilityFlags      ns_flags;
+                               Boolean                         ok;
+                               SCNetworkReachabilityRef        target;
+
+                               addr = (struct sockaddr *)&attribute->attribute[0];
+                               addrData = CFDataCreate(NULL, (const UInt8 *)addr, addr->sa_len);
+                               CFDictionarySetValue(targetOptions,
+                                                    kSCNetworkReachabilityOptionRemoteAddress,
+                                                    addrData);
+                               CFRelease(addrData);
+
+                               target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions);
+                               if (target == NULL) {
+                                       CFDictionaryRemoveValue(targetOptions, kSCNetworkReachabilityOptionInterface);
+                                       target = SCNetworkReachabilityCreateWithOptions(NULL, targetOptions);
+                                       if (target != NULL) {
+                                               // if interface name not (no longer) valid
+                                               CFRelease(target);
+                                               flags = 0;
+                                               break;
+                                       }
+
+                                       // address not valid?
+                                       my_log(LOG_ERR,
+                                              "_dns_resolver_set_reach_flags SCNetworkReachabilityCreateWithOptions() failed:\n  options = %@",
+                                              targetOptions);
+                                       break;
+                               }
+
+                               ok = SCNetworkReachabilityGetFlags(target, &ns_flags);
+                               CFRelease(target);
+                               if (!ok) {
+                                       break;
+                               }
+
+                               if ((n_nameserver++ == 0) ||
+                                   (rankReachability(ns_flags) < rankReachability(flags))) {
+                                       /* return the first (and later, worst case) result */
+                                       flags = ns_flags;
+                               }
+                       }
+
+                       attribute   = (dns_attribute_t *)((void *)attribute + attribute_length);
+                       n_attribute -= attribute_length;
+               }
+
+               CFRelease(targetOptions);
+
+               resolver->resolver.reach_flags = htonl(flags);
+       }
 
 
-       resolver->resolver.reach_flags = htonl(reach_flags);
        return;
 }
 
 
        return;
 }
 
 
+__private_extern__
 void
 _dns_resolver_set_timeout(dns_create_resolver_t *_resolver, uint32_t timeout)
 {
 void
 _dns_resolver_set_timeout(dns_create_resolver_t *_resolver, uint32_t timeout)
 {
@@ -422,6 +540,17 @@ _dns_resolver_set_timeout(dns_create_resolver_t *_resolver, uint32_t timeout)
 }
 
 
 }
 
 
+__private_extern__
+void
+_dns_resolver_set_service_identifier(dns_create_resolver_t *_resolver, uint32_t service_identifier)
+{
+       _dns_resolver_buf_t *resolver   = (_dns_resolver_buf_t *)*_resolver;
+
+       resolver->resolver.service_identifier = htonl(service_identifier);
+}
+
+
+__private_extern__
 void
 _dns_resolver_free(dns_create_resolver_t *_resolver)
 {
 void
 _dns_resolver_free(dns_create_resolver_t *_resolver)
 {
index 89c71b53911b2dd1543ad6e722331a5589f73ecd..decc575d100218c31b1b6ac371d6f649273c1f57 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2006, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006, 2008, 2009, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -49,110 +49,86 @@ typedef const struct __dns_create_resolver *    dns_create_resolver_t;
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-/*
- * NOTE: __private_extern__ and __OSX_AVAILABLE_STARTING() cannot be mixed
- *       due to a "visibility" conflict
- */
-
 /*
  * DNS configuration creation APIs
  */
 /*
  * DNS configuration creation APIs
  */
-__private_extern__
 dns_create_config_t
 dns_create_config_t
-_dns_configuration_create       (void)                                         /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+_dns_configuration_create       (void)                                         __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_configuration_add_resolver (dns_create_config_t   *_config,
 void
 _dns_configuration_add_resolver (dns_create_config_t   *_config,
-                                dns_create_resolver_t  _resolver)              /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                dns_create_resolver_t  _resolver)              __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_configuration_signature   (dns_create_config_t    *_config,
                                 unsigned char          *signature,
 void
 _dns_configuration_signature   (dns_create_config_t    *_config,
                                 unsigned char          *signature,
-                                size_t                 signature_len)          /*__OSX_AVAILABLE_STARTING(__MAC_10_7+,__IPHONE_5_0)*/; // signature_len >= CC_SHA1_DIGEST_LENGTH
-
-__private_extern__
-_Bool
-_dns_configuration_store       (dns_create_config_t    *_config)               /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                size_t                 signature_len)          __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0);      // signature_len >= CC_SHA1_DIGEST_LENGTH
 
 
-__private_extern__
 void
 void
-_dns_configuration_free                (dns_create_config_t    *_config)               /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+_dns_configuration_free                (dns_create_config_t    *_config)               __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 /*
  * DNS [resolver] configuration creation APIs
  */
 
 /*
  * DNS [resolver] configuration creation APIs
  */
-__private_extern__
 dns_create_resolver_t
 dns_create_resolver_t
-_dns_resolver_create           (void)                                          /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+_dns_resolver_create           (void)                                          __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_domain       (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_domain       (dns_create_resolver_t  *_resolver,
-                                const char             *domain)                /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                const char             *domain)                __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_add_nameserver   (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_add_nameserver   (dns_create_resolver_t  *_resolver,
-                                struct sockaddr        *nameserver)            /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                struct sockaddr        *nameserver)            __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_add_search       (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_add_search       (dns_create_resolver_t  *_resolver,
-                                const char             *search)                /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                const char             *search)                __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_add_sortaddr     (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_add_sortaddr     (dns_create_resolver_t  *_resolver,
-                                dns_sortaddr_t         *sortaddr)              /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                dns_sortaddr_t         *sortaddr)              __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_flags                (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_flags                (dns_create_resolver_t  *_resolver,
-                                uint32_t               flags)                  /*__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0)*/;
+                                uint32_t               flags)                  __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_if_index     (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_if_index     (dns_create_resolver_t  *_resolver,
-                                uint32_t               if_index)               /*__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0)*/;
+                                uint32_t               if_index)               __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_options      (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_options      (dns_create_resolver_t  *_resolver,
-                                const char             *options)               /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                const char             *options)               __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_order                (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_order                (dns_create_resolver_t  *_resolver,
-                                uint32_t               order)                  /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+                                uint32_t               order)                  __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 _dns_resolver_set_port         (dns_create_resolver_t  *_resolver,
 void
 _dns_resolver_set_port         (dns_create_resolver_t  *_resolver,
-                                uint16_t               port)                   /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;  // host byte order
+                                uint16_t               port)                   __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);      // host byte order
 
 
-__private_extern__
 void
 void
-_dns_resolver_set_reach_flags  (dns_create_resolver_t  *_resolver,
-                                uint32_t               reach_flags)            /*__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0)*/;
+_dns_resolver_set_timeout      (dns_create_resolver_t  *_resolver,
+                                uint32_t               timeout)                __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 
-__private_extern__
 void
 void
-_dns_resolver_set_timeout      (dns_create_resolver_t  *_resolver,
-                                uint32_t               timeout)                /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+_dns_resolver_set_service_identifier   (dns_create_resolver_t  *_resolver,
+                                       uint32_t                service_identifier)     __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
 
 
-__private_extern__
 void
 void
-_dns_resolver_free             (dns_create_resolver_t  *_resolver)             /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
+_dns_resolver_free             (dns_create_resolver_t  *_resolver)             __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0);
 
 #if    !TARGET_OS_IPHONE
 /*
  * DNS [resolver] flat-file configuration creation APIs
  */
 
 #if    !TARGET_OS_IPHONE
 /*
  * DNS [resolver] flat-file configuration creation APIs
  */
-__private_extern__
 void
 void
-_dnsinfo_flatfile_add_resolvers        (dns_create_config_t    *config)                /*__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)*/;
+_dnsinfo_flatfile_add_resolvers        (dns_create_config_t    *config)                __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
+
+void
+_dnsinfo_flatfile_set_flags    (uint32_t               flags)                  __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_NA);
 #endif // !TARGET_OS_IPHONE
 
 __END_DECLS
 #endif // !TARGET_OS_IPHONE
 
 __END_DECLS
index e052d2eb543f1ffb0a4d9d13271965864fcef395..65861b7914542e432d6bb3e4bb809feabd6261b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2009, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -39,6 +39,8 @@
 #include "dnsinfo_private.h"
 #include "dnsinfo_create.h"
 
 #include "dnsinfo_private.h"
 #include "dnsinfo_create.h"
 
+static uint32_t _dnsinfo_flatfile_flags;
+
 enum {
        TOKEN_DOMAIN,
        TOKEN_FLAGS,
 enum {
        TOKEN_DOMAIN,
        TOKEN_FLAGS,
@@ -233,6 +235,34 @@ _dnsinfo_parse_sortaddr(char *token)
 }
 
 
 }
 
 
+/*
+ * _dnsinfo_flatfile_set_flags
+ *
+ * Set the default resolver flags.
+ */
+__private_extern__
+void
+_dnsinfo_flatfile_set_flags(uint32_t flags)
+{
+       _dnsinfo_flatfile_flags = flags;
+       return;
+}
+
+
+static void
+_dnsinfo_flatfile_update_flags(dns_create_resolver_t *_resolver)
+{
+       uint32_t                new_flags;
+       uint32_t                old_flags;
+       _dns_resolver_buf_t     *resolver       = (_dns_resolver_buf_t *)*_resolver;
+
+       old_flags = ntohl(resolver->resolver.flags);
+       new_flags = old_flags | _dnsinfo_flatfile_flags;
+       _dns_resolver_set_flags(_resolver, new_flags);
+       return;
+}
+
+
 /*
  * _dnsinfo_flatfile_create_resolver
  *
 /*
  * _dnsinfo_flatfile_create_resolver
  *
@@ -243,6 +273,7 @@ static dns_create_resolver_t
 _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
 {
        char                    *buf;
 _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
 {
        char                    *buf;
+       uint32_t                config_flags            = 0;
        FILE                    *f;
        char                    filename[FILENAME_MAX];
        size_t                  len                     = 0;
        FILE                    *f;
        char                    filename[FILENAME_MAX];
        size_t                  len                     = 0;
@@ -339,20 +370,18 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
                        }
 
                        case TOKEN_FLAGS: {
                        }
 
                        case TOKEN_FLAGS: {
-                               uint32_t        flags   = 0;
-
                                while (word != NULL) {
                                        if (word[0] != '\0') {
                                                if (strcasecmp(word, "scoped") == 0) {
                                while (word != NULL) {
                                        if (word[0] != '\0') {
                                                if (strcasecmp(word, "scoped") == 0) {
-                                                       flags |= DNS_RESOLVER_FLAGS_SCOPED;
+                                                       config_flags |= DNS_RESOLVER_FLAGS_SCOPED;
+                                               } else if (strcasecmp(word, "a") == 0) {
+                                                       config_flags |= DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
+                                               } else if (strcasecmp(word, "aaaa") == 0) {
+                                                       config_flags |= DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
                                                }
                                        }
                                        word = strsep(&lineptr, sep);
                                }
                                                }
                                        }
                                        word = strsep(&lineptr, sep);
                                }
-
-                               if (flags != 0) {
-                                       _dns_resolver_set_flags(&res, flags);
-                               }
                                break;
                        }
 
                                break;
                        }
 
@@ -480,6 +509,15 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
                _dns_resolver_set_domain(&res, domain);
        }
 
                _dns_resolver_set_domain(&res, domain);
        }
 
+       if (res != NULL) {
+               // config flags should overwrite any default flags
+               if (config_flags != 0) {
+                       _dns_resolver_set_flags(&res, config_flags);
+               } else {
+                       _dnsinfo_flatfile_update_flags(&res);
+               }
+       }
+
     done :
 
        fclose(f);
     done :
 
        fclose(f);
@@ -493,6 +531,7 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path)
  * Parse the files in the resolver config directory (/etc/resolver) and add each
  * resolver to the dns config.
  */
  * Parse the files in the resolver config directory (/etc/resolver) and add each
  * resolver to the dns config.
  */
+__private_extern__
 void
 _dnsinfo_flatfile_add_resolvers(dns_create_config_t *config)
 {
 void
 _dnsinfo_flatfile_add_resolvers(dns_create_config_t *config)
 {
diff --git a/dnsinfo/dnsinfo_internal.h b/dnsinfo/dnsinfo_internal.h
new file mode 100644 (file)
index 0000000..a7dc643
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013 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 _S_DNSINFO_INTERNAL_H
+#define _S_DNSINFO_INTERNAL_H
+
+#include <Availability.h>
+#include <TargetConditionals.h>
+#include <sys/cdefs.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCNetworkReachabilityInternal.h"
+#include <arpa/inet.h>
+
+#include <dnsinfo.h>
+
+__BEGIN_DECLS
+
+static __inline__ void
+_dns_resolver_print(dns_resolver_t *resolver, int index)
+{
+       int     i;
+
+       SCPrint(TRUE, stdout, CFSTR("\nresolver #%d\n"), index);
+
+       if (resolver->domain != NULL) {
+               SCPrint(TRUE, stdout, CFSTR("  domain   : %s\n"), resolver->domain);
+       }
+
+       for (i = 0; i < resolver->n_search; i++) {
+               SCPrint(TRUE, stdout, CFSTR("  search domain[%d] : %s\n"), i, resolver->search[i]);
+       }
+
+       for (i = 0; i < resolver->n_nameserver; i++) {
+               char    buf[128];
+
+               _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf));
+               SCPrint(TRUE, stdout, CFSTR("  nameserver[%d] : %s\n"), i, buf);
+       }
+
+       for (i = 0; i < resolver->n_sortaddr; i++) {
+               char    abuf[32];
+               char    mbuf[32];
+
+               (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->address, abuf, sizeof(abuf));
+               (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->mask,    mbuf, sizeof(mbuf));
+               SCPrint(TRUE, stdout, CFSTR("  sortaddr[%d] : %s/%s\n"), i, abuf, mbuf);
+       }
+
+       if (resolver->options != NULL) {
+               SCPrint(TRUE, stdout, CFSTR("  options  : %s\n"), resolver->options);
+       }
+
+       if (resolver->port != 0) {
+               SCPrint(TRUE, stdout, CFSTR("  port     : %hd\n"), resolver->port);
+       }
+
+       if (resolver->timeout != 0) {
+               SCPrint(TRUE, stdout, CFSTR("  timeout  : %d\n"), resolver->timeout);
+       }
+
+       if (resolver->if_index != 0) {
+               char    buf[IFNAMSIZ];
+               char    *if_name;
+
+               if_name = if_indextoname(resolver->if_index, buf);
+               SCPrint(TRUE, stdout, CFSTR("  if_index : %d (%s)\n"),
+                       resolver->if_index,
+                       (if_name != NULL) ? if_name : "?");
+       }
+
+       if (resolver->service_identifier != 0) {
+               SCPrint(TRUE, stdout, CFSTR("  service_identifier : %d\n"),
+                       resolver->service_identifier);
+       }
+
+       if (resolver->flags != 0) {
+               uint32_t        flags   = resolver->flags;
+
+               SCPrint(TRUE, stdout, CFSTR("  flags    : "));
+               SCPrint(_sc_debug, stdout, CFSTR("0x%08x ("), flags);
+               if (flags & DNS_RESOLVER_FLAGS_SCOPED) {
+                       SCPrint(TRUE, stdout, CFSTR("Scoped"));
+                       flags &= ~DNS_RESOLVER_FLAGS_SCOPED;
+                       SCPrint(flags != 0, stdout, CFSTR(", "));
+               }
+               if (flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) {
+                       SCPrint(TRUE, stdout, CFSTR("Service-specific"));
+                       flags &= ~DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
+                       SCPrint(flags != 0, stdout, CFSTR(", "));
+               }
+               if (flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) {
+                       SCPrint(TRUE, stdout, CFSTR("Request A records"));
+                       flags &= ~DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
+                       SCPrint(flags != 0, stdout, CFSTR(", "));
+               }
+               if (flags & DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) {
+                       SCPrint(TRUE, stdout, CFSTR("Request AAAA records"));
+                       flags &= ~DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
+                       SCPrint(flags != 0, stdout, CFSTR(", "));
+               }
+               if (flags != 0) {
+                       SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
+               }
+               SCPrint(_sc_debug, stdout, CFSTR(")"));
+               SCPrint(TRUE, stdout, CFSTR("\n"));
+       }
+
+       if (resolver->reach_flags != 0) {
+               uint32_t        flags   = resolver->reach_flags;
+
+               SCPrint(TRUE, stdout, CFSTR("  reach    : "));
+               SCPrint(_sc_debug, stdout, CFSTR("0x%08x ("), flags);
+               __SCNetworkReachabilityPrintFlags(flags);
+               SCPrint(_sc_debug, stdout, CFSTR(")"));
+               SCPrint(TRUE, stdout, CFSTR("\n"));
+       }
+
+       if (resolver->search_order != 0) {
+               SCPrint(TRUE, stdout, CFSTR("  order    : %d\n"), resolver->search_order);
+       }
+
+       return;
+}
+
+
+static __inline__ void
+_dns_configuration_print(dns_config_t *dns_config)
+{
+       int     i;
+
+       SCPrint(TRUE, stdout, CFSTR("DNS configuration\n"));
+
+       for (i = 0; i < dns_config->n_resolver; i++) {
+               dns_resolver_t  *resolver       = dns_config->resolver[i];
+
+               _dns_resolver_print(resolver, i + 1);
+       }
+
+       if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) {
+               SCPrint(TRUE, stdout, CFSTR("\nDNS configuration (for scoped queries)\n"));
+
+               for (i = 0; i < dns_config->n_scoped_resolver; i++) {
+                       dns_resolver_t  *resolver       = dns_config->scoped_resolver[i];
+
+                       _dns_resolver_print(resolver, i + 1);
+               }
+       }
+
+       if ((dns_config->n_service_specific_resolver > 0) && (dns_config->service_specific_resolver != NULL)) {
+               SCPrint(TRUE, stdout, CFSTR("\nDNS configuration (for service-specific queries)\n"));
+
+               for (i = 0; i < dns_config->n_service_specific_resolver; i++) {
+                       dns_resolver_t  *resolver       = dns_config->service_specific_resolver[i];
+
+                       _dns_resolver_print(resolver, i + 1);
+               }
+       }
+
+       return;
+}
+
+__END_DECLS
+
+#endif /* !_S_DNSINFO_INTERNAL_H */
diff --git a/dnsinfo/dnsinfo_private.c b/dnsinfo/dnsinfo_private.c
deleted file mode 100644 (file)
index f7b256f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, 2005, 2007, 2009 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 9, 2004               Allan Nathanson <ajn@apple.com>
- * - initial revision
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <servers/bootstrap.h>
-#include <bootstrap_priv.h>
-
-#include "dnsinfo_private.h"
-#include "shared_dns_info_types.h"
-
-
-__private_extern__
-const char *
-_dns_configuration_notify_key()
-{
-       return "com.apple.system.SystemConfiguration.dns_configuration";
-}
-
-
-__private_extern__
-mach_port_t
-_dns_configuration_server_port()
-{
-       mach_port_t     server          = MACH_PORT_NULL;
-       char            *server_name;
-       kern_return_t   status;
-
-       server_name = getenv("DNS_SERVER");
-       if (!server_name) {
-               server_name = DNS_SERVER;
-       }
-
-#ifdef BOOTSTRAP_PRIVILEGED_SERVER
-       status = bootstrap_look_up2(bootstrap_port,
-                                   server_name,
-                                   &server,
-                                   0,
-                                   BOOTSTRAP_PRIVILEGED_SERVER);
-#else  // BOOTSTRAP_PRIVILEGED_SERVER
-       status = bootstrap_look_up(bootstrap_port, server_name, &server);
-#endif // BOOTSTRAP_PRIVILEGED_SERVER
-
-       switch (status) {
-               case BOOTSTRAP_SUCCESS :
-                       /* service currently registered, "a good thing" (tm) */
-                       break;
-               case BOOTSTRAP_NOT_PRIVILEGED :
-                       /* the service is not privileged */
-                       return MACH_PORT_NULL;
-               case BOOTSTRAP_UNKNOWN_SERVICE :
-                       /* service not currently registered, try again later */
-                       return MACH_PORT_NULL;
-               default :
-                       fprintf(stderr,
-                               "could not lookup DNS configuration info service: %s\n",
-                               bootstrap_strerror(status));
-                       return MACH_PORT_NULL;
-       }
-
-       return server;
-}
-
index 58128a8e05b745330ef3ac2d13d8ecc2da115015..d6e65b5fcac6c7ba1bb29b7ab2fb849841201cdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * | |             | |                   |                             |    resolver configurations  that will
  * | |             | |                   |                             |    be established in the "padding"
  * | |             | +-------------------+-----------------------------+
  * | |             | |                   |                             |    resolver configurations  that will
  * | |             | |                   |                             |    be established in the "padding"
  * | |             | +-------------------+-----------------------------+
+ * | |             | | generation        | uint64_t                    | <- generation # of configuration
+ * | |             | +-------------------+---------+-------------------+
+ * | |             | | n_service_specific_resolver | int32_t           | <- # of name service-specific resolvers
+ * | |             | +-------------------+---------+-------------------+
+ * | |             | | service_specific_resolver   | dns_resolver_t ** | <- not used during creation, filled
+ * | |             | |                             |                   |    in with pointer to a list of service-specific
+ * | |             | |                             |                   |    resolver configurations that will be
+ * | |             | |                             |                   |    established in the "padding"
+ * | |             | +-------------------+---------+-------------------+
  * | |             | | ...               | ...                         |
  * | +-------------+-+-------------------+-----------------------------+
  * | | n_attribute | uint32_t                                          | <- how many bytes of "attribute"
  * | |             | | ...               | ...                         |
  * | +-------------+-+-------------------+-----------------------------+
  * | | n_attribute | uint32_t                                          | <- how many bytes of "attribute"
 enum {
        CONFIG_ATTRIBUTE_RESOLVER       = 1,
        CONFIG_ATTRIBUTE_SCOPED_RESOLVER,
 enum {
        CONFIG_ATTRIBUTE_RESOLVER       = 1,
        CONFIG_ATTRIBUTE_SCOPED_RESOLVER,
+       CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER,
 };
 
 
 };
 
 
@@ -161,8 +171,6 @@ enum {
        RESOLVER_ATTRIBUTE_ADDRESS,
        RESOLVER_ATTRIBUTE_SEARCH,
        RESOLVER_ATTRIBUTE_SORTADDR,
        RESOLVER_ATTRIBUTE_ADDRESS,
        RESOLVER_ATTRIBUTE_SEARCH,
        RESOLVER_ATTRIBUTE_SORTADDR,
-       RESOLVER_ATTRIBUTE_IF_INDEX,
-       RESOLVER_ATTRIBUTE_FLAGS,
        RESOLVER_ATTRIBUTE_OPTIONS,
 };
 
        RESOLVER_ATTRIBUTE_OPTIONS,
 };
 
@@ -197,19 +205,6 @@ typedef struct {
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-/*
- * NOTE: __private_extern__ and __OSX_AVAILABLE_STARTING() cannot be mixed
- *       due to a "visibility" conflict
- */
-
-__private_extern__
-const char *
-_dns_configuration_notify_key  ()      /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
-
-__private_extern__
-mach_port_t
-_dns_configuration_server_port ()      /*__OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0)*/;
-
 __END_DECLS
 
 #endif /* __DNSINFO_PRIVATE_H__ */
 __END_DECLS
 
 #endif /* __DNSINFO_PRIVATE_H__ */
index 1d8bcace732da3a807088d317c497b82b95482da..9a3e588be58e154787023c23621a348ca6123333 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <bsm/libbsm.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <bsm/libbsm.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <SystemConfiguration/SCPrivate.h>
 
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <SystemConfiguration/SCPrivate.h>
 
+#include "libSystemConfiguration_client.h"
+#include "libSystemConfiguration_server.h"
+
+#include "dnsinfo_create.h"
 #include "dnsinfo_server.h"
 #include "dnsinfo_private.h"
 #include "dnsinfo_server.h"
 #include "dnsinfo_private.h"
-#include <network_information.h>
 
 
-static CFDataRef       shared_dns_info         = NULL;
-static  CFDataRef      shared_nwi_state        = NULL;
+#pragma mark -
+#pragma mark Globals
 
 
-__private_extern__
-kern_return_t
-_shared_dns_infoGet(mach_port_t server, dnsDataOut_t *dataRef, mach_msg_type_number_t *dataLen)
-{
-       *dataRef = NULL;
-       *dataLen = 0;
 
 
-       if (shared_dns_info != NULL) {
-               CFIndex len;
-               Boolean ok;
+/*
+ * S_dns_info
+ *
+ * Note: all accesses should be made while running on the _dns_server_queue()
+ */
+static libSC_info_server_t     S_dns_info;
+
 
 
-               ok = _SCSerializeData(shared_dns_info, (void **)dataRef, &len);
-               *dataLen = len;
-               if (!ok) {
-                       return KERN_FAILURE;
-               }
+/*
+ * S_debug
+ *     A boolean that enables additional logging.
+ */
+static Boolean         *S_debug = NULL;
+static SCLoggerRef     S_logger = NULL;
+
+
+/*
+ * S_sync_handler
+ *     ACK (in-sync or not-in-sync) updates should be posted using
+ *     this handler
+ *
+ * Note: all accesses should be made while running on the _dns_server_queue()
+ */
+static _dns_sync_handler_t     S_sync_handler  = NULL;
+
+
+#pragma mark -
+#pragma mark Support functions
+
+
+#ifdef NOT_YET_NEEDED
+static void
+log_xpc_object(const char *msg, xpc_object_t obj)
+{
+       char            *desc;
+
+       desc = xpc_copy_description(obj);
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("%s = %s"), msg, desc);
        }
        }
+       free(desc);
+}
+#endif
+
+
+#pragma mark -
+#pragma mark DNS configuration server
 
 
-       return KERN_SUCCESS;
+
+static dispatch_queue_t
+_dnsinfo_server_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(DNSINFO_SERVICE_NAME ".server", NULL);
+       });
+
+       return q;
 }
 
 
 }
 
 
-static
-kern_return_t
-_shared_infoSet_common(mach_port_t             server,
-                      dnsData_t                dataRef,
-                      mach_msg_type_number_t   dataLen,
-                      audit_token_t            audit_token,
-                      CFDataRef*               cache,
-                      const char*              notify_key)
+/*
+ * _dnsinfo_copy
+ *
+ * Called when a client wants a copy of the current
+ * DNS configuration
+ *
+ * - caller must be running on the _dns_server_queue()
+ */
+static void
+_dnsinfo_copy(xpc_connection_t connection, xpc_object_t request)
 {
 {
-       uid_t           euid            = 0;
-       CFDataRef       new_info        = NULL;
-       CFDataRef       n_cache         = *cache;
+       CFDataRef               data;
+       uint64_t                generation;
+       xpc_connection_t        remote;
+       xpc_object_t            reply;
+
+       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);
+               return;
+       }
 
 
-       if ((dataRef != NULL) && (dataLen > 0)) {
-               if (!_SCUnserializeData(&new_info, (void *)dataRef, dataLen)) {
-                       goto error;
+       // extract data and generation #
+       data = _libSC_info_server_get_data(&S_dns_info,
+                                          connection,
+                                          &generation);
+
+       if (*S_debug) {
+               const char      *proc_name;
+
+               // extract process name
+               proc_name = xpc_dictionary_get_string(request, DNSINFO_PROC_NAME);
+               if (proc_name == NULL) {
+                       proc_name = "???";
                }
                }
+
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%s[%d]> DNS configuration copy: %llu"),
+                           connection,
+                           proc_name,
+                           xpc_connection_get_pid(connection),
+                           generation);
        }
 
        }
 
-       audit_token_to_au32(audit_token,
-                           NULL,       // auidp
-                           &euid,      // euid
-                           NULL,       // egid
-                           NULL,       // ruid
-                           NULL,       // rgid
-                           NULL,       // pid
-                           NULL,       // asid
-                           NULL);      // tid
-       if (euid != 0) {
-               goto error;
+       // return the DNS configuration (if available)
+       if (data != NULL) {
+               xpc_dictionary_set_data(reply,
+                                       DNSINFO_CONFIGURATION,
+                                       CFDataGetBytePtr(data),
+                                       CFDataGetLength(data));
        }
 
        }
 
-       if ((n_cache != NULL) &&
-           (new_info != NULL) &&
-           CFEqual(n_cache, new_info)) {
-               CFRelease(new_info);
-               return KERN_SUCCESS;
+       // reply
+       xpc_connection_send_message(remote, reply);
+       xpc_release(reply);
+
+       return;
+}
+
+
+/*
+ * _dnsinfo_acknowledge
+ *
+ * Called when a client wants to acknowledge processing
+ * of the DNS configuration
+ *
+ * - caller must be running on the _dns_server_queue()
+ */
+static void
+_dnsinfo_acknowledge(xpc_connection_t connection, xpc_object_t request)
+{
+       uint64_t        generation;
+       Boolean         inSync;
+
+       generation = xpc_dictionary_get_uint64(request, DNSINFO_GENERATION);
+
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%d> DNS configuration ack: %llu"),
+                           connection,
+                           xpc_connection_get_pid(connection),
+                           generation);
        }
 
        }
 
-       if (n_cache != NULL) CFRelease(n_cache);
-       *cache = new_info;
+       (void) _libSC_info_server_acknowledged(&S_dns_info, connection, generation);
 
 
-       if (notify_key != NULL) {
-               uint32_t        status;
+       // Note: all of the mDNSResponder ack's should result
+       //       in a [new] network change being posted
 
 
-               status = notify_post(notify_key);
-               if (status != NOTIFY_STATUS_OK) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("notify_post() failed: %d"), status);
-                       // notification posting failures are non-fatal
-               }
+       inSync = _libSC_info_server_in_sync(&S_dns_info);
+       S_sync_handler(inSync);
+
+       return;
+}
+
+
+static void
+process_request(xpc_connection_t connection, xpc_object_t request)
+{
+       int64_t         op;
+
+       op = xpc_dictionary_get_int64(request, DNSINFO_REQUEST);
+       switch (op) {
+               case DNSINFO_REQUEST_COPY :
+                       /*
+                        * Return the DNS configuration
+                        */
+                       _dnsinfo_copy(connection, request);
+                       break;
+
+               case DNSINFO_REQUEST_ACKNOWLEDGE :
+                       /*
+                        * Acknowlege a [processed] DNS configuration
+                        */
+                       _dnsinfo_acknowledge(connection, request);
+
+                       break;
+               default :
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("<%p> unknown request : %d"),
+                                   connection,
+                                   op);
+
+                       break;
        }
 
        }
 
-       return KERN_SUCCESS;
+       return;
+}
 
 
-    error :
 
 
-       if (new_info != NULL)    CFRelease(new_info);
-       return KERN_FAILURE;
+static void
+process_new_connection(xpc_connection_t c)
+{
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%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) {
+               xpc_type_t      type;
+
+               type = xpc_get_type(xobj);
+               if (type == XPC_TYPE_DICTIONARY) {
+                       // process the request
+                       process_request(c, xobj);
+
+               } else if (type == XPC_TYPE_ERROR) {
+                       const char      *desc;
+
+                       desc = xpc_dictionary_get_string(xobj, XPC_ERROR_KEY_DESCRIPTION);
+                       if (xobj == XPC_ERROR_CONNECTION_INVALID) {
+                               Boolean         changed;
+
+                               if (*S_debug) {
+                                       SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%d> DNS configuration session: close"),
+                                                   c,
+                                                   xpc_connection_get_pid(c));
+                               }
+
+                               changed = _libSC_info_server_close(&S_dns_info, c);
+                               if (changed) {
+                                       Boolean         inSync;
+
+                                       // report change
+                                       inSync = _libSC_info_server_in_sync(&S_dns_info);
+                                       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);
+
+                       } else {
+                               SCLoggerLog(S_logger, LOG_ERR,
+                                           CFSTR("<%p:%d> Connection error: %d : %s"),
+                                           c,
+                                           xpc_connection_get_pid(c),
+                                           xobj,
+                                           desc);
+                       }
+
+               }  else {
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("<%p:%d> unknown event type : %x"),
+                                   c,
+                                   xpc_connection_get_pid(c),
+                                   type);
+               }
+       });
+
+       xpc_connection_resume(c);
+
+       return;
 }
 
 
 }
 
 
+#pragma mark -
+#pragma mark DNS configuration server SPIs
+
+
 __private_extern__
 __private_extern__
-kern_return_t
-_shared_dns_infoSet(mach_port_t                        server,
-                   dnsData_t                   dataRef,
-                   mach_msg_type_number_t      dataLen,
-                   audit_token_t               audit_token)
+void
+load_DNSConfiguration(CFBundleRef              bundle,
+                     SCLoggerRef               logger,
+                     Boolean                   *bundleVerbose,
+                     _dns_sync_handler_t       syncHandler)
 {
 {
-       const char      *notify_key;
+       xpc_connection_t        c;
+       const char              *name;
+
+       S_debug = bundleVerbose;
+       S_logger = logger;
+
+       /*
+        * keep track of DNS configuration acknowledgements
+        */
+       _libSC_info_server_init(&S_dns_info);
+
+       /*
+        * save the in-sync/not-in-sync handler
+        */
+       S_sync_handler = Block_copy(syncHandler);
+
+       // create XPC listener
+       name = getenv(DNSINFO_SERVICE_NAME);
+       if (name == NULL) {
+               name = DNSINFO_SERVICE_NAME;
+       }
+
+       c = xpc_connection_create_mach_service(name,
+                                              _dnsinfo_server_queue(),
+                                              XPC_CONNECTION_MACH_SERVICE_LISTENER);
+
+       xpc_connection_set_event_handler(c, ^(xpc_object_t event) {
+               xpc_type_t      type;
+
+               type = xpc_get_type(event);
+               if (type == XPC_TYPE_CONNECTION) {
+                       process_new_connection(event);
+
+               } else if (type == XPC_TYPE_ERROR) {
+                       const char      *desc;
+
+                       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);
+                               xpc_release(c);
+                       } else if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
+                               SCLoggerLog(S_logger, LOG_ERR, CFSTR("DNS configuration server: %s"), desc);
+                       } else {
+                               SCLoggerLog(S_logger, LOG_ERR,
+                                     CFSTR("DNS configuration server: Connection error: %d : %s"),
+                                     event,
+                                     desc);
+                       }
+
+               } else {
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("DNS configuration server: unknown event type : %x"),
+                                   type);
+
+               }
+       });
+
+       xpc_connection_resume(c);
+
+SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("XPC server \"%s\" started"), name);
 
 
-       notify_key = _dns_configuration_notify_key();
-       return _shared_infoSet_common(server, dataRef, dataLen,
-                                     audit_token, &shared_dns_info,
-                                     notify_key);
+       return;
 }
 
 
 __private_extern__
 }
 
 
 __private_extern__
-kern_return_t
-_shared_nwi_stateGet(mach_port_t server, dnsDataOut_t *dataRef, mach_msg_type_number_t *dataLen)
+_Bool
+_dns_configuration_store(dns_create_config_t *_config)
 {
 {
-       *dataRef = NULL;
-       *dataLen = 0;
+       _dns_config_buf_t       *config         = (_dns_config_buf_t *)*_config;
+       Boolean                 in_sync;
+       uint64_t                new_generation  = 0;
+       CFDataRef               new_dns_info    = NULL;
+       const char              *notify_key;
 
 
-       if (shared_nwi_state != NULL) {
-               CFIndex len;
-               Boolean ok;
+       if (config != NULL) {
+               const UInt8     *bytes;
+               CFIndex         len;
 
 
-               ok = _SCSerializeData(shared_nwi_state, (void **)dataRef, &len);
-               *dataLen = len;
-               if (!ok) {
-                       return KERN_FAILURE;
+               new_generation = config->config.generation;
+
+               if (*S_debug) {
+                       SCLoggerLog(S_logger, LOG_INFO, CFSTR("DNS configuration updated: %llu"),
+                                   new_generation);
                }
                }
+
+               bytes = (const UInt8 *)config;
+               len = sizeof(_dns_config_buf_t) + ntohl(config->n_attribute);
+
+               new_dns_info = CFDataCreate(NULL, bytes, len);
        }
 
        }
 
-       return KERN_SUCCESS;
+       dispatch_sync(_dnsinfo_server_queue(), ^{
+               _libSC_info_server_set_data(&S_dns_info, new_dns_info, new_generation);
+       });
+
+       if (new_dns_info != NULL) {
+               CFRelease(new_dns_info);
+       }
+
+       // if anyone is keeping us in sync, they now need to catch up
+       in_sync = _libSC_info_server_in_sync(&S_dns_info);
+       S_sync_handler(in_sync);
+
+       // and let everyone else know that the configuration has been updated
+       notify_key = dns_configuration_notify_key();
+       if (notify_key != NULL) {
+               uint32_t        status;
 
 
+               status = notify_post(notify_key);
+               if (status != NOTIFY_STATUS_OK) {
+                       SCLoggerLog(S_logger, LOG_ERR, CFSTR("notify_post() failed: %d"), status);
+                       // notification posting failures are non-fatal
+               }
+       }
+
+       return TRUE;
 }
 
 
 }
 
 
-__private_extern__
-kern_return_t
-_shared_nwi_stateSet(mach_port_t               server,
-                    dnsData_t                  dataRef,
-                    mach_msg_type_number_t     dataLen,
-                    audit_token_t              audit_token)
-{
-       const char      *notify_key;
+#pragma mark -
+#pragma mark Testing
+
 
 
-       notify_key = nwi_state_get_notify_key();
+#ifdef  MAIN
 
 
-       return _shared_infoSet_common(server, dataRef, dataLen,
-                                     audit_token, &shared_nwi_state,
-                                     notify_key);
+int
+main(int argc, char **argv)
+{
+       static Boolean verbose = (argc > 1) ? TRUE : FALSE;
+//     _sc_log     = FALSE;
+       _sc_verbose = (argc > 1) ? TRUE : FALSE;
+       _sc_debug   = TRUE;
+
+       load_DNSConfiguration(CFBundleGetMainBundle(),          // bundle
+                             NULL,                             //SCLogger
+                             &verbose,                         // bundleVerbose
+                             ^(Boolean inSync) {               // sync handler
+                                     SCLoggerLog(NULL, LOG_INFO,
+                                           CFSTR("in sync: %s"),
+                                           inSync ? "Yes" : "No")
+                             });
+       CFRunLoopRun();
+       /* not reached */
+       exit(0);
+       return 0;
 }
 }
+
+#endif  /* MAIN */
index 7483a3e41657934a71fd59b4cd2e8f275e0dce18..53b7779d4d043c53b8f3399595147d4e6a7c074f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004, 2005, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2005, 2009, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define _S_DNSINFO_SERVER_H
 
 #include <sys/cdefs.h>
 #define _S_DNSINFO_SERVER_H
 
 #include <sys/cdefs.h>
+#include <stdbool.h>
 #include <mach/mach.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <mach/mach.h>
 #include <CoreFoundation/CoreFoundation.h>
+#include <dispatch/dispatch.h>
 
 
-#include "shared_dns_info_types.h"
+#include "dnsinfo_create.h"
+
+typedef void (^_dns_sync_handler_t)(Boolean inSync);
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
-__private_extern__
-kern_return_t  _shared_dns_infoGet     (mach_port_t            server,
-                                        dnsDataOut_t           *dataRef,
-                                        mach_msg_type_number_t *dataLen);
-
-__private_extern__
-kern_return_t  _shared_dns_infoSet     (mach_port_t            server,
-                                        dnsData_t              dataRef,
-                                        mach_msg_type_number_t dataLen,
-                                        audit_token_t          audit_token);
-
-__private_extern__
-kern_return_t  _shared_nwi_stateGet    (mach_port_t            server,
-                                        dnsDataOut_t           *dataRef,
-                                        mach_msg_type_number_t *dataLen);
-
-__private_extern__
-kern_return_t  _shared_nwi_stateSet    (mach_port_t            server,
-                                        dnsData_t              dataRef,
-                                        mach_msg_type_number_t dataLen,
-                                        audit_token_t          audit_token);
+void
+load_DNSConfiguration                  (CFBundleRef            bundle,
+                                        SCLoggerRef            logger,
+                                        Boolean                *bundleVerbose,
+                                        _dns_sync_handler_t    syncHandler);
+
+_Bool
+_dns_configuration_store               (dns_create_config_t    *_config);
 
 __END_DECLS
 
 
 __END_DECLS
 
diff --git a/dnsinfo/shared_dns_info.defs b/dnsinfo/shared_dns_info.defs
deleted file mode 100644 (file)
index 4a24c43..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, 2005, 2009, 2011 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
- *
- * February 9, 2004            Allan Nathanson <ajn@apple.com>
- * - initial revision
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-subsystem shared_dns_info 21000;
-serverprefix _;
-
-import "shared_dns_info_types.h";
-
-/*
- * DNS configuration (client->server)
- */
-type dnsData    = ^ array [] of MACH_MSG_TYPE_BYTE
-       ctype : dnsData_t;
-
-/*
- * DNS configuration (server->client)
- */
-type dnsDataOut = ^ array [] of MACH_MSG_TYPE_BYTE
-       ctype : dnsDataOut_t;
-
-/*
- * DNS configuration API's
- */
-
-routine shared_dns_infoGet     (       server          : mach_port_t;
-                                out    data            : dnsDataOut, dealloc);
-
-#ifndef        LIBDNSINFO_A
-routine shared_dns_infoSet     (       server          : mach_port_t;
-                                       data            : dnsData;
-                   ServerAuditToken    audit_token     : audit_token_t);
-#else  // LIBDNSINFO_A
-       skip;           /* shared_dns_infoSet */
-#endif // LIBDNSINFO_A
-
-routine shared_nwi_stateGet     (      server          : mach_port_t;
-                               out     data            : dnsDataOut, dealloc);
-
-#ifndef LIBDNSINFO_A
-routine shared_nwi_stateSet    (       server          : mach_port_t;
-                               data                    : dnsData;
-                   ServerAuditToken    audit_token     : audit_token_t);
-#else   // LIBDNSINFO_A
-       skip;           /* shared_nwi_stateSet */
-#endif  // LIBDNSINFO_A
-
diff --git a/dnsinfo/shared_dns_info_types.h b/dnsinfo/shared_dns_info_types.h
deleted file mode 100644 (file)
index 780cf77..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2004, 2007 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 _SHARED_DNS_INFO_TYPES_H
-#define _SHARED_DNS_INFO_TYPES_H
-
-/*
- * Keep IPC functions private to the framework
- */
-#ifdef mig_external
-#undef mig_external
-#endif
-#define mig_external __private_extern__
-
-/* Turn MIG type checking on by default */
-#ifdef __MigTypeCheck
-#undef __MigTypeCheck
-#endif
-#define __MigTypeCheck 1
-
-/*
- * Mach server port name
- */
-#define DNS_SERVER     "com.apple.SystemConfiguration.configd"
-
-/*
- * Input arguments: DNS configuration
- *     (sent as out-of-line data in a message)
- */
-typedef const char * dnsData_t;
-
-/* Output arguments: DNS configuration
- *     (sent as out-of-line data in a message)
- */
-typedef char * dnsDataOut_t;
-
-#endif /* !_SHARED_DNS_INFO_TYPES_H */
index 818391c119f8fe8aa7f837dfce5f8b9740ee8233..a0b66a9950cabd90ee15ac8fba2b823e43841a95 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
 #!/bin/sh
-# Copyright (c) 2004-2012 Apple Inc.
+# Copyright (c) 2004-2013 Apple Inc.
 #
 # get-mobility-info
 #
 #
 # get-mobility-info
 #
@@ -13,12 +13,20 @@ if [ ${EUID} -ne 0 ]; then
        PRIV="sudo"
 fi
 
        PRIV="sudo"
 fi
 
+if [ -x /usr/bin/tail ]; then
+       TAIL_2000="/usr/bin/tail -n 2000"
+       TAIL_25000="/usr/bin/tail -n 25000"
+else
+       TAIL_2000="/bin/cat"
+       TAIL_25000="/bin/cat"
+fi
+
 OUT="mobility-info-`date +'%m.%d.%Y.%H%M%S'`"
 OUTDIR="/var/tmp"
 if [ -d ~/Desktop ]; then
        OUTDIR=~/Desktop
 elif [ "`readlink /tmp`" = "private/var/tmp" ]; then
 OUT="mobility-info-`date +'%m.%d.%Y.%H%M%S'`"
 OUTDIR="/var/tmp"
 if [ -d ~/Desktop ]; then
        OUTDIR=~/Desktop
 elif [ "`readlink /tmp`" = "private/var/tmp" ]; then
-       OUTDIR=/Library/Logs/CrashReporter/SystemConfiguration
+       OUTDIR=/Library/Logs/CrashReporter
        mkdir -p ${OUTDIR}
 fi
 
        mkdir -p ${OUTDIR}
 fi
 
@@ -50,35 +58,63 @@ echo ""
 echo "Please wait, collecting information and statistics"
 echo ""
 
 echo "Please wait, collecting information and statistics"
 echo ""
 
+#
+# Execute network reachability/DNS commands early as "mDNSResponder" will block while
+# logging its "state" info.
+#
+scutil -d -v -r www.apple.com "" no-server             > reachability-info     2>&1
+if [ -x /usr/bin/dig -a -f /etc/resolv.conf ]; then
+       /usr/bin/dig -t any -c any www.apple.com        > dig-results           2>/dev/null
+fi
+
+#
+# Signal "networkd" and "mDNSResponder" to log their "state" info. This logging will
+# continue while we execute a few other commands and should be complete by the time
+# we collect the log content.
+#
+if [ -x /usr/bin/killall ]; then
+       ${PRIV} /usr/bin/killall -INFO networkd
+       ${PRIV} /usr/bin/killall -INFO mDNSResponder
+       sleep 1
+fi
+
 #
 # processes
 #
 #
 # processes
 #
-ps axlww                                               > ps                    2>&1
+if [ -x /bin/ps ]; then
+       /bin/ps axlww                                   > ps                    2>&1
+fi
 
 #
 # network interface configuration
 #
 
 #
 # network interface configuration
 #
-ifconfig -a -L -b -m -r -v                             > ifconfig              2>&1
-if [ $? -ne 0 ]; then
-       ifconfig -a                                     > ifconfig              2>&1
+if [ -x /sbin/ifconfig ]; then
+       /sbin/ifconfig -a -L -b -m -r -v -v             > ifconfig              2>&1
+       if [ $? -ne 0 ]; then
+               /sbin/ifconfig -a                       > ifconfig              2>&1
+       fi
 fi
 
 #
 # network route configuration
 #
 fi
 
 #
 # network route configuration
 #
-netstat -n -r -a -l                                    > netstat               2>&1
+if [ -x /usr/sbin/netstat ]; then
+       /usr/sbin/netstat -n -r -a -l                   > netstat               2>&1
+fi
 
 #
 # DHCP configuration
 #
 
 #
 # DHCP configuration
 #
-for if in `ifconfig -l`
-do
-       case ${if} in
-       lo* )   ;;
-       en* )   ipconfig getpacket ${if}                > ipconfig-${if}        2>&1
-               ;;
-       esac
-done
+if [ -x /sbin/ifconfig ]; then
+       for if in `/sbin/ifconfig -l`
+       do
+               case ${if} in
+               lo* )   ;;
+               en* )   ipconfig getpacket ${if}        > ipconfig-${if}        2>&1
+                       ;;
+               esac
+       done
+fi
 
 #
 # AirPort info
 
 #
 # AirPort info
@@ -88,6 +124,22 @@ if [ -x /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport
                                                        > airport               2>&1
 fi
 
                                                        > airport               2>&1
 fi
 
+#
+# collect wifi dump
+#
+if [ -x /usr/bin/wdutil ]; then
+       ${PRIV} /usr/bin/wdutil dump
+       mkdir -p "wifi_dump"
+       /bin/ls -1 /private/tmp/wifi-*                                          2>/dev/null     \
+       | while read log
+       do
+               if [ -f "${log}" ]; then
+                       b="`basename ${log}`"
+                       ${PRIV} cat "${log}"            > "wifi_dump/${b}"      2>&1
+               fi
+       done
+fi
+
 #
 # OS info
 #
 #
 # OS info
 #
@@ -103,41 +155,34 @@ fi
 #
 # IOKit info
 #
 #
 # IOKit info
 #
-ioreg -i -l -w 0                                       >  ioreg                2>&1
-ioreg -i -l -p IODeviceTree -w 0                       >> ioreg                2>&1
+if [ -x /usr/sbin/ioreg ]; then
+       /usr/sbin/ioreg -i -l -w 0                      >  ioreg                2>&1
+       /usr/sbin/ioreg -i -l -p IODeviceTree -w 0      >> ioreg                2>&1
+fi
 
 #
 # Power Management info
 #
 
 #
 # Power Management info
 #
-echo "#"                                               >  pmset
-echo "# pmset -g"                                      >> pmset
-echo "#"                                               >> pmset
-pmset -g                                               >> pmset                2>&1
-
-echo "#"                                               >> pmset
-echo "# pmset -g ps"                                   >> pmset
-echo "#"                                               >> pmset
-pmset -g ps                                            >> pmset                2>&1
-
-echo "#"                                               >> pmset
-echo "# pmset -g assertions"                           >> pmset
-echo "#"                                               >> pmset
-pmset -g assertions                                    >> pmset                2>&1
-
-echo "#"                                               >> pmset
-echo "# pmset -g log"                                  >> pmset
-echo "#"                                               >> pmset
-pmset -g log  | tail -n 25000                          >> pmset                2>&1
+if [ -x /usr/bin/pmset ]; then
+       echo "#"                                                        >  pmset
+       echo "# pmset -g everything"                                    >> pmset
+       echo "#"                                                        >> pmset
+       /usr/bin/pmset -g everything 2>/dev/null  | ${TAIL_25000}       >> pmset
+fi
 
 #
 # Host name
 #
 
 #
 # Host name
 #
-hostname                                               > hostname              2>&1
+if [ -x /bin/hostname ]; then
+       /bin/hostname                                   > hostname              2>&1
+fi
 
 #
 # Host configuration
 #
 
 #
 # Host configuration
 #
-hostinfo                                               > hostinfo              2>&1
+if [ -x /usr/bin/hostinfo ]; then
+       /usr/bin/hostinfo                               > hostinfo              2>&1
+fi
 if [ -e /etc/hostconfig ]; then
        cat /etc/hostconfig                             > etc.hostconfig        2>&1
 fi
 if [ -e /etc/hostconfig ]; then
        cat /etc/hostconfig                             > etc.hostconfig        2>&1
 fi
@@ -152,6 +197,9 @@ fi
 if [ -e /var/run/resolv.conf ]; then
        cat /var/run/resolv.conf                        > var.run.resolv.conf   2>&1
 fi
 if [ -e /var/run/resolv.conf ]; then
        cat /var/run/resolv.conf                        > var.run.resolv.conf   2>&1
 fi
+if [ -e /etc/resolver ]; then
+       tar -c -H /etc/resolver                         > etc.resolver.tar      2>/dev/null
+fi
 
 #
 # Proxy configuration
 
 #
 # Proxy configuration
@@ -161,7 +209,20 @@ scutil -d -v --proxy                                       > proxy-configuration   2>&1
 #
 # Network information
 #
 #
 # Network information
 #
-scutil --nwi                                           > network-information   2>&1
+if [ -x /sbin/ifconfig ]; then
+       echo "#"                                        >  network-information
+       echo "# scutil --nwi"                           >> network-information
+       echo "#"                                        >> network-information
+       scutil --nwi                                    >> network-information  2>&1
+       for if in `/sbin/ifconfig -l`
+       do
+               echo ""                                 >> network-information
+               echo "#"                                >> network-information
+               echo "# scutil --nwi ${if}"             >> network-information
+               echo "#"                                >> network-information
+               scutil --nwi ${if}                      >> network-information  2>&1
+       done
+fi
 
 #
 # System / network preferences
 
 #
 # System / network preferences
@@ -185,6 +246,27 @@ do
        fi
 done
 
        fi
 done
 
+#
+# System / network preferences (from other volumes)
+#
+mount                                                                                  \
+| awk 'BEGIN { FS= "[/ \t]+" } /^\/dev\/disk.* on \/Volumes\// { print $6 }'           \
+| while read volume
+do
+       V_PATH="/Volumes/${volume}"
+       for f in                                                                        \
+               /Library/Preferences/SystemConfiguration/Networkinterfaces.plist        \
+               /Library/Preferences/SystemConfiguration/preferences.plist              \
+
+       do
+               if [ -f "${V_PATH}/${f}" ]; then
+                       mkdir -p "OtherPreferences/${volume}"
+                       b="`basename ${f}`"
+                       cat "${V_PATH}/${f}"            > "OtherPreferences/${volume}/${b}"     2>&1
+               fi
+       done
+done
+
 #
 # InternetSharing
 #
 #
 # InternetSharing
 #
@@ -216,211 +298,154 @@ if [ -f /var/tmp/configd-reachability ]; then
        cat /var/tmp/configd-reachability               > configd-reachability          2>&1
 fi
 
        cat /var/tmp/configd-reachability               > configd-reachability          2>&1
 fi
 
-#
-# network reachability
-#
-scutil -d -v -r www.apple.com "" no-server             > reachability-info     2>&1
-if [ -x /usr/bin/dig -a -f /etc/resolv.conf ]; then
-       /usr/bin/dig -t any -c any www.apple.com        > dig-results           2>/dev/null
-fi
-
 #
 # mounted filesystems
 #
 mount                                                  > mounted-filesystems   2>&1
 
 #
 # mounted filesystems
 #
 mount                                                  > mounted-filesystems   2>&1
 
-#
-# mDNSResponder, networkd info
-#
-if [ -x /usr/bin/killall ]; then
-       ${PRIV} killall -INFO mDNSResponder
-       ${PRIV} killall -INFO networkd
-
-       # and wait a short amount of time for mDNSResponder
-       # to actually log the requested information
-       sleep 15
-fi
-
-#
-# awacsd info
-#
-if [ -x /usr/sbin/awacsd -a -x /usr/bin/killall ]; then
-       ${PRIV} killall -INFO awacsd                                    2>/dev/null
-
-       # and wait a short amount of time for awacsd
-       # to actually log the requested information
-       sleep 1
-fi
-
-#
-# system log, kernel.log, early boot log messages
-#
-if [ -x /usr/bin/syslog ]; then
-       # save the recent activity
-       ${PRIV} syslog | tail -n 25000                                  > syslog
-
-       # save just the "kernel" activity (in case some of the
-       # interesting/relevant message are before the messages
-       # captured above.
-       ${PRIV} syslog -k Facility kern | tail -n 25000                 > kernel
-
-       if [ -d /var/log/DiagnosticMessages ]; then
-               # save any MessageTracer activity
-               ${PRIV} syslog  -d /var/log/DiagnosticMessages  \
-                               -F raw                          \
-                               -T local                        \
-                       | tail -n 25000                                 > DiagnosticMessages
-       fi
-else
-       if [ -f /var/log/system.log ]; then
-               ${PRIV} tail -n 25000 /var/log/system.log               > system.log
-       fi
-       if [ -f /var/log/kernel.log ]; then
-               ${PRIV} tail -n 25000 /var/log/kernel.log               > kernel.log
-       fi
-fi
-${PRIV} dmesg                                                          > dmesg
-
-#
-# IPConfiguration log
-#
-if [ -f /var/log/com.apple.IPConfiguration.bootp ]; then
-       ${PRIV} tail -n 2000 /var/log/com.apple.IPConfiguration.bootp   \
-                                                       > com.apple.IPConfiguration.bootp
-fi
-
-#
-# ppp log file(s)
-#
-scutil <<_END_OF_INPUT                         \
-| awk -F' *: *'                                        \
-    '                                          \
-     /Logfile : / {                            \
-       if (index($2, "/") == 1) { print $2 }   \
-       else { print "/var/log/ppp/" $2 }       \
-     }                                         \
-     END {                                     \
-       print "/tmp/pppotcp.log"                        \
-     }                                         \
-    '                                          \
-| sort -u                                      \
-| while read logFile
-open
-show Setup:/Network/Service/[^/]+/PPP pattern
-quit
-_END_OF_INPUT
-do
-       if [ -f "${logFile}" ]; then
-               b="`basename ${logFile}`"
-               cat "${logFile}"                        > "${b}"                2>&1
-       fi
-done
-
-#
-# application firewall log
-#
-if [ -f /var/log/appfirewall.log ]; then
-       ${PRIV} tail -n 2000 /var/log/appfirewall.log   > appfirewall.log
-fi
+${PRIV} cat /etc/hosts                                         > etc.hosts             2>/dev/null
 
 #
 # kernel extensions statistic
 #
 if   [ -x /usr/sbin/kextstat ]; then
 
 #
 # kernel extensions statistic
 #
 if   [ -x /usr/sbin/kextstat ]; then
-       kextstat                                        > kextstat              2>&1
+       /usr/sbin/kextstat                              > kextstat              2>&1
 elif [ -x /usr/sbin/kmodstat ]; then
 elif [ -x /usr/sbin/kmodstat ]; then
-       kmodstat                                        > kmodstat              2>&1
+       /usr/sbin/kmodstat                              > kmodstat              2>&1
 fi
 
 #
 # network statistics
 #
 fi
 
 #
 # network statistics
 #
-echo "#"                                               >  network-statistics
-echo "# arp -n -a"                                     >> network-statistics
-echo "#"                                               >> network-statistics
-arp -n -a                                              >> network-statistics   2>&1
-
-echo "#"                                               >> network-statistics
-echo "# netstat -n -a -A"                              >> network-statistics
-echo "#"                                               >> network-statistics
-netstat -n -a -A                                       >> network-statistics   2>&1
-
-echo "#"                                               >> network-statistics
-echo "# netstat -s"                                    >> network-statistics
-echo "#"                                               >> network-statistics
-netstat -s                                             >> network-statistics   2>&1
-
-echo "#"                                               >> network-statistics
-echo "# netstat -mmm"                                  >> network-statistics
-echo "#"                                               >> network-statistics
-netstat -mmm                                           >> network-statistics   2>&1
-
-echo "#"                                               >> network-statistics
-echo "# netstat -i -n -d"                              >> network-statistics
-echo "#"                                               >> network-statistics
-netstat -i -n -d                                       >> network-statistics   2>&1
-
-echo "#"                                               >> network-statistics
-echo "# netstat -g -n -s"                              >> network-statistics
-echo "#"                                               >> network-statistics
-netstat -g -n -s                                       >> network-statistics   2>&1
+echo -n ""                                                     >  network-statistics
+
+if   [ -x /usr/sbin/arp ]; then
+       echo "#"                                                >> network-statistics
+       echo "# arp -n -a"                                      >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/arp -n -a                                     >> network-statistics   2>&1
+fi
+
+if [ -x /usr/sbin/netstat ]; then
+       echo "#"                                                >> network-statistics
+       echo "# netstat -n -a -A"                               >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -n -a -A                              >> network-statistics   2>&1
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -s"                                     >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -s                                    >> network-statistics   2>&1
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -mmm"                                   >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -mmm                                  >> network-statistics   2>&1
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -i -n -d"                               >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -i -n -d                              >> network-statistics   2>&1
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -g -n -s"                               >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -g -n -s                              >> network-statistics   2>&1
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -i -x R"                                >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -i -x R                               >> network-statistics   2>&1
+       echo "#"                                                >> network-statistics
+
+       echo "# netstat -a -n -p mptcp"                         >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -a -n -p mptcp                        >> network-statistics   2>/dev/null
+
+       echo "#"                                                >> network-statistics
+       echo "# netstat -s -p mptcp"                            >> network-statistics
+       echo "#"                                                >> network-statistics
+       /usr/sbin/netstat -s -p mptcp                           >> network-statistics   2>/dev/null
+
+       if [ -x /sbin/ifconfig ]; then
+               for if in `/sbin/ifconfig -l`
+               do
+                       `/sbin/ifconfig -v ${if} | grep -q TXSTART`
+                       if [ $? -eq 0 ]; then
+                               echo "#"                        >> network-statistics
+                               echo "# netstat -qq -I ${if}"   >> network-statistics
+                               echo "#"                        >> network-statistics
+                               /usr/sbin/netstat -qq -I ${if}  >> network-statistics   2>&1
+                       fi
+                       `/sbin/ifconfig -v ${if} | grep -q RXPOLL`
+                       if [ $? -eq 0 ]; then
+                               echo "#"                        >> network-statistics
+                               echo "# netstat -Q -I ${if}"    >> network-statistics
+                               echo "#"                        >> network-statistics
+                               /usr/sbin/netstat -Q -I ${if}   >> network-statistics   2>&1
+                       fi
+               done
+       fi
+fi
 
 if [ -x /usr/sbin/ndp ]; then
        echo "#"                                        >> network-statistics
        echo "# ndp -n -a"                              >> network-statistics
        echo "#"                                        >> network-statistics
 
 if [ -x /usr/sbin/ndp ]; then
        echo "#"                                        >> network-statistics
        echo "# ndp -n -a"                              >> network-statistics
        echo "#"                                        >> network-statistics
-       ndp -n -a                                       >> network-statistics   2>&1
+       /usr/sbin/ndp -n -a                             >> network-statistics   2>&1
 
        echo "#"                                        >> network-statistics
        echo "# ndp -n -p"                              >> network-statistics
        echo "#"                                        >> network-statistics
 
        echo "#"                                        >> network-statistics
        echo "# ndp -n -p"                              >> network-statistics
        echo "#"                                        >> network-statistics
-       ndp -n -p                                       >> network-statistics   2>&1
+       /usr/sbin/ndp -n -p                             >> network-statistics   2>&1
 
        echo "#"                                        >> network-statistics
        echo "# ndp -n -r"                              >> network-statistics
        echo "#"                                        >> network-statistics
 
        echo "#"                                        >> network-statistics
        echo "# ndp -n -r"                              >> network-statistics
        echo "#"                                        >> network-statistics
-       ndp -n -r                                       >> network-statistics   2>&1
+       /usr/sbin/ndp -n -r                             >> network-statistics   2>&1
 
 
-       for if in `ifconfig -l`
-       do
-               echo "#"                                >> network-statistics
-               echo "# ndp -i ${if}"                   >> network-statistics
-               echo "#"                                >> network-statistics
-               ndp -i ${if}                            >> network-statistics   2>&1
-       done
+       if [ -x /sbin/ifconfig ]; then
+               for if in `/sbin/ifconfig -l`
+               do
+                       echo "#"                        >> network-statistics
+                       echo "# ndp -i ${if}"           >> network-statistics
+                       echo "#"                        >> network-statistics
+                       /usr/sbin/ndp -i ${if}          >> network-statistics   2>&1
+               done
+       fi
 fi
 
 if [ -x /sbin/ipfw ]; then
        echo "#"                                        >> network-statistics
        echo "# ipfw -at show"                          >> network-statistics
        echo "#"                                        >> network-statistics
 fi
 
 if [ -x /sbin/ipfw ]; then
        echo "#"                                        >> network-statistics
        echo "# ipfw -at show"                          >> network-statistics
        echo "#"                                        >> network-statistics
-       ${PRIV} ipfw -at show                           >> network-statistics   2>&1
+       ${PRIV} /sbin/ipfw -at show                     >> network-statistics   2>&1
 fi
 
 if [ -x /sbin/ip6fw ]; then
        echo "#"                                        >> network-statistics
 fi
 
 if [ -x /sbin/ip6fw ]; then
        echo "#"                                        >> network-statistics
-       echo "# ip6fw -at show"                 >> network-statistics
+       echo "# ip6fw -at show"                         >> network-statistics
        echo "#"                                        >> network-statistics
        echo "#"                                        >> network-statistics
-       ${PRIV} ip6fw -at show                          >> network-statistics   2>&1
+       ${PRIV} /sbin/ip6fw -at show                    >> network-statistics   2>&1
 fi
 
 if [ -x /sbin/pfctl ]; then
        echo "#"                                        >  pf
        echo "# pfctl -s all"                           >> pf
        echo "#"                                        >> pf
 fi
 
 if [ -x /sbin/pfctl ]; then
        echo "#"                                        >  pf
        echo "# pfctl -s all"                           >> pf
        echo "#"                                        >> pf
-       ${PRIV} pfctl -s all                            >> pf                   2>&1
+       ${PRIV} /sbin/pfctl -s all                      >> pf                   2>&1
        echo "=============================="           >> pf
        echo "#"                                        >> pf
        echo "# pfctl -s References"                    >> pf
        echo "#"                                        >> pf
        echo "=============================="           >> pf
        echo "#"                                        >> pf
        echo "# pfctl -s References"                    >> pf
        echo "#"                                        >> pf
-       ${PRIV} pfctl -s References                     >> pf                   2>&1
+       ${PRIV} /sbin/pfctl -s References               >> pf                   2>&1
        for ANCHOR in `${PRIV} pfctl -s Anchors -v 2>/dev/null`
        do
                echo "=============================="   >> pf
                echo "#"                                >> pf
                echo "# pfctl -a ${ANCHOR} -s all"      >> pf
                echo "#"                                >> pf
        for ANCHOR in `${PRIV} pfctl -s Anchors -v 2>/dev/null`
        do
                echo "=============================="   >> pf
                echo "#"                                >> pf
                echo "# pfctl -a ${ANCHOR} -s all"      >> pf
                echo "#"                                >> pf
-               ${PRIV} pfctl -a ${ANCHOR} -s all       >> pf                   2>&1
+               ${PRIV} /sbin/pfctl -a ${ANCHOR} -s all >> pf                   2>&1
        done
 fi
 
        done
 fi
 
@@ -428,7 +453,7 @@ if [ -x /usr/sbin/lsof ]; then
        echo "#"                                        >> network-statistics
        echo "# lsof -i -U -n -P"                       >> network-statistics
        echo "#"                                        >> network-statistics
        echo "#"                                        >> network-statistics
        echo "# lsof -i -U -n -P"                       >> network-statistics
        echo "#"                                        >> network-statistics
-       ${PRIV} lsof -i -U -n -P                        >> network-statistics   2>&1
+       ${PRIV} /usr/sbin/lsof -i -U -n -P              >> network-statistics   2>&1
 fi
 
 #
 fi
 
 #
@@ -438,425 +463,390 @@ if [ -x /usr/bin/odutil ]; then
        echo "#"                                        >  od-info
        echo "# odutil show all"                        >> od-info
        echo "#"                                        >> od-info
        echo "#"                                        >  od-info
        echo "# odutil show all"                        >> od-info
        echo "#"                                        >> od-info
-       ${PRIV} odutil show all                         >> od-info              2>&1
+       ${PRIV} /usr/bin/odutil show all                >> od-info              2>&1
 elif [ -x /usr/bin/dscacheutil ]; then
        echo "#"                                        >  ds-info
        echo "# dscacheutil -configuration"             >> ds-info
        echo "#"                                        >> ds-info
 elif [ -x /usr/bin/dscacheutil ]; then
        echo "#"                                        >  ds-info
        echo "# dscacheutil -configuration"             >> ds-info
        echo "#"                                        >> ds-info
-       dscacheutil -configuration                      >> ds-info              2>&1
+       /usr/bin/dscacheutil -configuration             >> ds-info              2>&1
 
        echo "#"                                        >> ds-info
        echo "# dscacheutil -statistics"                >> ds-info
        echo "#"                                        >> ds-info
 
        echo "#"                                        >> ds-info
        echo "# dscacheutil -statistics"                >> ds-info
        echo "#"                                        >> ds-info
-       dscacheutil -statistics                         >> ds-info              2>&1
+       /usr/bin/dscacheutil -statistics                >> ds-info              2>&1
 
        echo "#"                                        >> ds-info
        echo "# dscacheutil -cachedump -entries"        >> ds-info
        echo "#"                                        >> ds-info
 
        echo "#"                                        >> ds-info
        echo "# dscacheutil -cachedump -entries"        >> ds-info
        echo "#"                                        >> ds-info
-       dscacheutil -cachedump -entries                 >> ds-info              2>&1
+       /usr/bin/dscacheutil -cachedump -entries        >> ds-info              2>&1
 fi
 
 #
 # IPsec configuration
 #
 fi
 
 #
 # IPsec configuration
 #
-echo "#"                                               >  ipsec
-echo "# setkey -D"                                     >> ipsec
-echo "#"                                               >> ipsec
-${PRIV} setkey -D                                      \
-| perl -M'Digest::MD5 qw(md5_hex)' -l -n -e '
-       if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) {
-               printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
-       } else {
-               printf "%s\n", $_;
-       }
-'                                                      >> ipsec
-
-echo ""                                                        >> ipsec
-echo "#"                                               >> ipsec
-echo "# setkey -Pp -D"                                 >> ipsec
-echo "#"                                               >> ipsec
-${PRIV} setkey -Pp -D                                  >> ipsec
-
-for CF in /var/run/racoon/*.conf
-do
-       if [ ! -r "${CF}" ]; then
-               continue
-       fi
-
-       echo ""                                         >> ipsec
-       echo "#"                                        >> ipsec
-       echo "# ${CF}"                                  >> ipsec
-       echo "#"                                        >> ipsec
-       ${PRIV} cat ${CF}                               \
-       | perl -M'Digest::MD5 qw(md5_hex)' -l -n -e '
-               if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) {
+if [ -x /usr/sbin/setkey -a -x /usr/bin/perl ]; then
+       echo "#"                                                >  ipsec
+       echo "# setkey -D"                                      >> ipsec
+       echo "#"                                                >> ipsec
+       ${PRIV} /usr/sbin/setkey -D                             \
+       | /usr/bin/perl -M'Digest::MD5 qw(md5_hex)' -l -n -e '
+               if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) {
                        printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
                } else {
                        printf "%s\n", $_;
                }
                        printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
                } else {
                        printf "%s\n", $_;
                }
-       '                                               >> ipsec
-done
+       '                                                       >> ipsec
+
+       echo ""                                                 >> ipsec
+       echo "#"                                                >> ipsec
+       echo "# setkey -Pp -D"                                  >> ipsec
+       echo "#"                                                >> ipsec
+       ${PRIV} /usr/sbin/setkey -Pp -D                         >> ipsec
+
+       for CF in /var/run/racoon/*.conf
+       do
+               if [ ! -r "${CF}" ]; then
+                       continue
+               fi
+
+               echo ""                                         >> ipsec
+               echo "#"                                        >> ipsec
+               echo "# ${CF}"                                  >> ipsec
+               echo "#"                                        >> ipsec
+               ${PRIV} cat ${CF}                               \
+               | /usr/bin/perl -M'Digest::MD5 qw(md5_hex)' -l -n -e '
+                       if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) {
+                               printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
+                       } else {
+                               printf "%s\n", $_;
+                       }
+               '                                               >> ipsec
+       done
+fi
 
 #
 # Kerberos configuration
 #
 if [ -x /usr/bin/klist ]; then
        echo "#"                                        >  kerberos
 
 #
 # Kerberos configuration
 #
 if [ -x /usr/bin/klist ]; then
        echo "#"                                        >  kerberos
-       echo "# klist -e -c -A -f -a -n"                >> kerberos
+       echo "# klist --verbose --all-content"          >> kerberos
+       echo "#"                                        >> kerberos
+       klist --verbose --all-content                   >> kerberos     2>&1
+
        echo "#"                                        >> kerberos
        echo "#"                                        >> kerberos
-       ${PRIV} klist -e -c -A -f -a -n                 >> kerberos     2>&1
+       echo "# ktutil list"                            >> kerberos
+       echo "#"                                        >> kerberos
+       ${PRIV} /usr/sbin/ktutil --verbose list         >> kerberos     2>&1
 
        echo "#"                                        >> kerberos
 
        echo "#"                                        >> kerberos
-       echo "# klist -e -k -t -K"                      >> kerberos
+       echo "# gsstool list --verbose"                 >> kerberos
        echo "#"                                        >> kerberos
        echo "#"                                        >> kerberos
-       ${PRIV} klist -e -k -t -K                       >> kerberos     2>&1
+       /System/Library/PrivateFrameworks/Heimdal.framework/Helpers/gsstool list --verbose >> kerberos  2>&1
 fi
 
 #
 fi
 
 #
-# BTMM configuration
+# system profiler
 #
 #
+if [ -x /usr/sbin/system_profiler ]; then
+       system_profiler -xml    SPEthernetDataType      \
+                               SPFibreChannelDataType  \
+                               SPFireWireDataType      \
+                               SPFirewallDataType      \
+                               SPModemDataType         \
+                               SPNetworkDataType       \
+                               SPThunderboltDataType   \
+                               SPWWANDataType          \
+                               SPAirPortDataType       > system_profiler.spx   2>/dev/null
+fi
 
 
-BTMM_CLEANUP()
-{
-       rm -f .btmmfifo .btmminfo .digsync
-}
-
-BTMM_SETUP()
-{
-       BTMM_CLEANUP
-       mkfifo .btmmfifo
+#
+# system usage statistics
+#
+echo -n ""                                             > system-statistics
 
 
-       BTMMPORT=40000
-       while nc -6z ::1 "${PORT}"                      > /dev/null     2>&1
-       do
-               BTMMPORT=$((PORT + 1))
-       done
-}
+if [ -x /usr/bin/uptime ]; then
+       echo "#"                                        >> system-statistics
+       echo "# uptime"                                 >> system-statistics
+       echo "#"                                        >> system-statistics
+       /usr/bin/uptime                                 >> system-statistics    2>&1
+fi
 
 
-BTMM_CHECKMACDOTCOM()
-{
-       TAIL=`echo "${1}" | cut -d. -f2-`
-       if [ "${TAIL}" = "members.mac.com" ]; then
-               return 0
-       fi
+if [ -x /usr/sbin/sysctl ]; then
+       echo "#"                                        >> system-statistics
+       echo "# sysctl -a"                              >> system-statistics
+       echo "#"                                        >> system-statistics
+       /usr/sbin/sysctl -a                             >> system-statistics    2>&1
+fi
 
 
-       return 1
-}
+if [ -x /usr/bin/zprint ]; then
+       echo "#"                                        >> system-statistics
+       echo "# zprint"                                 >> system-statistics
+       echo "#"                                        >> system-statistics
+       ${PRIV} /usr/bin/zprint                         >> system-statistics    2>&1
+fi
 
 
-# get DNS info
-# params: QUERYNAME QUERYTYPE
-BTMM_DIG()
+#
+# collect executable and plugin info
+#
+report_binary_info()
 {
 {
-       rm -f .digsync
+    if [ ! -f ${1} ]; then
+       return
+    fi
 
 
-       nc -6 -l "${BTMMPORT}" < .btmmfifo                      \
-       | openssl s_client      -connect "${HOSTPORT}" -quiet   > .btmmfifo     2>.digsync &
+    VERSION=`what ${1}`
+    echo "${VERSION}"                                  >> versions     2>&1
 
 
-       N_RETRY=0
-       while [ $N_RETRY -lt 50 -a ! -s .digsync ]
-       do
-               N_RETRY=$((N_RETRY + 1))
-               sleep 0.1
-       done
+    SUM=`sum ${1}`
+    echo "\tsum: ${SUM}"                               >> versions     2>&1
 
 
-       dig @::1        -p "${BTMMPORT}"                \
-                       -y "${TSIG}"                    \
-                       +short                          \
-                       +tcp                            \
-                       "${1}" "${2}"                   2>/dev/null
+    LSINFO=`ls -lu ${1}`
+    echo "\tadditional info: ${LSINFO}"                        >> versions     2>&1
 
 
-       wait %1
+    echo ""                                            >> versions     2>&1
 }
 
 }
 
-# get the unique identifier used to lookup the keychain item for a zone
-# params: ZONE
-BTMM_UNIQUEIDFROMZONE()
+get_binary_info()
 {
 {
-       BTMM_CHECKMACDOTCOM "${1}"
-       if [ $? -eq 0 ]; then
-               echo "dns:${1}"
-       else
-               echo "btmmdns:${1}"
-       fi
-}
+    for BIN in                                                                         \
+       /usr/libexec/bootpd                                                             \
+       /usr/libexec/configd                                                            \
+       /usr/sbin/mDNSResponder                                                         \
+       /usr/sbin/awacsd                                                                \
+       /usr/sbin/pppd                                                                  \
+       /usr/sbin/racoon                                                                \
+       /usr/libexec/misd                                                               \
+       /usr/libexec/InternetSharing                                                    \
+       /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration    \
+
+    do
+       report_binary_info "${BIN}"
+    done
+
+    if [ -x /usr/bin/xcodebuild ]; then
+           /usr/bin/xcodebuild -showsdks                       \
+           | grep iphone                                       \
+           | awk '{print $NF}'                                 \
+           | while read IOS
+           do
+               SDKPATH="`xcrun --sdk $IOS --show-sdk-path`"
+               for BIN in                                                                              \
+                   /usr/libexec/configd_sim                                                            \
+                   /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration        \
 
 
-# get hostname, port, TSIG name and TSIG data from keychain
-# params: UNIQUEID
-BTMM_GETINFO()
-{
-       ${PRIV} security find-generic-password          \
-               -s "${1}"                               \
-               -g /Library/Keychains/System.keychain   > .btmminfo     2>/dev/null
-       ${PRIV} security find-generic-password          \
-               -s "${1}"                               \
-               -g /Library/Keychains/System.keychain   \
-               2>&1 > /dev/null                        \
-       | sed -n 's/^password: \"\(.*\)\"$/\1/p'
+               do
+                   report_binary_info "${SDKPATH}${BIN}"
+               done
+           done
+    fi
 }
 
 }
 
-# params: ZONE
-BTMM_URLISH()
+get_plugins_info()
 {
 {
-       BTMM_CHECKMACDOTCOM "${1}"
-       if [ $? -eq 0 ]; then
-               echo "pm-members.mac.com.:443"
-       else
-               cat .btmminfo | sed -n 's/.*0x00000007 <blob>=\"\(.*\)\"/\1/p'
+    num=0
+    cd ${ROOT}/System/Library/SystemConfiguration
+    for PLUGIN in *.bundle
+    do
+       plugins[$num]=$PLUGIN
+       num=$(( $num + 1 ))
+    done
+
+    cd "${WORKDIR}"
+
+    for PLUGIN in "${plugins[@]}"
+    do
+       PLUGIN_DIR="${ROOT}/System/Library/SystemConfiguration/${PLUGIN}"
+       PLUGIN_INF=${PLUGIN_DIR}/Contents/Info.plist
+       if [ ! -f ${PLUGIN_INF} ]; then
+           PLUGIN_INF=${PLUGIN_DIR}/Info.plist
+           if [ ! -f ${PLUGIN_INF} ]; then
+               echo "${PLUGIN_INF}: No Info.plist"             >> versions             2>&1
+           fi
        fi
        fi
-}
 
 
-BTMM_RELAYINFO()
-{
-       BTMM_CHECKMACDOTCOM "${1}"
+       echo "${PLUGIN}"                                        >> versions             2>&1
+
+       ENABLED="Enabled"
+       BOOL=`scutil --get ${PLUGIN_INF} / Enabled                                      2>/dev/null`
        if [ $? -eq 0 ]; then
        if [ $? -eq 0 ]; then
-               return
+           if [ ${BOOL} = "TRUE" ]; then
+               ENABLED="Enabled*"
+           else
+               ENABLED="Disabled"
+           fi
        fi
        fi
+       echo "\t${ENABLED}"                                     >> versions             2>&1
 
 
-       SECRET=`BTMM_GETINFO "btmmrelay:${1}"`
-
-       if [ -z "${SECRET}" ]; then
-               echo "  No Relay keychain item."                >> btmm
-               return
+       VERBOSE=""
+       BOOL=`scutil --get ${PLUGIN_INF} / Verbose                                      2>/dev/null`
+       if [ $? -eq 0 ]; then
+           if [ ${BOOL} = "TRUE" ]; then
+               VERBOSE="Verbose"
+           fi
        fi
        fi
-
-       if [ `echo "${SECRET}" | wc -l` -ne 1 ]; then
-               echo "  More than one Relay keychain item."     >> btmm
-               return
+       if [ -n "${VERBOSE}" ]; then
+               echo "\t${VERBOSE}"                             >> versions             2>&1
        fi
 
        fi
 
-       URLISH=`BTMM_URLISH "${DOMAIN}"`
-       ACCOUNT=`cat .btmminfo | sed -n 's/.*\"acct\"<blob>=\"\(.*\)\"/\1/p'`
-       KEYHASH="`perl -M'Digest::SHA1 qw(sha1_hex)' -l -e '
-                       printf "[SHA1:%s]\n", sha1_hex($ARGV[0] . "\n");
-       ' ${SECRET}`"
-       echo "  RHP: ${URLISH}"                                 >> btmm
-       echo "  RAC: ${ACCOUNT}"                                >> btmm
-       echo "  RKY: ${KEYHASH}"                                >> btmm
-}
-
-BTMM_REPORTZONE()
-{
-       DOMAIN="${1}"
+       VERSION=`scutil --get ${PLUGIN_INF} / CFBundleVersion                           2>/dev/null`
+       if [ $? -eq 1 ]; then
+               VERSION=`scutil --get ${PLUGIN_INF} / CFBundleShortVersionString        2>/dev/null`
+       fi
+       echo "\tVersion: ${VERSION}"                            >> versions             2>&1
 
 
-       echo                                                    >> btmm
-       echo "${DOMAIN}"                                        >> btmm
+       if [ -f ${PLUGIN_DIR}/Contents/MacOS/${PLUGIN%.*} ]; then
+           SUM=`sum ${PLUGIN_DIR}/Contents/MacOS/${PLUGIN%.*}`
+           echo "\tsum: ${SUM}"                                >> versions             2>&1
 
 
-       DNSID=`BTMM_UNIQUEIDFROMZONE "${DOMAIN}"`
-       SECRET=`BTMM_GETINFO "${DNSID}"`
+           LSINFO=`ls -lu ${PLUGIN_DIR}/Contents/MacOS/${PLUGIN%.*}`
+           echo "\tadditional info: ${LSINFO}"                 >> versions             2>&1
+       elif [ -f ${PLUGIN_DIR}/${PLUGIN%.*} ]; then
+           SUM=`sum ${PLUGIN_DIR}/${PLUGIN%.*}`
+           echo "\tsum: ${SUM}"                                >> versions             2>&1
 
 
-       if [ -z "${SECRET}" ]; then
-               echo "  No DNS keychain item."                  >> btmm
-               return
+           LSINFO=`ls -lu ${PLUGIN_DIR}/${PLUGIN%.*}`
+           echo "\tadditional info: ${LSINFO}"                 >> versions             2>&1
        fi
 
        fi
 
-       if [ `echo "${SECRET}" | wc -l` -ne 1 ]; then
-               echo "  More than one DNS keychain item."       >> btmm
-               return
-       fi
+       echo ""                                                 >> versions             2>&1
+    done
+}
 
 
-       URLISH=`BTMM_URLISH "${DOMAIN}"`
-       HOSTPORT=`echo "${URLISH}" | cut -d@ -f2`
-       ACCOUNT=`cat .btmminfo | sed -n 's/.*\"acct\"<blob>=\"\(.*\)\"/\1/p'`
-       TSIG="${ACCOUNT}:${SECRET}"
-
-       KEYHASH="`perl -M'Digest::SHA1 qw(sha1_hex)' -l -e '
-                       printf "[SHA1:%s]\n", sha1_hex($ARGV[0] . "\n");
-               ' ${SECRET}`"
-       echo ""                                                 >> btmm
-       echo "  DHP: ${URLISH}"                                 >> btmm
-       echo "  DAC: ${ACCOUNT}"                                >> btmm
-       echo "  DKY: ${KEYHASH}"                                >> btmm
-
-       BTMM_RELAYINFO "${DOMAIN}"
-
-       REACHHOST=`echo "${HOSTPORT}" | cut -d: -f1`
-       STATUSES=`scutil -r "${REACHHOST}"`
-       for REACHSTATUS in `echo ${STATUSES} | tr -d ' ' | tr ',' ' '`; do
-               if [ "$REACHSTATUS" == "NotReachable" ] \
-                       || [ "$REACHSTATUS" == "ConnectionRequired" ]; then
-                       echo "  Skipping DNS queries, no connectivity"  >> btmm
-                       return
-               fi
-       done
+if [ -x /usr/bin/what -a -x /usr/bin/sum -a -x /bin/ls ]; then
+       get_binary_info
+       get_plugins_info
+fi
 
 
-       for TYPE in                     \
-               _afpovertcp._tcp        \
-               _airport._tcp           \
-               _adisk._tcp             \
-               _http._tcp              \
-               _rfb._tcp               \
-               _smb._tcp               \
-               _ssh._tcp
-       do
-               BTMM_DIG "${TYPE}.${DOMAIN}" ptr        \
-               | while read -r REG
-               do
-                       echo ""                                 >> btmm
-                       /bin/echo "  ${REG}"                    >> btmm
-                       echo ""                                 >> btmm
-
-                       INF_Q=`/bin/echo "${REG}" | sed -e "s/${TYPE}/_device-info._tcp/"`
-                       INF=`BTMM_DIG "${INF_Q}" txt`
-                       echo "    INF: ${INF}"                  >> btmm
-
-                       SRV=`BTMM_DIG ${REG} srv`
-                       SRV1=`/bin/echo "${SRV}" | head -1`
-                       echo "    SRV: ${SRV1}"                 >> btmm
-                       SRV2=`/bin/echo "${SRV}" | tail +2`
-                       if [ -n "${SRV2}" ]; then
-                               SRV="${SRV1}"
-                               /bin/echo "${SRV2}"             \
-                               | sed -e 's/^/  *****: /'       >> btmm
-                       fi
+#
+# Last thing is to collect the logs to give a chance for networkd and mDNSResponder
+# to finish dumping their state
+#
 
 
-                       TXT=`BTMM_DIG ${REG} txt`
-                       TXT1=`/bin/echo "${TXT}" | head -1`
-                       echo "    TXT: ${TXT1}"                 >> btmm
-                       TXT2=`/bin/echo "${TXT}" | tail +2`
-                       if [ -n "${TXT2}" ]; then
-                               /bin/echo "${TXT2}"             \
-                               | sed -e 's/^/  *****: /'       >> btmm
-                       fi
+#
+# system log, kernel.log, early boot log messages
+#
+if [ -x /usr/bin/syslog ]; then
+       # save the recent activity
+       ${PRIV} /usr/bin/syslog | ${TAIL_25000}                         > syslog
 
 
-                       HOST=`/bin/echo "${SRV}" | cut -d ' ' -f 4-`
-                       if [ -n "${HOST}" ]; then
-                               V4=`BTMM_DIG ${HOST} a`
-                               V6=`BTMM_DIG ${HOST} aaaa`
-                               KRB=`BTMM_DIG _kerberos.${HOST} txt`
-                               TUN=`BTMM_DIG _autotunnel._udp.${HOST} srv`
-                               AT6=`BTMM_DIG _autotunnel6.${HOST} aaaa`
-                       else
-                               V4=""
-                               V6=""
-                               KRB=""
-                               TUN=""
-                               AT6=""
-                       fi
-                       if [ -n "${V4}" ]; then
-                               echo "     v4: ${V4}"           >> btmm
-                       fi
-                       if [ -n "${V6}" ]; then
-                               echo "     v6: ${V6}"           >> btmm
-                       fi
-                       if [ -n "${KRB}" ]; then
-                               echo "    KRB: ${KRB}"          >> btmm
-                       fi
-                       if [ -n "${TUN}" ]; then
-                               echo "    TUN: ${TUN}"          >> btmm
-
-                               HOST=`/bin/echo "${TUN}" | cut -d ' ' -f 4-`
-                               if [ -n "${HOST}" ]; then
-                                       V4=`BTMM_DIG ${HOST} a`
-                                       V6=`BTMM_DIG ${HOST} aaaa`
-                               fi
-                               if [ -n "${V4}" ]; then
-                                       echo "     v4: ${V4}"   >> btmm
-                               fi
-                               if [ -n "${V6}" ]; then
-                                       echo "     v6: ${V6}"   >> btmm
-                               fi
-                       fi
-                       if [ -n "${AT6}" ]; then
-                               echo "    AT6: ${AT6}"          >> btmm
-                       fi
-               done
-       done
-}
+       # save just the "kernel" activity (in case some of the
+       # interesting/relevant message are before the messages
+       # captured above.
+       ${PRIV} /usr/bin/syslog -k Facility kern | ${TAIL_25000}        > kernel
 
 
-BTMM_SETUP
+       if [ -d /var/log/DiagnosticMessages ]; then
+               # save any MessageTracer activity
+               ${PRIV} /usr/bin/syslog -d /var/log/DiagnosticMessages  \
+                                       -F raw                          \
+                                       -T local                        \
+                       | ${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
+       fi
+fi
+if [ -x /sbin/dmesg ]; then
+       ${PRIV} /sbin/dmesg                                             > dmesg
+fi
 
 
-scutil <<_END_OF_INPUT \
-| sed -n 's@.* : *\(.*\)$@\1@p' \
-| sort \
-| while read DOMAIN
+#
+# IPConfiguration log
+#
+if [ -f /var/log/com.apple.IPConfiguration.bootp ]; then
+       ${PRIV} ${TAIL_2000} /var/log/com.apple.IPConfiguration.bootp   \
+                                                       > com.apple.IPConfiguration.bootp
+fi
+
+#
+# ppp log file(s)
+#
+scutil <<_END_OF_INPUT                         \
+| awk -F' *: *'                                        \
+    '                                          \
+     /Logfile : / {                            \
+       if (index($2, "/") == 1) { print $2 }   \
+       else { print "/var/log/ppp/" $2 }       \
+     }                                         \
+     END {                                     \
+       print "/tmp/pppotcp.log"                        \
+     }                                         \
+    '                                          \
+| sort -u                                      \
+| while read logFile
 open
 open
-show Setup:/Network/BackToMyMac
+show Setup:/Network/Service/[^/]+/PPP pattern
 quit
 _END_OF_INPUT
 do
 quit
 _END_OF_INPUT
 do
-       BTMM_REPORTZONE "$DOMAIN"
+       if [ -f "${logFile}" ]; then
+               b="`basename ${logFile}`"
+               cat "${logFile}"                        > "${b}"                2>&1
+       fi
 done
 
 done
 
-BTMM_CLEANUP
-
 #
 #
-# collect crash reports
+# application firewall log
 #
 #
-for daemon in                          \
-               bootpd                  \
-               configd                 \
-               eapolclient             \
-               mDNSResponder           \
-               mDNSResponderHelper     \
-               awacsd                  \
-               pppd                    \
-               racoon                  \
-               socketfilterfw          \
-               InternetSharing         \
-               SCHelper                \
-               SCMonitor               \
+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
+       #
+       for daemon in                           \
+                       bootpd                  \
+                       configd                 \
+                       eapolclient             \
+                       mDNSResponder           \
+                       mDNSResponderHelper     \
+                       awacsd                  \
+                       pppd                    \
+                       racoon                  \
+                       socketfilterfw          \
+                       InternetSharing         \
+                       SCHelper                \
+                       SCMonitor               \
 
 
-do
-       /bin/ls -1      /Library/Logs/DiagnosticReports/${daemon}_*.crash       \
-                       /Library/Logs/CrashReporter/${daemon}_*.crash           \
-                       /Library/Logs/CrashReporter/${daemon}_*.plist           \
-                       2>/dev/null                                             \
+       do
+               /bin/ls -1      /Library/Logs/DiagnosticReports/${daemon}_*.crash       \
+                               /Library/Logs/CrashReporter/${daemon}_*.crash           \
+                               /Library/Logs/CrashReporter/${daemon}_*.plist           \
+                               2>/dev/null                                             \
+               | while read log
+               do
+                       if [ -f "${log}" ]; then
+                               b="`basename ${log}`"
+                               ${PRIV} cat "${log}"            > "${b}"                2>&1
+                       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}`"
        | while read log
        do
                if [ -f "${log}" ]; then
                        b="`basename ${log}`"
-                       ${PRIV} cat "${log}"            > "${b}"                2>&1
+                       ${PRIV} cat "${log}"                    > "${b}"                2>&1
                fi
        done
                fi
        done
-done
-
-#
-# system profiler
-#
-if [ -x /usr/sbin/system_profiler ]; then
-       system_profiler -xml    SPEthernetDataType      \
-                               SPFibreChannelDataType  \
-                               SPFireWireDataType      \
-                               SPFirewallDataType      \
-                               SPModemDataType         \
-                               SPNetworkDataType       \
-                               SPThunderboltDataType   \
-                               SPWWANDataType          \
-                               SPAirPortDataType       > system_profiler.spx   2>&1
 fi
 
 fi
 
-#
-# system usage statistics
-#
-echo "#"                                               >  system-statistics
-echo "# uptime"                                                >> system-statistics
-echo "#"                                               >> system-statistics
-uptime                                                 >> system-statistics    2>&1
-
-echo "#"                                               >> system-statistics
-echo "# sysctl -a"                                     >> system-statistics
-echo "#"                                               >> system-statistics
-sysctl -a                                              >> system-statistics    2>&1
-
-echo "#"                                               >> system-statistics
-echo "# zprint"                                                >> system-statistics
-echo "#"                                               >> system-statistics
-zprint                                                 >> system-statistics    2>&1
-
-echo "#"                                               >> system-statistics
-echo "# top -l5 -s2"                                   >> system-statistics
-echo "#"                                               >> system-statistics
-top -s 2 -l 5                                          >> system-statistics    2>&1
 
 #
 # collect everything into a single archive
 #
 cd "${WORKDIR}/.."
 
 #
 # collect everything into a single archive
 #
 cd "${WORKDIR}/.."
-if [ -x /usr/bin/tar ]; then
-       tar -c ${GZ_OPT} -f "${ARCHIVE}" "${OUT}"
-else
-       pax -w ${GZ_OPT} -f "${ARCHIVE}" "${OUT}"
-fi
+tar -c ${GZ_OPT} -f "${ARCHIVE}" "${OUT}"
 rm -rf "${WORKDIR}"
 
 if [ ${UID} -eq 0 ]; then
 rm -rf "${WORKDIR}"
 
 if [ ${UID} -eq 0 ]; then
@@ -869,10 +859,3 @@ fi
 
 echo "Network data collected to \"${ARCHIVE}\""
 
 
 echo "Network data collected to \"${ARCHIVE}\""
 
-#
-# if requested, generate a crash report
-#
-if [ "${OUTDIR}" = "/Library/Logs/CrashReporter/SystemConfiguration" -a "${1}" = "CRASH" ]; then
-       kill -ABRT $$
-fi
-
diff --git a/libSystemConfiguration/libSystemConfiguration_client.c b/libSystemConfiguration/libSystemConfiguration_client.c
new file mode 100644 (file)
index 0000000..5023329
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012, 2013 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 <Availability.h>
+#include <TargetConditionals.h>
+#include <asl.h>
+#include <dispatch/dispatch.h>
+#include <vproc.h>
+#include <vproc_priv.h>
+#include <xpc/xpc.h>
+
+#include "libSystemConfiguration_client.h"
+
+
+#pragma mark -
+#pragma mark libSC fork handlers
+
+
+__attribute__((weak_import)) bool _dispatch_is_multithreaded(void);
+
+static boolean_t _has_forked = FALSE;
+
+// These functions are registered with libSystem to
+// handle pthread_atfork callbacks.
+
+void
+_libSC_info_fork_prepare()
+{
+       return;
+}
+
+void
+_libSC_info_fork_parent()
+{
+       return;
+}
+
+void
+_libSC_info_fork_child()
+{
+       if (_dispatch_is_multithreaded()) {
+               // if dispatch was active before fork
+               _has_forked = TRUE;
+       }
+
+       return;
+}
+
+
+#pragma mark -
+#pragma mark Support functions
+
+
+static void
+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);
+       free(desc);
+}
+
+
+__private_extern__
+libSC_info_client_t *
+libSC_info_client_create(dispatch_queue_t      q,
+                        const char             *service_name,
+                        const char             *service_description)
+{
+       xpc_connection_t        c;
+       libSC_info_client_t     *client;
+#if    !TARGET_IPHONE_SIMULATOR
+       const uint64_t          flags   =       XPC_CONNECTION_MACH_SERVICE_PRIVILEGED;
+#else  // !TARGET_IPHONE_SIMULATOR
+       const uint64_t          flags   =       0;
+#endif // !TARGET_IPHONE_SIMULATOR
+
+       if (_has_forked) {
+               return NULL;
+       }
+
+       client = malloc(sizeof(libSC_info_client_t));
+       client->active = TRUE;
+       client->service_description = strdup(service_description);
+       client->service_name = strdup(service_name);
+
+       c = xpc_connection_create_mach_service(service_name, q, flags);
+
+       xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) {
+               xpc_type_t      type;
+
+               type = xpc_get_type(xobj);
+               if (type == XPC_TYPE_DICTIONARY) {
+                       asl_log(NULL, NULL, ASL_LEVEL_ERR, "%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);
+                               client->active = FALSE;
+                       } else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) {
+                               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%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);
+                       }
+
+               } else {
+                       asl_log(NULL, NULL, ASL_LEVEL_ERR,
+                               "%s: unknown event type : %p",
+                               client->service_name,
+                               type);
+               }
+       });
+
+       client->connection = c;
+
+       xpc_connection_resume(c);
+
+       return client;
+}
+
+
+__private_extern__
+void
+libSC_info_client_release(libSC_info_client_t *client)
+{
+       xpc_release(client->connection);
+       free(client->service_description);
+       free(client->service_name);
+       free(client);
+}
+
+
+__private_extern__
+xpc_object_t
+libSC_send_message_with_reply_sync(libSC_info_client_t *client,
+                                  xpc_object_t         message)
+{
+       xpc_object_t    reply;
+
+       while (TRUE) {
+               // send request to the DNS configuration server
+               reply = xpc_connection_send_message_with_reply_sync(client->connection, message);
+               if (reply != NULL) {
+                       xpc_type_t      type;
+
+                       type = xpc_get_type(reply);
+                       if (type == XPC_TYPE_DICTIONARY) {
+                               // reply available
+                               break;
+                       }
+
+                       if ((type == XPC_TYPE_ERROR) && (reply == XPC_ERROR_CONNECTION_INTERRUPTED)) {
+                               asl_log(NULL, NULL, ASL_LEVEL_DEBUG,
+                                       "%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);
+                               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);
+                               log_xpc_object("  reply", reply);
+                       }
+
+                       xpc_release(reply);
+                       reply = NULL;
+                       break;
+               }
+       }
+
+       return reply;
+}
diff --git a/libSystemConfiguration/libSystemConfiguration_client.h b/libSystemConfiguration/libSystemConfiguration_client.h
new file mode 100644 (file)
index 0000000..c93d477
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, 2013 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 _LIBSYSTEMCONFIGURATION_CLIENT_H
+#define _LIBSYSTEMCONFIGURATION_CLIENT_H
+
+#include <Availability.h>
+#include <TargetConditionals.h>
+#include <sys/cdefs.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+
+// ------------------------------------------------------------
+
+#pragma mark -
+#pragma mark [XPC] DNS configuration server
+
+#define        DNSINFO_SERVER_VERSION          20130408
+
+#if    !TARGET_IPHONE_SIMULATOR
+#define        DNSINFO_SERVICE_NAME            "com.apple.SystemConfiguration.DNSConfiguration"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define        DNSINFO_SERVICE_NAME            "com.apple.SystemConfiguration.DNSConfiguration_sim"
+#endif // !TARGET_IPHONE_SIMULATOR
+
+#define        DNSINFO_PROC_NAME               "proc_name"     // string
+
+#define        DNSINFO_REQUEST                 "request_op"    // int64
+
+enum {
+       DNSINFO_REQUEST_COPY            = 0x10001,
+       DNSINFO_REQUEST_ACKNOWLEDGE,
+};
+
+#define        DNSINFO_CONFIGURATION           "configuration" // data
+#define        DNSINFO_GENERATION              "generation"    // uint64
+
+// ------------------------------------------------------------
+
+#pragma mark -
+#pragma mark [XPC] Network information (nwi) server
+
+#define        NWI_SERVER_VERSION              20130408
+
+#if    !TARGET_IPHONE_SIMULATOR
+#define        NWI_SERVICE_NAME                "com.apple.SystemConfiguration.NetworkInformation"
+#else  // !TARGET_IPHONE_SIMULATOR
+#define        NWI_SERVICE_NAME                "com.apple.SystemConfiguration.NetworkInformation_sim"
+#endif // !TARGET_IPHONE_SIMULATOR
+
+#define        NWI_PROC_NAME                   "proc_name"     // string
+
+#define        NWI_REQUEST                     "request_op"    // int64
+
+enum {
+       NWI_REQUEST_COPY                = 0x20001,
+       NWI_REQUEST_ACKNOWLEDGE,
+};
+
+#define        NWI_CONFIGURATION               "configuration" // data
+#define        NWI_GENERATION                  "generation"    // uint64
+
+// ------------------------------------------------------------
+
+typedef struct {
+       _Bool                   active;
+       xpc_connection_t        connection;
+       char                    *service_description;
+       char                    *service_name;
+} libSC_info_client_t;
+
+// ------------------------------------------------------------
+
+__BEGIN_DECLS
+
+libSC_info_client_t *
+libSC_info_client_create               (
+                                        dispatch_queue_t       q,
+                                        const char             *service_name,
+                                        const char             *service_description
+                                       );
+
+void
+libSC_info_client_release              (
+                                        libSC_info_client_t    *client
+                                       );
+
+xpc_object_t
+libSC_send_message_with_reply_sync     (
+                                        libSC_info_client_t    *client,
+                                        xpc_object_t           message
+                                       );
+
+__END_DECLS
+
+#endif // _LIBSYSTEMCONFIGURATION_CLIENT_H
diff --git a/libSystemConfiguration/libSystemConfiguration_server.c b/libSystemConfiguration/libSystemConfiguration_server.c
new file mode 100644 (file)
index 0000000..82a201a
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2012, 2013 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 <Availability.h>
+#include <TargetConditionals.h>
+#include <asl.h>
+#include <dispatch/dispatch.h>
+#include <vproc.h>
+#include <vproc_priv.h>
+#include <xpc/xpc.h>
+#include <xpc/private.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCPrivate.h>
+
+#include "libSystemConfiguration_server.h"
+
+#define kTrailingEdgeAgentEntitlement "com.apple.SystemConfiguration.trailing-edge-agent"
+
+#pragma mark -
+#pragma mark Support functions
+
+
+//__private_extern__ void
+//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);
+//     free(desc);
+//}
+
+
+#pragma mark -
+#pragma mark client connection trackng
+
+
+typedef struct {
+       xpc_connection_t        connection;
+} client_key_t;
+
+typedef struct {
+       pid_t                   pid;
+       uint64_t                generation_pushed;
+       uint64_t                generation_acknowledged;
+} client_val_t;
+
+
+static __inline__ CF_RETURNS_RETAINED CFDataRef
+_client_key(xpc_connection_t c)
+{
+       client_key_t    key;
+       CFDataRef       client_key;
+
+       key.connection = c;
+       client_key = CFDataCreate(NULL, (UInt8 *)&key, sizeof(key));
+       return client_key;
+}
+
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+static void
+_handle_entitlement_check_failure(pid_t pid)
+{
+       static Boolean                  cleanupScheduled        = FALSE;
+       static dispatch_once_t          initializer             = 0;
+       static CFMutableArrayRef        pids                    = NULL;
+       static dispatch_queue_t         queue                   = NULL;
+
+       dispatch_once(&initializer, ^{
+               pids = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+               queue = dispatch_queue_create("handle unentitled ack", NULL);
+       });
+
+       dispatch_sync(queue, ^{
+               CFNumberRef     pidNumber       = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
+
+               if (!CFArrayContainsValue(pids, CFRangeMake(0, CFArrayGetCount(pids)), pidNumber)) {
+                       CFArrayAppendValue(pids, pidNumber);
+
+                       SCLog(TRUE, LOG_ERR, CFSTR("DNS/nwi dropping ack w/no entitlement, pid = %d"), pid);
+
+                       if (!cleanupScheduled) {
+                               cleanupScheduled = TRUE;
+                               dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 180LL * NSEC_PER_SEC), queue, ^{
+                                       CFArrayRemoveAllValues(pids);
+                                       cleanupScheduled = FALSE;
+                               });
+                       }
+               }
+
+               CFRelease(pidNumber);
+       });
+}
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+
+/*
+ * libSystemConfiguraiton_client
+ *
+ * - all APIs must be called from the same [serial] dispatch queue
+ */
+
+
+__private_extern__
+void
+_libSC_info_server_init(libSC_info_server_t *server_info) {
+       bzero(server_info, sizeof(*server_info));
+       server_info->info = CFDictionaryCreateMutable(NULL,
+                                                     0,
+                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                     &kCFTypeDictionaryValueCallBacks);
+       return;
+}
+
+
+__private_extern__
+void
+_libSC_info_server_set_data(libSC_info_server_t        *server_info,
+                           CFDataRef           data,
+                           uint64_t            generation)
+{
+       // update stored configuration
+       if (server_info->data != NULL) {
+               CFRelease(server_info->data);
+               server_info->data = NULL;
+       }
+       if (data != NULL) {
+               CFRetain(data);
+               server_info->data = data;
+       }
+
+       // update generation
+       if (generation == 0) {
+               // generation must be non-zero
+               generation = 1;
+       }
+       server_info->generation = generation;
+
+       // new configuration, all ack'ing clients need to
+       // check-in again
+       server_info->inSync_NO += server_info->inSync_YES;
+       server_info->inSync_YES = 0;
+
+       return;
+}
+
+
+/*
+ * _libSC_info_server_in_sync
+ *
+ * Called to check if all of the "active" configuration [XPC] connection
+ * are in sync with the requested generation.
+ */
+__private_extern__
+Boolean
+_libSC_info_server_in_sync(libSC_info_server_t *server_info)
+{
+       return (server_info->inSync_NO == 0) ? TRUE : FALSE;
+}
+
+
+/*
+ * _libSC_info_server_open
+ *
+ * Called when a new configuration [XPC] connection
+ * is established.
+ *
+ * - tracks the last generation pushed to the caller and
+ *   the last generation ack'd by the caller
+ */
+__private_extern__
+void
+_libSC_info_server_open(libSC_info_server_t    *server_info,
+                       xpc_connection_t        c)
+{
+       CFDataRef       client_key;
+       CFDataRef       client_val;
+       client_val_t    val;
+
+       client_key = _client_key(c);
+
+       val.pid                     = xpc_connection_get_pid(c);
+       val.generation_pushed       = 0;
+       val.generation_acknowledged = 0;
+       client_val = CFDataCreate(NULL, (UInt8 *)&val, sizeof(val));
+
+       CFDictionarySetValue(server_info->info, client_key, client_val);
+       CFRelease(client_key);
+       CFRelease(client_val);
+
+       return;
+}
+
+
+/*
+ * _libSC_info_server_get_data
+ *
+ * Called when a [XPC] connection wants the current configuration.
+ *
+ * - updates the last generation pushed to the caller
+ */
+__private_extern__
+CFDataRef
+_libSC_info_server_get_data(libSC_info_server_t        *server_info,
+                           xpc_connection_t    c,
+                           uint64_t            *generation)
+{
+       CFDataRef       client_key;
+       CFDataRef       client_val;
+       client_val_t    *val;
+
+       // update last generation pushed to client
+       client_key = _client_key(c);
+       client_val = CFDictionaryGetValue(server_info->info, client_key);
+       CFRelease(client_key);
+
+       val = (client_val_t *)(void *)CFDataGetBytePtr(client_val);
+       val->generation_pushed = server_info->generation;
+
+       // return generation
+       *generation = server_info->generation;
+       if (*generation == 1) {
+               *generation = 0;
+       }
+
+       // return data
+       return server_info->data;
+}
+
+
+/*
+ * _libSC_info_server_acknowledged
+ *
+ * Called when a [XPC] connection wants to acknowledge a
+ * processed configuration.
+ *
+ * - updates the last generation ack'd by the caller
+ * - updates the count of [XPC] connections that are / not in sync
+ */
+__private_extern__
+Boolean
+_libSC_info_server_acknowledged(libSC_info_server_t    *server_info,
+                               xpc_connection_t        c,
+                               uint64_t                generation)
+{
+       CFDataRef       client_key;
+       CFDataRef       client_val;
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+       xpc_object_t    ent_value;
+       Boolean         entitled        = FALSE;
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+       Boolean         sync_updated    = FALSE;
+       client_val_t    *val;
+
+#if    ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+       ent_value = xpc_connection_copy_entitlement_value(c, kTrailingEdgeAgentEntitlement);
+       if (ent_value != NULL) {
+               if (xpc_get_type(ent_value) == XPC_TYPE_BOOL) {
+                       entitled = xpc_bool_get_value(ent_value);
+               }
+               xpc_release(ent_value);
+       }
+
+       if (!entitled) {
+               _handle_entitlement_check_failure(xpc_connection_get_pid(c));
+               return FALSE;
+       }
+#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
+
+       client_key = _client_key(c);
+       client_val = CFDictionaryGetValue(server_info->info, client_key);
+       CFRelease(client_key);
+
+       val = (client_val_t *)(void *)CFDataGetBytePtr(client_val);
+
+       if (val->generation_acknowledged == 0) {
+               // if first ack
+               if (generation == server_info->generation) {
+                       server_info->inSync_YES++;
+               } else {
+                       server_info->inSync_NO++;
+                       sync_updated = TRUE;
+               }
+       } else if ((generation != val->generation_acknowledged) &&
+                   (generation == server_info->generation)) {
+               // if we've previously ack'd a configuration
+               // ... and if we are ack'ing a configuration
+               //     that we have not previously ack'd
+               // ... and if we're ack'ing the current stored
+               //     configuration
+               server_info->inSync_NO--;
+               server_info->inSync_YES++;
+               sync_updated = TRUE;
+       }
+
+       val->generation_acknowledged = generation;
+
+       return sync_updated;
+}
+
+
+/*
+ * _libSC_info_server_close
+ *
+ * Called when a configuration [XPC] connection is closed.
+ */
+__private_extern__
+Boolean
+_libSC_info_server_close(libSC_info_server_t   *server_info,
+                        xpc_connection_t       c)
+{
+       CFDataRef       client_key;
+       CFDataRef       client_val;
+       Boolean         sync_updated    = FALSE;
+
+       client_key = _client_key(c);
+
+       // get client info, remove ack'd info
+       client_val = CFDictionaryGetValue(server_info->info, client_key);
+       if (client_val != NULL) {
+               client_val_t    *val;
+
+               val = (client_val_t *)(void *)CFDataGetBytePtr(client_val);
+               if (val->generation_acknowledged > 0) {
+                       // if we've previously ack'd a configuration
+                       if (val->generation_acknowledged == server_info->generation) {
+                               // if currently in sync
+                               server_info->inSync_YES--;
+                       } else {
+                               // if currently NOT in sync
+                               server_info->inSync_NO--;
+                               sync_updated = TRUE;
+                       }
+               }
+       }
+
+       CFDictionaryRemoveValue(server_info->info, client_key);
+       CFRelease(client_key);
+
+       return sync_updated;
+}
+
diff --git a/libSystemConfiguration/libSystemConfiguration_server.h b/libSystemConfiguration/libSystemConfiguration_server.h
new file mode 100644 (file)
index 0000000..4093bb7
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012 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 _LIBSYSTEMCONFIGURATION_SERVER_H
+#define _LIBSYSTEMCONFIGURATION_SERVER_H
+
+#include <Availability.h>
+#include <TargetConditionals.h>
+#include <sys/cdefs.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+// ------------------------------------------------------------
+
+#pragma mark -
+#pragma mark [XPC] information server common code
+
+// ------------------------------------------------------------
+
+
+/*
+ * libSC_info_server_t
+ *     data (CFData)
+ *             stored configuration
+ *     generation
+ *             generation of the last stored configuration
+ *     info (CFDictionary)
+ *             key = xpc_connection_t [CFData]
+ *             val = [CFData] (process name, last push'd, last ack'd)
+ *     inSync_NO, inSync_YES
+ *             count of client connections that have ack'd a configuration that
+ *             are (or are not) in sync with the last stored generation#
+*/
+typedef struct {
+       CFDataRef               data;
+       uint64_t                generation;
+       CFMutableDictionaryRef  info;
+       int                     inSync_NO;      // ack'ing clients not in sync w/generation
+       int                     inSync_YES;     // ack'ing clients in sync w/generation
+} libSC_info_server_t;
+
+
+__BEGIN_DECLS
+
+// Global server info SPIs
+
+void
+_libSC_info_server_init                (
+                                libSC_info_server_t    *server_info
+                               );
+
+Boolean
+_libSC_info_server_in_sync     (
+                                libSC_info_server_t    *server_info
+                               );
+
+void
+_libSC_info_server_set_data    (
+                                libSC_info_server_t    *server_info,
+                                CFDataRef              data,
+                                uint64_t               generation
+                               );
+
+// Per-session server info SPIs
+
+void
+_libSC_info_server_open                (
+                                libSC_info_server_t    *server_info,
+                                xpc_connection_t       c
+                               );
+
+CFDataRef
+_libSC_info_server_get_data    (
+                                libSC_info_server_t    *server_info,
+                                xpc_connection_t       c,
+                                uint64_t               *generation
+                               );
+
+Boolean
+_libSC_info_server_acknowledged        (
+                                libSC_info_server_t    *server_info,
+                                xpc_connection_t       c,
+                                uint64_t               generation
+                               );
+
+Boolean
+_libSC_info_server_close       (
+                                libSC_info_server_t    *server_info,
+                                xpc_connection_t       c
+                               );
+
+__END_DECLS
+
+#endif // _LIBSYSTEMCONFIGURATION_SERVER_H
index 18b4c6bee2021fbf1049cfde31ea01902445fd24..4153c001740d888b1b35133e0fffa6136f83f866 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/socket.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/socket.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+
+#include "libSystemConfiguration_client.h"
 #include "network_information.h"
 #include "network_information_priv.h"
 
 #include "network_information.h"
 #include "network_information_priv.h"
 
@@ -37,8 +41,30 @@ static boolean_t     nwi_store_token_valid   = FALSE;
 static pthread_once_t  initialized             = PTHREAD_ONCE_INIT;
 static int             nwi_store_token;
 
 static pthread_once_t  initialized             = PTHREAD_ONCE_INIT;
 static int             nwi_store_token;
 
+static boolean_t       nwi_store_force_refresh = FALSE;
+
+#pragma mark -
+#pragma mark Network information [nwi] client support
+
+
+// Note: protected by __nwi_configuration_queue()
+static int                     nwi_active      = 0;
+static libSC_info_client_t     *nwi_client     = NULL;
+
+
+static dispatch_queue_t
+__nwi_configuration_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(NWI_SERVICE_NAME, NULL);
+       });
+
+       return q;
+}
 
 
-/* Private */
 static
 void
 _nwi_state_initialize(void)
 static
 void
 _nwi_state_initialize(void)
@@ -57,7 +83,7 @@ _nwi_state_initialize(void)
 
 static
 void
 
 static
 void
-nwi_set_alias(nwi_state* state, nwi_ifstate* ifstate)
+_nwi_set_alias(nwi_state* state, nwi_ifstate* ifstate)
 {
        nwi_ifstate*      ifstate_alias;
        int af = ifstate->af;
 {
        nwi_ifstate*      ifstate_alias;
        int af = ifstate->af;
@@ -87,11 +113,15 @@ _nwi_state_reset_alias(nwi_state_t state) {
 
        for (i = state->ipv6_start;
             i < state->ipv6_start + state->ipv6_count; i++) {
 
        for (i = state->ipv6_start;
             i < state->ipv6_start + state->ipv6_count; i++) {
-               nwi_set_alias(state, &state->nwi_ifstates[i]);
+               _nwi_set_alias(state, &state->nwi_ifstates[i]);
        }
 }
 
        }
 }
 
-/* Public APIs' */
+
+#pragma mark -
+#pragma mark Network information [nwi] APIs
+
+
 /*
  * Function: nwi_state_get_notify_key
  * Purpose:
 /*
  * Function: nwi_state_get_notify_key
  * Purpose:
@@ -105,12 +135,23 @@ _nwi_state_reset_alias(nwi_state_t state) {
 const char *
 nwi_state_get_notify_key()
 {
 const char *
 nwi_state_get_notify_key()
 {
+#if    !TARGET_IPHONE_SIMULATOR
        return "com.apple.system.SystemConfiguration.nwi";
        return "com.apple.system.SystemConfiguration.nwi";
+#else  // !TARGET_IPHONE_SIMULATOR
+       return "com.apple.iOS_Simulator.SystemConfiguration.nwi";
+#endif // !TARGET_IPHONE_SIMULATOR
 }
 
 }
 
+#define ATOMIC_CMPXCHG(p, o, n)        __sync_bool_compare_and_swap((p), (o), (n))
 #define ATOMIC_INC(p)          __sync_fetch_and_add((p), 1)            // return (n++);
 #define ATOMIC_DEC(p)          __sync_sub_and_fetch((p), 1)            // return (--n);
 
 #define ATOMIC_INC(p)          __sync_fetch_and_add((p), 1)            // return (n++);
 #define ATOMIC_DEC(p)          __sync_sub_and_fetch((p), 1)            // return (--n);
 
+void
+_nwi_state_force_refresh()
+{
+       ATOMIC_CMPXCHG(&nwi_store_force_refresh, FALSE, TRUE);
+}
+
 static void
 nwi_state_retain(nwi_state_t state)
 {
 static void
 nwi_state_retain(nwi_state_t state)
 {
@@ -126,12 +167,102 @@ nwi_state_retain(nwi_state_t state)
 void
 nwi_state_release(nwi_state_t state)
 {
 void
 nwi_state_release(nwi_state_t state)
 {
-       if (ATOMIC_DEC(&state->ref) == 0) {
-               free(state);
+       if (ATOMIC_DEC(&state->ref) > 0) {
+               // if not last reference
+               return;
+       }
+
+       // release connection reference on 1-->0 transition
+       if (state->svr) {
+               dispatch_sync(__nwi_configuration_queue(), ^{
+                       if (--nwi_active == 0) {
+                               // if last reference, drop connection
+                               libSC_info_client_release(nwi_client);
+                               nwi_client = NULL;
+                       }
+               });
        }
        }
+
+       // release nwi_state
+       free(state);
+
        return;
 }
 
        return;
 }
 
+static nwi_state *
+_nwi_state_copy_data()
+{
+       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(), ^{
+               if ((nwi_active++ == 0) || (nwi_client == NULL)) {
+                       static dispatch_once_t  once;
+                       static const char       *service_name   = NWI_SERVICE_NAME;
+
+                       dispatch_once(&once, ^{
+                               const char      *name;
+
+                               // get [XPC] service name
+                               name = getenv(service_name);
+                               if ((name != NULL) && (issetugid() == 0)) {
+                                       service_name = strdup(name);
+                               }
+
+                               // get process name
+                               proc_name = getprogname();
+                       });
+
+                       nwi_client =
+                               libSC_info_client_create(__nwi_configuration_queue(),   // dispatch queue
+                                                        service_name,                  // XPC service name
+                                                        "Network information");        // service description
+                       if (nwi_client == NULL) {
+                               --nwi_active;
+                       }
+               }
+       });
+
+       if ((nwi_client == NULL) || !nwi_client->active) {
+               // if network information server not available
+               return NULL;
+       }
+
+       // 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);
+       }
+
+       // set request
+       xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_REQUEST_COPY);
+
+       // send request to the DNS configuration server
+       reply = libSC_send_message_with_reply_sync(nwi_client, reqdict);
+       xpc_release(reqdict);
+
+       if (reply != NULL) {
+               const void      *dataRef;
+               size_t          dataLen = 0;
+
+               dataRef = xpc_dictionary_get_data(reply, NWI_CONFIGURATION, &dataLen);
+               if (dataRef != NULL) {
+                       nwi_state = malloc(dataLen);
+                       bcopy((void *)dataRef, nwi_state, dataLen);
+                       nwi_state->ref = 0;
+                       nwi_state->svr = TRUE;
+               }
+
+               xpc_release(reply);
+       }
+
+       return nwi_state;
+}
+
 /*
  * Function: nwi_state_copy
  * Purpose:
 /*
  * Function: nwi_state_copy
  * Purpose:
@@ -141,12 +272,15 @@ nwi_state_release(nwi_state_t state)
 nwi_state_t
 nwi_state_copy(void)
 {
 nwi_state_t
 nwi_state_copy(void)
 {
+       boolean_t       force_refresh;
        nwi_state_t     nwi_state = NULL;
        nwi_state_t     old_state = NULL;
 
        pthread_once(&initialized, _nwi_state_initialize);
        pthread_mutex_lock(&nwi_store_lock);
 
        nwi_state_t     nwi_state = NULL;
        nwi_state_t     old_state = NULL;
 
        pthread_once(&initialized, _nwi_state_initialize);
        pthread_mutex_lock(&nwi_store_lock);
 
+       force_refresh = ATOMIC_CMPXCHG(&nwi_store_force_refresh, TRUE, FALSE);
+
        if (G_nwi_state != NULL) {
                int             check = 0;
                uint32_t        status;
        if (G_nwi_state != NULL) {
                int             check = 0;
                uint32_t        status;
@@ -164,7 +298,7 @@ nwi_state_copy(void)
                                check = 1;
                        }
                }
                                check = 1;
                        }
                }
-               if (check != 0) {
+               if (check != 0 || force_refresh) {
                        /* new need snapshot */
                        old_state = G_nwi_state;
                        G_nwi_state = NULL;
                        /* new need snapshot */
                        old_state = G_nwi_state;
                        G_nwi_state = NULL;
@@ -172,7 +306,7 @@ nwi_state_copy(void)
        }
        /* Let's populate the cache if it's empty */
        if (G_nwi_state == NULL) {
        }
        /* Let's populate the cache if it's empty */
        if (G_nwi_state == NULL) {
-               G_nwi_state = _nwi_state_copy();
+               G_nwi_state = _nwi_state_copy_data();
                if (G_nwi_state != NULL) {
                        /* one reference for G_nwi_state */
                        nwi_state_retain(G_nwi_state);
                if (G_nwi_state != NULL) {
                        /* one reference for G_nwi_state */
                        nwi_state_retain(G_nwi_state);
@@ -202,6 +336,34 @@ nwi_state_copy(void)
 void
 _nwi_state_ack(nwi_state_t state, const char *bundle_id)
 {
 void
 _nwi_state_ack(nwi_state_t state, const char *bundle_id)
 {
+       xpc_object_t    reqdict;
+
+       if (state == NULL) {
+               return; // ASSERT
+       }
+
+       if ((nwi_client == NULL) || !nwi_client->active) {
+               // if network information server not available
+               return;
+       }
+
+       dispatch_sync(__nwi_configuration_queue(), ^{
+               nwi_active++;   // keep connection active (for the life of the process)
+       });
+
+       // create message
+       reqdict = xpc_dictionary_create(NULL, NULL, 0);
+
+       // set request
+       xpc_dictionary_set_int64(reqdict, NWI_REQUEST, NWI_REQUEST_ACKNOWLEDGE);
+
+       // set generation
+       xpc_dictionary_set_uint64(reqdict, NWI_GENERATION, state->generation_count);
+
+       // send acknowledgement to the DNS configuration server
+       xpc_connection_send_message(nwi_client->connection, reqdict);
+
+       xpc_release(reqdict);
        return;
 }
 
        return;
 }
 
@@ -218,6 +380,17 @@ nwi_state_get_generation(nwi_state_t state)
        return (state->generation_count);
 }
 
        return (state->generation_count);
 }
 
+/*
+ * Function: nwi_ifstate_get_generation
+ * Purpose:
+ *   Returns the generation (mach_time) of the nwi_ifstate data.
+ */
+uint64_t
+nwi_ifstate_get_generation(nwi_ifstate_t ifstate)
+{
+       return (ifstate->if_generation_count);
+}
+
 /*
  * Function: nwi_ifstate_get_ifname
  * Purpose:
 /*
  * Function: nwi_ifstate_get_ifname
  * Purpose:
@@ -370,3 +543,238 @@ nwi_ifstate_compare_rank(nwi_ifstate_t ifstate1, nwi_ifstate_t ifstate2)
 {
        return RankCompare(ifstate1->rank, ifstate2->rank);
 }
 {
        return RankCompare(ifstate1->rank, ifstate2->rank);
 }
+
+/*
+ * nwi_state_get_reachability_flags
+ *
+ * returns the global reachability flags for a given address family.
+ * If no address family is passed in, it returns the global reachability
+ * flags for either families.
+ *
+ * The reachability flags returned follow the definition of
+ * SCNetworkReachabilityFlags.
+ *
+ * If the flags are zero (i.e. do not contain kSCNetworkReachabilityFlagsReachable), there is no connectivity.
+ *
+ * Otherwise, at least kSCNetworkReachabilityFlagsReachable is set:
+ *        Reachable only
+ *          No other connection flags are set.
+ *        Reachable and no ConnectionRequired
+ *          If we have connectivity for the specified address family (and we'd
+ *          be returning the reachability flags associated with the default route)
+ *        Reachable and ConnectionRequired
+ *          If we do not currently have an active/primary network but we may
+ *          be able to establish connectivity.
+ *        Reachable and OnDemand
+ *          If we do not currently have an active/primary network but we may
+ *          be able to establish connective on demand.
+ *        Reachable and TransientConnection
+ *          This connection is transient.
+ *        Reachable and WWAN
+ *          This connection will be going over the cellular network.
+ */
+uint32_t
+nwi_state_get_reachability_flags(nwi_state_t nwi_state, int af)
+{
+       if (nwi_state == NULL) {
+               return (0);
+       }
+       if (af == AF_INET || af == AF_INET6) {
+               nwi_ifstate_t ifstate;
+
+               ifstate = nwi_state_get_first_ifstate(nwi_state, af);
+
+               if (ifstate != NULL) {
+                       return ifstate->reach_flags;
+               }
+
+               return (af == AF_INET) ? nwi_state->reach_flags_v4 : nwi_state->reach_flags_v6;
+       } else {
+               nwi_ifstate_t ifstate_v4;
+               nwi_ifstate_t ifstate_v6;
+
+               ifstate_v4 = nwi_state_get_first_ifstate(nwi_state, AF_INET);
+               ifstate_v6 = nwi_state_get_first_ifstate(nwi_state, AF_INET6);
+
+               if (ifstate_v4 != NULL) {
+                       if (ifstate_v6 != NULL) {
+                               if (nwi_ifstate_compare_rank(ifstate_v4, ifstate_v6) > 0) {
+                                       return ifstate_v6->reach_flags;
+                               } else {
+                                       return ifstate_v4->reach_flags;
+                               }
+                       } else {
+                               return ifstate_v4->reach_flags;
+                       }
+               } else {
+                       if (ifstate_v6 != NULL) {
+                               return ifstate_v6->reach_flags;
+                       }
+               }
+
+               if (nwi_state->reach_flags_v4 != 0) {
+                       return nwi_state->reach_flags_v4;
+               }
+               // This is the case where both ifstate are NULL.
+               return nwi_state->reach_flags_v6;
+       }
+}
+
+/*
+ * nwi_ifstate_get_vpn_server
+ *
+ * returns a sockaddr representation of the vpn server address.
+ * NULL if PPP/VPN/IPSec server address does not exist.
+ */
+const struct sockaddr *
+nwi_ifstate_get_vpn_server(nwi_ifstate_t ifstate)
+{
+       const struct sockaddr * vpn_server_addr;
+
+       vpn_server_addr = (const struct sockaddr *)(void *)
+                          &ifstate->vpn_server_address;
+
+       if (vpn_server_addr->sa_family == 0) {
+               return NULL;
+       }
+       return vpn_server_addr;
+}
+
+/*
+ * nwi_ifstate_get_reachability_flags
+ *
+ * returns the reachability flags for the interface given an address family.
+ * The flags returned are those determined outside of
+ * the routing table.  [None, ConnectionRequired, OnDemand,
+ * Transient Connection, WWAN].
+ */
+uint32_t
+nwi_ifstate_get_reachability_flags(nwi_ifstate_t ifstate)
+{
+       return ifstate->reach_flags;
+}
+
+/*
+ * nwi_ifstate_get_signature
+ *
+ * returns the signature and its length for an ifstate given an address family.
+ * If AF_UNSPEC is passed in, the signature for a given ifstate is returned.
+ *
+ * If the signature does not exist, NULL is returned.
+ */
+const uint8_t *
+nwi_ifstate_get_signature(nwi_ifstate_t ifstate, int af, int * length)
+{
+       nwi_ifstate_t i_state = NULL;
+
+       switch (af) {
+               case AF_UNSPEC:
+                       i_state = ifstate;
+                       break;
+               case AF_INET:
+               case AF_INET6:
+                       i_state = (ifstate->af == af) ? ifstate : ifstate->af_alias;
+                       break;
+               default:
+                       break;
+
+       }
+
+       if (i_state != NULL) {
+               if ((i_state->flags & NWI_IFSTATE_FLAGS_HAS_SIGNATURE) != 0) {
+                       *length = sizeof(i_state->signature);
+                       return (i_state->signature);
+               }
+       }
+
+       *length = 0;
+       return NULL;
+}
+
+static inline
+boolean_t
+_nwi_ifstate_is_in_list(nwi_ifstate_t ifstate, int af)
+{
+       nwi_ifstate_t i_state;
+
+       i_state = (ifstate->af == af) ? ifstate : ifstate->af_alias;
+       if (i_state == NULL) {
+               return FALSE;
+       }
+
+       if ((nwi_ifstate_get_flags(i_state) & NWI_IFSTATE_FLAGS_NOT_IN_LIST) == 0) {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+/*
+ * nwi_ifstate_get_dns_signature
+ *
+ * returns the signature and its length for given
+ * ifstate with a valid dns configuration.
+ *
+ * If the signature does not exist, NULL is returned.
+ *
+ */
+const uint8_t *
+nwi_ifstate_get_dns_signature(nwi_ifstate_t ifstate, int * length)
+{
+       const uint8_t * signature = NULL;
+       const uint8_t * v4_signature;
+       int             v4_signature_len;
+       const uint8_t * v6_signature;
+       int             v6_signature_len;
+
+       *length = 0;
+
+       if ((nwi_ifstate_get_flags(ifstate) & NWI_IFSTATE_FLAGS_HAS_DNS) == 0) {
+               return NULL;
+       }
+
+       v4_signature = nwi_ifstate_get_signature(ifstate, AF_INET, &v4_signature_len);
+       v6_signature = nwi_ifstate_get_signature(ifstate, AF_INET6, &v6_signature_len);
+       if (v4_signature == NULL && v6_signature == NULL) {
+               return NULL;
+       }
+
+       if (_nwi_ifstate_is_in_list(ifstate, AF_INET) == TRUE) {
+               signature = v4_signature;
+               *length = v4_signature_len;
+       } else {
+               if (_nwi_ifstate_is_in_list(ifstate, AF_INET6) != TRUE && v4_signature_len > 0) {
+                       /* v6 is ranked never, v4 is ranked never but has a valid signature */
+                       signature = v4_signature;
+                       *length = v4_signature_len;
+               } else {
+                       /* v6 is not ranked never or v4 has no signature */
+                       signature = v6_signature;
+                       *length = v6_signature_len;
+               }
+       }
+
+       return signature;
+}
+
+
+#pragma mark -
+#pragma mark Network information [nwi] test code
+
+
+#ifdef MAIN
+
+int
+main(int argc, char **argv)
+{
+       dns_config_t    *config;
+
+       config = dns_configuration_copy();
+       if (config != NULL) {
+               dns_configuration_free(&config);
+       }
+
+       exit(0);
+}
+
+#endif
index 418b304498297a4f947edcc96937213187f28546..7c364fcd29694ef83c1deb2ba10112a769b032fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define _NETWORK_INFORMATION_H_
 
 #include <stdint.h>
 #define _NETWORK_INFORMATION_H_
 
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 typedef struct _nwi_state * nwi_state_t;
 typedef struct _nwi_ifstate * nwi_ifstate_t;
 
 
 typedef struct _nwi_state * nwi_state_t;
 typedef struct _nwi_ifstate * nwi_ifstate_t;
 
+__BEGIN_DECLS
+
 /*
  * Function: nwi_state_copy
  * Purpose:
 /*
  * Function: nwi_state_copy
  * Purpose:
@@ -81,13 +84,21 @@ nwi_state_get_first_ifstate(nwi_state_t state, int af);
 /*
  * Function: nwi_state_get_generation
  * Purpose:
 /*
  * Function: nwi_state_get_generation
  * Purpose:
- *   Returns the generation (mach_time) of the nwi_state data.
+ *   Returns the generation of the nwi_state data.
  *   Every time the data is updated due to changes
  *   in the network, this value will change.
  */
 uint64_t
 nwi_state_get_generation(nwi_state_t state);
 
  *   Every time the data is updated due to changes
  *   in the network, this value will change.
  */
 uint64_t
 nwi_state_get_generation(nwi_state_t state);
 
+/*
+ * Function: nwi_ifstate_get_generation
+ * Purpose:
+ *   Returns the generation of the nwi_ifstate data.
+ */
+uint64_t
+nwi_ifstate_get_generation(nwi_ifstate_t ifstate);
+
 /*
  * Function: nwi_state_get_ifstate
  * Purpose:
 /*
  * Function: nwi_state_get_ifstate
  * Purpose:
@@ -165,4 +176,82 @@ void
 _nwi_state_ack(nwi_state_t state, const char *bundle_id)
        __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
 
 _nwi_state_ack(nwi_state_t state, const char *bundle_id)
        __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
 
+/*
+ * nwi_state_get_reachability_flags
+ *
+ * returns the global reachability flags for a given address family.
+ * If no address family is passed in, it returns the global reachability
+ * flags for either families.
+ *
+ * The reachability flags returned follow the definition of
+ * SCNetworkReachabilityFlags.
+ *
+ * If the flags are zero (i.e. do not contain kSCNetworkReachabilityFlagsReachable), there is no connectivity.
+ *
+ * Otherwise, at least kSCNetworkReachabilityFlagsReachable is set:
+ *        Reachable only
+ *          No other connection flags are set.
+ *        Reachable and no ConnectionRequired
+ *          If we have connectivity for the specified address family (and we'd
+ *          be returning the reachability flags associated with the default route)
+ *        Reachable and ConnectionRequired
+ *          If we do not currently have an active/primary network but we may
+ *          be able to establish connectivity.
+ *        Reachable and OnDemand
+ *          If we do not currently have an active/primary network but we may
+ *          be able to establish connective on demand.
+ *        Reachable and TransientConnection
+ *          This connection is transient.
+ *        Reachable and WWAN
+ *          This connection will be going over the cellular network.
+ */
+uint32_t
+nwi_state_get_reachability_flags(nwi_state_t nwi_state, int af);
+
+/*
+ * nwi_ifstate_get_vpn_server
+ *
+ * returns a sockaddr representation of the vpn server address.
+ * NULL if PPP/VPN/IPSec server address does not exist.
+ */
+const struct sockaddr *
+nwi_ifstate_get_vpn_server(nwi_ifstate_t ifstate);
+
+/*
+ * nwi_ifstate_get_reachability_flags
+ *
+ * returns the reachability flags for the interface given an address family.
+ * The flags returned are those determined outside of
+ * the routing table.  [None, ConnectionRequired, OnDemand,
+ * Transient Connection, WWAN].
+ */
+uint32_t
+nwi_ifstate_get_reachability_flags(nwi_ifstate_t ifstate);
+
+/*
+ * nwi_ifstate_get_signature
+ *
+ * returns the signature and its length for an ifstate given an address family.
+ * If AF_UNSPEC is passed in, the signature for a given ifstate is returned.
+ *
+ * If the signature does not exist, NULL is returned.
+ */
+const uint8_t *
+nwi_ifstate_get_signature(nwi_ifstate_t ifstate, int af, int * length);
+
+
+/*
+ * nwi_ifstate_get_dns_signature
+ *
+ * returns the signature and its length for given
+ * ifstate with a valid dns configuration.
+ *
+ * If the signature does not exist, NULL is returned.
+ *
+ */
+const uint8_t *
+nwi_ifstate_get_dns_signature(nwi_ifstate_t ifstate, int * length);
+
+__END_DECLS
+
 #endif
 #endif
index 7dfc706bdd35d7a4b60c646305e69371fbd8f3f7..af1f1ba177020de64143481a6045134099234568 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 
 #include <arpa/inet.h>
  */
 
 #include <arpa/inet.h>
+#include <assert.h>
 #include <notify.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <stdlib.h>
 #include <notify.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <stdlib.h>
-#include <syslog.h>
 #include <stdbool.h>
 #include "network_information_priv.h"
 #include <limits.h>
 #include <stdbool.h>
 #include "network_information_priv.h"
 #include <limits.h>
+#include <stdio.h>
 
 
-sa_family_t nwi_af_list[] = {AF_INET, AF_INET6};
+__private_extern__
+const sa_family_t nwi_af_list[] = {AF_INET, AF_INET6};
 
 static __inline__ unsigned int
 nwi_state_compute_size(unsigned int n)
 
 static __inline__ unsigned int
 nwi_state_compute_size(unsigned int n)
@@ -55,6 +57,7 @@ nwi_state_copy_priv(nwi_state_t src)
                bcopy(src, dest, src->size);
 
                dest->ref = 1;
                bcopy(src, dest, src->size);
 
                dest->ref = 1;
+               dest->svr = FALSE;
        }
        return dest;
 }
        }
        return dest;
 }
@@ -86,6 +89,7 @@ nwi_state_new(nwi_state_t old_state, int elems)
                return NULL;
        }
 
                return NULL;
        }
 
+       bzero(state, new_size);
        state->size = new_size;
 
        /*
        state->size = new_size;
 
        /*
@@ -103,7 +107,6 @@ nwi_state_new(nwi_state_t old_state, int elems)
                }
 
                state->ipv4_count = old_state->ipv4_count;
                }
 
                state->ipv4_count = old_state->ipv4_count;
-
                if (state->ipv4_count > 0) {
                        bcopy((void*) old_state->nwi_ifstates,
                              (void*) state->nwi_ifstates,
                if (state->ipv4_count > 0) {
                        bcopy((void*) old_state->nwi_ifstates,
                              (void*) state->nwi_ifstates,
@@ -119,33 +122,47 @@ nwi_state_new(nwi_state_t old_state, int elems)
        nwi_state_set_last(state, AF_INET6);
 
        state->ref = 1;
        nwi_state_set_last(state, AF_INET6);
 
        state->ref = 1;
+       state->svr = FALSE;
        return state;
 }
 
        return state;
 }
 
-static inline
-nwi_ifstate_t nwi_ifstate_get_last(nwi_state_t state, int af, uint32_t** last)
+static __inline__
+nwi_ifstate_t
+nwi_ifstate_get_last(nwi_state_t state, int af, uint32_t** last)
 {
        uint32_t*       count;
        int             idx;
 
 {
        uint32_t*       count;
        int             idx;
 
-       count = (af == AF_INET)
-               ?&state->ipv4_count:&state->ipv6_count;
+       assert(state != NULL);
+
+       count = (af == AF_INET) ? &state->ipv4_count
+                               : &state->ipv6_count;
 
 
-       idx = (af == AF_INET)
-               ?state->ipv4_count:(state->ipv6_start + state->ipv6_count);
+       idx = (af == AF_INET) ? state->ipv4_count
+                             : (state->ipv6_start + state->ipv6_count);
 
        *last = count;
 
        return &state->nwi_ifstates[idx];
 
        *last = count;
 
        return &state->nwi_ifstates[idx];
-
 }
 
 __private_extern__
 void
 }
 
 __private_extern__
 void
+nwi_ifstate_set_signature(nwi_ifstate_t ifstate, uint8_t * signature)
+{
+       bcopy(signature, ifstate->signature, sizeof(ifstate->signature));
+       ifstate->flags |= NWI_IFSTATE_FLAGS_HAS_SIGNATURE;
+       return;
+}
+
+__private_extern__
+nwi_ifstate_t
 nwi_insert_ifstate(nwi_state_t state,
 nwi_insert_ifstate(nwi_state_t state,
-                  const char* ifname, int af,
+                  const char * ifname, int af,
                   uint64_t flags, Rank rank,
                   uint64_t flags, Rank rank,
-                  void* ifa)
+                  void * ifa,
+                  struct sockaddr * vpn_server_addr,
+                  uint32_t reach_flags)
 {
        nwi_ifstate_t   ifstate;
 
 {
        nwi_ifstate_t   ifstate;
 
@@ -155,7 +172,7 @@ nwi_insert_ifstate(nwi_state_t state,
        /* Already present, just ignore it */
        if (ifstate != NULL) {
                if (ifstate->rank < rank) {
        /* Already present, just ignore it */
        if (ifstate != NULL) {
                if (ifstate->rank < rank) {
-                       return;
+                       return NULL;
                }
        }
 
                }
        }
 
@@ -164,10 +181,9 @@ nwi_insert_ifstate(nwi_state_t state,
 
                /* We need to append it as the last element */
                ifstate = nwi_ifstate_get_last(state, af, &last);
 
                /* We need to append it as the last element */
                ifstate = nwi_ifstate_get_last(state, af, &last);
-               strcpy(ifstate->ifname, ifname);
-               ifstate->af_alias = NULL;
+               bzero(ifstate, sizeof(*ifstate));
+               strlcpy(ifstate->ifname, ifname, sizeof(ifstate->ifname));
                ifstate->af = af;
                ifstate->af = af;
-               ifstate->diff_ch = NULL;
                (*last)++;
        }
 
                (*last)++;
        }
 
@@ -187,10 +203,17 @@ nwi_insert_ifstate(nwi_state_t state,
 
        }
 
 
        }
 
+       if (vpn_server_addr != NULL && vpn_server_addr->sa_family != 0) {
+               _nwi_ifstate_set_vpn_server(ifstate, vpn_server_addr);
+       } else {
+               _nwi_ifstate_set_vpn_server(ifstate, NULL);
+       }
+
+       ifstate->reach_flags = reach_flags;
        ifstate->rank = rank;
        ifstate->flags = flags;
 
        ifstate->rank = rank;
        ifstate->flags = flags;
 
-       return;
+       return ifstate;
 }
 
 __private_extern__
 }
 
 __private_extern__
@@ -220,79 +243,18 @@ nwi_state_set_last(nwi_state_t state, int af)
 
        /* The last element is an element with the flags set as
         * NWI_IFSTATE_FLAGS_NOT_IN_LIST */
 
        /* The last element is an element with the flags set as
         * NWI_IFSTATE_FLAGS_NOT_IN_LIST */
-       last_elem_idx = (af == AF_INET)
-                       ?state->ipv4_count
-                       :(state->ipv6_start + state->ipv6_count);
+       last_elem_idx = (af == AF_INET) ? state->ipv4_count
+                                       : (state->ipv6_start + state->ipv6_count);
 
        state->nwi_ifstates[last_elem_idx].ifname[0] = '\0';
 
        state->nwi_ifstates[last_elem_idx].ifname[0] = '\0';
-       state->nwi_ifstates[last_elem_idx].flags
-           |= NWI_IFSTATE_FLAGS_NOT_IN_LIST;
+       state->nwi_ifstates[last_elem_idx].flags = NWI_IFSTATE_FLAGS_NOT_IN_LIST;
 }
 
 }
 
-__private_extern__
-void
-_nwi_state_dump(int level, nwi_state_t state)
-{
-       const char *            addr_str;
-       void *                  address;
-       int                     i;
-       char                    ntopbuf[INET6_ADDRSTRLEN];
-       nwi_ifstate_t           scan;
-
-
-       if (state == NULL) {
-               syslog(level, "<empty nwi_state>");
-               return;
-       }
-       syslog(level, "nwi_state = { gen = %llu size = %u #ipv4 = %u #ipv6 = %u }",
-              state->generation_count,
-              state->size,
-              state->ipv4_count,
-              state->ipv6_count);
-
-       if (state->ipv4_count) {
-               syslog(level, "IPv4:");
-               for (i = 0, scan = state->nwi_ifstates;
-                    i < state->ipv4_count; i++, scan++) {
-                       bool has_dns = (scan->flags & NWI_IFSTATE_FLAGS_HAS_DNS) != 0;
-                       bool never = (scan->flags & NWI_IFSTATE_FLAGS_NOT_IN_LIST) != 0;
-
-                       address = nwi_ifstate_get_address(scan);
-                       addr_str =  inet_ntop(scan->af, address, ntopbuf, sizeof(ntopbuf));
-
-                       syslog(level, "    [%d]: %s%s%s%s rank %u iaddr: %s " ,
-                              i, scan->ifname, scan->diff_ch != NULL?scan->diff_ch:"",
-                              has_dns ? " dns" : "",
-                              never ? " never" : "",
-                              scan->rank,
-                              addr_str);
-               }
-       }
-       if (state->ipv6_count) {
-               syslog(level, "IPv6:");
-               for (i = 0, scan = state->nwi_ifstates + state->ipv6_start;
-                    i < state->ipv6_count; i++, scan++) {
-                       bool has_dns = (scan->flags & NWI_IFSTATE_FLAGS_HAS_DNS) != 0;
-                       bool never = (scan->flags & NWI_IFSTATE_FLAGS_NOT_IN_LIST) != 0;
-
-                       address = nwi_ifstate_get_address(scan);
-                       addr_str =  inet_ntop(scan->af, address, ntopbuf, sizeof(ntopbuf));
-                       syslog(level, "    [%d]: %s%s%s%s rank %u iaddr6: %s ",
-                              i, scan->ifname, scan->diff_ch != NULL?scan->diff_ch:"",
-                              has_dns ? " dns" : "",
-                              never ? " never" : "",
-                              scan->rank,
-                              addr_str);
-               }
-       }
-       return;
-}
-
-
 #define        unchanged       ""
 #define added          "+"
 #define deleted                "-"
 #define changed                "!"
 #define        unchanged       ""
 #define added          "+"
 #define deleted                "-"
 #define changed                "!"
+#define rank_change    "R"
 
 __private_extern__
 void *
 
 __private_extern__
 void *
@@ -305,7 +267,10 @@ __private_extern__
 const char *
 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate)
 {
 const char *
 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate)
 {
-       return ifstate->diff_ch;
+       if (strcmp(ifstate->diff_str, rank_change) == 0) {
+               return changed;
+       }
+       return ifstate->diff_str;
 }
 
 static
 }
 
 static
@@ -313,10 +278,6 @@ inline
 boolean_t
 nwi_ifstate_has_changed(nwi_ifstate_t ifstate1, nwi_ifstate_t ifstate2)
 {
 boolean_t
 nwi_ifstate_has_changed(nwi_ifstate_t ifstate1, nwi_ifstate_t ifstate2)
 {
-       if (ifstate1->rank != ifstate2->rank) {
-               return TRUE;
-       }
-
        if (ifstate1->flags != ifstate2->flags) {
                return TRUE;
        }
        if (ifstate1->flags != ifstate2->flags) {
                return TRUE;
        }
@@ -350,85 +311,116 @@ nwi_ifstate_append(nwi_state_t state, nwi_ifstate_t scan)
 static
 inline
 void
 static
 inline
 void
-nwi_ifstate_set_diff_str(nwi_ifstate_t ifstate, const char * ch)
+nwi_ifstate_set_diff_str(nwi_ifstate_t ifstate, const char *diff_str)
 {
 {
-       ifstate->diff_ch = ch;
+       ifstate->diff_str = diff_str;
 }
 
 static
 void
 }
 
 static
 void
-nwi_state_merge_added(nwi_state_t state, nwi_state_t old_state,
-                   nwi_state_t new_state)
+nwi_ifstate_set_added_or_changed_str(nwi_state_t state, nwi_state_t old_state, nwi_ifstate_t ifstate)
 {
 {
-       int idx;
-       nwi_ifstate_t scan;
-
-       /* Iterate through v4 and v6 list and annotate the diff flags */
-       for (idx = 0; idx < sizeof(nwi_af_list)/sizeof(nwi_af_list[0]); idx++) {
-               scan = nwi_state_get_first_ifstate(new_state, nwi_af_list[idx]);
+       nwi_ifstate_t   existing_ifstate, new_ifstate;
+
+       existing_ifstate = nwi_state_get_ifstate_with_name(old_state,
+                                                          ifstate->af,
+                                                          nwi_ifstate_get_ifname(ifstate));
+
+       /* Add the element that is not in the store */
+       new_ifstate = nwi_ifstate_append(state, ifstate);
+
+       /* These are potentially "added" elements unless they are
+        * in the old list */
+       nwi_ifstate_set_diff_str(new_ifstate, added);
+
+       if (existing_ifstate != NULL) {
+               if (nwi_ifstate_has_changed(existing_ifstate, new_ifstate) == TRUE) {
+                       nwi_ifstate_set_diff_str(new_ifstate, changed);
+               } else if (existing_ifstate->rank != new_ifstate->rank) {
+                       nwi_ifstate_set_diff_str(new_ifstate, rank_change);
+               } else {
+                       nwi_ifstate_set_diff_str(new_ifstate, unchanged);
+               }
+       }
+       return;
+}
 
 
-               while (scan != NULL) {
-                       nwi_ifstate_t   existing_ifstate, new_ifstate;
-                       const char*     ifname;
+static
+void
+nwi_ifstate_set_removed_str(nwi_state_t state, nwi_ifstate_t ifstate)
+{
+       nwi_ifstate_t   existing_ifstate;
 
 
-                       ifname = nwi_ifstate_get_ifname(scan);
+       existing_ifstate = nwi_state_get_ifstate_with_name(state,
+                                                          ifstate->af,
+                                                          nwi_ifstate_get_ifname(ifstate));
 
 
-                       existing_ifstate = nwi_state_get_ifstate_with_name(old_state, scan->af, ifname);
+       /* Any elements that has not been added means that they are removed */
+       if (existing_ifstate == NULL) {
+               nwi_ifstate_t new_ifstate = nwi_ifstate_append(state, ifstate);
+               nwi_ifstate_set_diff_str(new_ifstate, deleted);
+       }
+       return;
+}
 
 
-                       /* Add the element that is not in the store */
-                       new_ifstate = nwi_ifstate_append(state, scan);
+static
+void
+nwi_state_merge_added(nwi_state_t state, nwi_state_t old_state,
+                   nwi_state_t new_state)
+{
+       int i;
+       nwi_ifstate_t scan;
 
 
-                       /* These are potentially "added" elements unless they are
-                        * in the old list */
-                       nwi_ifstate_set_diff_str(new_ifstate, added);
+       if (new_state == NULL) {
+               return;
+       }
 
 
-                       if (existing_ifstate != NULL) {
-                               if (nwi_ifstate_has_changed(existing_ifstate, new_ifstate) == TRUE) {
-                                       nwi_ifstate_set_diff_str(new_ifstate, changed);
-                               } else {
-                                       nwi_ifstate_set_diff_str(new_ifstate, unchanged);
-                               }
-                       }
-                       scan = nwi_ifstate_get_next(scan, scan->af);
+       if (new_state->ipv4_count) {
+               for (i = 0, scan = new_state->nwi_ifstates;
+                    i < new_state->ipv4_count; i++, scan++) {
+                       nwi_ifstate_set_added_or_changed_str(state, old_state, scan);
                }
                }
-               nwi_state_set_last(state, nwi_af_list[idx]);
+               nwi_state_set_last(state, AF_INET);
        }
 
        }
 
+       if (new_state->ipv6_count) {
+               for (i = 0, scan = new_state->nwi_ifstates + new_state->ipv6_start;
+                    i < new_state->ipv6_count; i++, scan++) {
+                       nwi_ifstate_set_added_or_changed_str(state, old_state, scan);
+               }
+               nwi_state_set_last(state, AF_INET6);
+       }
        return;
 }
 
        return;
 }
 
-static
 void
 nwi_state_merge_removed(nwi_state_t state, nwi_state_t old_state)
 {
 void
 nwi_state_merge_removed(nwi_state_t state, nwi_state_t old_state)
 {
-       int idx;
+       int i;
        nwi_ifstate_t scan;
 
        nwi_ifstate_t scan;
 
-       /* Iterate through v4 and v6 list and annotate the diff flags */
-       for (idx = 0; idx < sizeof(nwi_af_list)/sizeof(nwi_af_list[0]); idx++) {
-               scan = nwi_state_get_first_ifstate(old_state, nwi_af_list[idx]);
-
-               while (scan != NULL) {
-                       nwi_ifstate_t   existing_ifstate;
-                       const char*     ifname;
-
-                       ifname = nwi_ifstate_get_ifname(scan);
-
-                       existing_ifstate = nwi_state_get_ifstate_with_name(state, scan->af, ifname);
+       if (old_state == NULL) {
+               return;
+       }
 
 
-                       /* Any elements that has not been added means that they are removed */
-                       if (existing_ifstate == NULL) {
-                               nwi_ifstate_t new_ifstate = nwi_ifstate_append(state, scan);
-                               nwi_ifstate_set_diff_str(new_ifstate, deleted);
-                       }
-                       scan = nwi_ifstate_get_next(scan, scan->af);
+       if (old_state->ipv4_count) {
+               for (i = 0, scan = old_state->nwi_ifstates;
+                    i < old_state->ipv4_count; i++, scan++) {
+                       nwi_ifstate_set_removed_str(state, scan);
                }
                }
-               nwi_state_set_last(state, nwi_af_list[idx]);
+               nwi_state_set_last(state, AF_INET);
        }
 
        }
 
+       if (old_state->ipv6_count) {
+               for (i = 0, scan = old_state->nwi_ifstates + old_state->ipv6_start;
+                    i < old_state->ipv6_count; i++, scan++) {
+                       nwi_ifstate_set_removed_str(state, scan);
+               }
+               nwi_state_set_last(state, AF_INET6);
+       }
+       return;
 }
 
 }
 
-
 __private_extern__
 nwi_state_t
 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state)
 __private_extern__
 nwi_state_t
 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state)
@@ -453,7 +445,111 @@ nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state)
        nwi_state_merge_added(diff, old_state,  new_state);
        nwi_state_merge_removed(diff, old_state);
 
        nwi_state_merge_added(diff, old_state,  new_state);
        nwi_state_merge_removed(diff, old_state);
 
-       /* Diff consists of a nwi_state_t with annotated diff_ch's */
+       /* Diff consists of a nwi_state_t with annotated diff_str's */
        return diff;
 }
 
        return diff;
 }
 
+static __inline__
+void
+_nwi_ifstate_set_generation(nwi_ifstate_t ifstate, uint64_t generation_count)
+{
+       ifstate->if_generation_count = generation_count;
+
+       return;
+}
+
+static
+boolean_t
+_nwi_ifstate_has_changed(nwi_state_t state, const char * ifname)
+{
+       nwi_ifstate_t   ifstate;
+
+       /* If either the v4 ifstate or the v6 ifstate
+        * has changed, then report that the interface has changed */
+       ifstate = nwi_state_get_ifstate_with_name(state,
+                                                 AF_INET,
+                                                 ifname);
+
+       if (ifstate != NULL
+           && ifstate->diff_str != NULL
+           && strcmp(ifstate->diff_str, unchanged) != 0
+           && strcmp(ifstate->diff_str, rank_change) != 0) {
+               return (TRUE);
+       }
+
+       ifstate = nwi_state_get_ifstate_with_name(state,
+                                                 AF_INET6,
+                                                 ifname);
+
+       if (ifstate != NULL
+           && ifstate->diff_str != NULL
+           && strcmp(ifstate->diff_str, unchanged) != 0
+           && strcmp(ifstate->diff_str, rank_change) != 0) {
+               return (TRUE);
+       }
+       return (FALSE);
+}
+
+__private_extern__
+void
+_nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state, nwi_state_t changes)
+{
+       int             i;
+       uint64_t        generation_count;
+       nwi_ifstate_t   scan;
+
+       if (state == NULL || changes == NULL) {
+               return;
+       }
+
+       /* cache the generation count */
+       generation_count = state->generation_count;
+
+       if (state->ipv4_count) {
+               for (i = 0, scan = state->nwi_ifstates;
+                    i < state->ipv4_count; i++, scan++) {
+                       if (_nwi_ifstate_has_changed(changes, scan->ifname) == TRUE) {
+                               /* Update the interface generation count */
+                               _nwi_ifstate_set_generation(scan, generation_count);
+                       } else {
+                               nwi_ifstate_t old_ifstate;
+
+                               old_ifstate = nwi_state_get_ifstate_with_name(old_state,
+                                                                             AF_INET,
+                                                                             scan->ifname);
+
+                               /* Set the current generation count */
+                               _nwi_ifstate_set_generation(scan,
+                                                           old_ifstate->if_generation_count);
+                       }
+               }
+       }
+
+       if (state->ipv6_count) {
+               for (i = 0, scan = state->nwi_ifstates + state->ipv6_start;
+                    i < state->ipv6_count; i++, scan++) {
+                       /* The generation count has been already updated in
+                        * the ipv4 case, just skip it. */
+                       if (nwi_ifstate_get_generation(scan) ==
+                               generation_count) {
+                               continue;
+                       }
+                       if (_nwi_ifstate_has_changed(changes, scan->ifname) == TRUE) {
+                               /* update the interface generation count */
+                               _nwi_ifstate_set_generation(scan, generation_count);
+                       } else {
+                               nwi_ifstate_t old_ifstate;
+
+                               old_ifstate = nwi_state_get_ifstate_with_name(old_state,
+                                                                             AF_INET6,
+                                                                             scan->ifname);
+                               assert(old_ifstate != NULL);
+
+                               /* Set the current generation count */
+                               _nwi_ifstate_set_generation(scan,
+                                                           old_ifstate->if_generation_count);
+                       }
+               }
+       }
+       return;
+}
index 3eb3c12c1ba70bc699ab873f142301c01ebeeda0..5ea1ded7e3c61abf38f2deac5341085958d7ba71 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -24,7 +24,9 @@
 #ifndef _NETWORK_INFORMATION_PRIV_H_
 #define _NETWORK_INFORMATION_PRIV_H_
 
 #ifndef _NETWORK_INFORMATION_PRIV_H_
 #define _NETWORK_INFORMATION_PRIV_H_
 
+#include <CommonCrypto/CommonDigest.h>
 #include <net/if.h>
 #include <net/if.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 #include <netinet/in.h>
 #include <stdint.h>
 #include <string.h>
 #include <netinet/in.h>
 
 #include "network_information.h"
 
 
 #include "network_information.h"
 
-__private_extern__
-sa_family_t nwi_af_list[2];
+extern const sa_family_t nwi_af_list[2];
 
 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST  0x8
 
 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST  0x8
+#define NWI_IFSTATE_FLAGS_HAS_SIGNATURE        0x10
+
+#define        NWI_PTR(type, name)                             \
+       union {                                         \
+               type            name;                   \
+               uint64_t        _ ## name ## _p;        \
+       }
 
 typedef uint32_t        Rank;
 
 
 typedef uint32_t        Rank;
 
+#pragma pack(4)
 typedef struct _nwi_ifstate {
 typedef struct _nwi_ifstate {
-       char ifname[IFNAMSIZ];
-       uint64_t flags;
-       nwi_ifstate_t af_alias;
-       Rank rank;
-       int af;
+       char                    ifname[IFNAMSIZ];
+       uint64_t                flags;
+       NWI_PTR(nwi_ifstate_t,  af_alias);
+       Rank                    rank;
+       sa_family_t             af;
        union {
        union {
-               struct in_addr iaddr;
-               struct in6_addr iaddr6;
+           struct in_addr      iaddr;
+           struct in6_addr     iaddr6;
        };
        };
-       const char* diff_ch;
+       NWI_PTR(const char *,   diff_str);
+       uint64_t                if_generation_count;
+       uint32_t                reach_flags;
+       union {
+           struct sockaddr_in  vpn_server_address4;
+           struct sockaddr_in6 vpn_server_address6;
+       } vpn_server_address;
+       unsigned char           signature[CC_SHA1_DIGEST_LENGTH];
 } nwi_ifstate;
 } nwi_ifstate;
+#pragma pack()
 
 /*
  * nwi_state
 
 /*
  * nwi_state
@@ -71,7 +88,16 @@ typedef struct _nwi_ifstate {
  *| ipv6_start                                  |-------+
  *|                                             |       |
  *|---------------------------------------------+       |ipv6_start stores the index of the start of the v6 list.
  *| ipv6_start                                  |-------+
  *|                                             |       |
  *|---------------------------------------------+       |ipv6_start stores the index of the start of the v6 list.
- *| ref                                         |       |
+ *| ref (reference count)                       |       |
+ *|                                             |       |
+ *|---------------------------------------------+       |
+ *| svr (TRUE if copied from server)            |       |
+ *|                                             |       |
+ *|---------------------------------------------+       |
+ *| reach_flags_v4                              |       |
+ *|                                             |       |
+ *|---------------------------------------------+       |
+ *| reach_flags_v6                              |       |
  *|                                             |       |
  *|---------------------------------------------+       |
  *| IPv4 nwi_ifstates                           |       |
  *|                                             |       |
  *|---------------------------------------------+       |
  *| IPv4 nwi_ifstates                           |       |
@@ -92,21 +118,26 @@ typedef struct _nwi_ifstate {
  *|---------------------------------------------+
  *
  */
  *|---------------------------------------------+
  *
  */
+#pragma pack(4)
 typedef struct _nwi_state {
 typedef struct _nwi_state {
-       uint64_t generation_count;
-       uint32_t size;
-       uint32_t ipv4_count;
-       uint32_t ipv6_count;
-       uint32_t ipv6_start;
-       uint32_t ref;
-       nwi_ifstate nwi_ifstates[0];
+       uint64_t        generation_count;
+       uint32_t        size;
+       uint32_t        ipv4_count;
+       uint32_t        ipv6_count;
+       uint32_t        ipv6_start;
+       uint32_t        ref;
+       _Bool           svr;
+       uint32_t        reach_flags_v4;
+       uint32_t        reach_flags_v6;
+       nwi_ifstate     nwi_ifstates[0];
 } nwi_state;
 } nwi_state;
+#pragma pack()
 
 static __inline__ int
 uint32_cmp(uint32_t a, uint32_t b)
 {
        int             ret;
 
 static __inline__ int
 uint32_cmp(uint32_t a, uint32_t b)
 {
        int             ret;
-       
+
        if (a == b) {
                ret = 0;
        }
        if (a == b) {
                ret = 0;
        }
@@ -203,50 +234,73 @@ nwi_state_get_ifstate_with_name(nwi_state_t state,
        return (NULL);
 }
 
        return (NULL);
 }
 
-__private_extern__
+static __inline__
+void
+_nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate, struct sockaddr *serv_addr)
+{
+       size_t len;
+
+       if (serv_addr == NULL) {
+               bzero(&ifstate->vpn_server_address,
+                     sizeof(ifstate->vpn_server_address));
+               return;
+       }
+
+       len = serv_addr->sa_len;
+
+       if (len == 0 || len > sizeof(ifstate->vpn_server_address)) {
+               return;
+       }
+
+       memcpy(&ifstate->vpn_server_address,
+              serv_addr,
+              len);
+       return;
+
+}
+
+static __inline__
+void
+_nwi_state_set_reachability_flags(nwi_state_t state, uint32_t reach_flags_v4, uint32_t reach_flags_v6)
+{
+       state->reach_flags_v4 = reach_flags_v4;
+       state->reach_flags_v6 = reach_flags_v6;
+       return;
+}
+
 nwi_state_t
 nwi_state_new(nwi_state_t old_state, int elems);
 
 nwi_state_t
 nwi_state_new(nwi_state_t old_state, int elems);
 
-__private_extern__
 nwi_state_t
 nwi_state_copy_priv(nwi_state_t old_state);
 
 nwi_state_t
 nwi_state_copy_priv(nwi_state_t old_state);
 
-__private_extern__
-void
+nwi_ifstate_t
 nwi_insert_ifstate(nwi_state_t state, const char* ifname, int af,
                   uint64_t flags, Rank rank,
 nwi_insert_ifstate(nwi_state_t state, const char* ifname, int af,
                   uint64_t flags, Rank rank,
-                  void * ifa);
+                  void * ifa, struct sockaddr * vpn_server_addr, uint32_t reach_flags);
+
+void
+nwi_ifstate_set_signature(nwi_ifstate_t ifstate, uint8_t * signature);
 
 
-__private_extern__
 void
 nwi_state_clear(nwi_state_t state, int af);
 
 void
 nwi_state_clear(nwi_state_t state, int af);
 
-__private_extern__
 void
 nwi_state_set_last(nwi_state_t state, int af);
 
 void
 nwi_state_set_last(nwi_state_t state, int af);
 
-__private_extern__
 nwi_state_t
 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state);
 
 nwi_state_t
 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state);
 
-__private_extern__
 void *
 nwi_ifstate_get_address(nwi_ifstate_t ifstate);
 
 void *
 nwi_ifstate_get_address(nwi_ifstate_t ifstate);
 
-__private_extern__
 const char *
 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate);
 
 const char *
 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate);
 
-__private_extern__
-_Bool
-_nwi_state_store(nwi_state_t state);
-
-__private_extern__
-nwi_state_t
-_nwi_state_copy(void);
+void
+_nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state, nwi_state_t changes);
 
 
-__private_extern__
 void
 void
-_nwi_state_dump(int level, nwi_state_t state);
+_nwi_state_force_refresh();
 
 #endif
 
 #endif
diff --git a/nwi/network_information_server.c b/nwi/network_information_server.c
new file mode 100644 (file)
index 0000000..00c9ff3
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2012, 2013 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
+ *
+ * February 8, 2012            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <notify.h>
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+#include <CommonCrypto/CommonDigest.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCPrivate.h>
+
+#include "libSystemConfiguration_client.h"
+#include "libSystemConfiguration_server.h"
+
+#include <network_information.h>
+#include "network_information_priv.h"
+#include "network_information_server.h"
+
+
+#pragma mark -
+#pragma mark Globals
+
+
+/*
+ * S_nwi_info
+ *
+ * Note: all accesses should be made while running on the _nwi_server_queue()
+ */
+static libSC_info_server_t     S_nwi_info;
+
+
+/*
+ * S_debug
+ *   A boolean that enables additional logging.
+ */
+static Boolean         *S_debug        = NULL;
+static SCLoggerRef     S_logger        = NULL;
+
+
+/*
+ * S_sync_handler
+ *     ACK (in-sync or not-in-sync) updates should be posted using
+ *     this handler
+ *
+ * Note: all accesses should be made while running on the _nwi_server_queue()
+ */
+static _nwi_sync_handler_t     S_sync_handler  = NULL;
+
+
+#pragma mark -
+#pragma mark Support functions
+
+
+#ifdef NOT_YET_NEEDED
+static void
+log_xpc_object(const char *msg, xpc_object_t obj)
+{
+       char            *desc;
+
+       desc = xpc_copy_description(obj);
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, "%s = %s", msg, desc);
+       }
+       free(desc);
+}
+#endif
+
+
+#pragma mark -
+#pragma mark Network information server "main"
+
+
+static dispatch_queue_t
+_nwi_state_server_queue()
+{
+       static dispatch_once_t  once;
+       static dispatch_queue_t q;
+
+       dispatch_once(&once, ^{
+               q = dispatch_queue_create(NWI_SERVICE_NAME ".server", NULL);
+       });
+
+       return q;
+}
+
+
+/*
+ * _nwi_state_copy
+ *
+ * Called when a client wants a copy of the current
+ * Network information
+ *
+ * - caller must be running on the _nwi_server_queue()
+ */
+static void
+_nwi_state_copy(xpc_connection_t connection, xpc_object_t request)
+{
+       CFDataRef               data;
+       uint64_t                generation;
+       xpc_connection_t        remote;
+       xpc_object_t            reply;
+
+       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);
+               return;
+       }
+
+       // extract data and generation #
+       data = _libSC_info_server_get_data(&S_nwi_info, connection, &generation);
+
+       if (*S_debug) {
+               const char      *proc_name;
+
+               // extract process name
+               proc_name = xpc_dictionary_get_string(request, NWI_PROC_NAME);
+               if (proc_name == NULL) {
+                       proc_name = "???";
+               }
+
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%s[%d]> Network information copy: %lu"),
+                           connection,
+                           proc_name,
+                           xpc_connection_get_pid(connection),
+                           generation);
+       }
+
+       // return the Network information (if available)
+       if (data != NULL) {
+               xpc_dictionary_set_data(reply,
+                                       NWI_CONFIGURATION,
+                                       CFDataGetBytePtr(data),
+                                       CFDataGetLength(data));
+       }
+
+       // reply
+       xpc_connection_send_message(remote, reply);
+       xpc_release(reply);
+
+       return;
+}
+
+
+/*
+ * _nwi_state_acknowledge
+ *
+ * Called when a client wants to acknowledge processing
+ * of the Network information
+ *
+ * - caller must be running on the _nwi_server_queue()
+ */
+static void
+_nwi_state_acknowledge(xpc_connection_t connection, xpc_object_t request)
+{
+       Boolean         changed;
+       uint64_t        generation;
+
+       generation = xpc_dictionary_get_uint64(request, NWI_GENERATION);
+
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%d> Network information ack: %lu"),
+                           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);
+       }
+
+       return;
+}
+
+
+static void
+process_request(xpc_connection_t connection, xpc_object_t request)
+{
+       int64_t         op;
+
+       op = xpc_dictionary_get_int64(request, NWI_REQUEST);
+       switch (op) {
+               case NWI_REQUEST_COPY :
+                       /*
+                        * Return the Network information
+                        */
+                       _nwi_state_copy(connection, request);
+                       break;
+
+               case NWI_REQUEST_ACKNOWLEDGE :
+                       /*
+                        * Acknowlege a [processed] Network information
+                        */
+                       _nwi_state_acknowledge(connection, request);
+
+                       break;
+               default :
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("<%p> unknown request : %d"),
+                                   connection,
+                                   op);
+
+                       break;
+       }
+
+       return;
+}
+
+
+static void
+process_new_connection(xpc_connection_t c)
+{
+       if (*S_debug) {
+               SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%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) {
+               xpc_type_t      type;
+
+               type = xpc_get_type(xobj);
+               if (type == XPC_TYPE_DICTIONARY) {
+                       // process the request
+                       process_request(c, xobj);
+
+               } else if (type == XPC_TYPE_ERROR) {
+                       const char      *desc;
+
+                       desc = xpc_dictionary_get_string(xobj, XPC_ERROR_KEY_DESCRIPTION);
+                       if (xobj == XPC_ERROR_CONNECTION_INVALID) {
+                               Boolean         changed;
+
+                               if (*S_debug) {
+                                       SCLoggerLog(S_logger, LOG_INFO, CFSTR("<%p:%d> Network information session: close"),
+                                                   c,
+                                                   xpc_connection_get_pid(c));
+                               }
+
+                               changed = _libSC_info_server_close(&S_nwi_info, c);
+                               if (changed) {
+                                       Boolean         inSync;
+
+                                       // report change
+                                       inSync = _libSC_info_server_in_sync(&S_nwi_info);
+                                       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);
+
+                       } else {
+                               SCLoggerLog(S_logger, LOG_ERR,
+                                           CFSTR("<%p:%d> Connection error: %d : %s"),
+                                           c,
+                                           xpc_connection_get_pid(c),
+                                           xobj,
+                                           desc);
+                       }
+
+               }  else {
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("<%p:%d> unknown event type : %x"),
+                                   c,
+                                   xpc_connection_get_pid(c),
+                                   type);
+               }
+       });
+
+       xpc_connection_resume(c);
+
+       return;
+}
+
+
+#pragma mark -
+#pragma mark Network Information server SPIs
+
+
+__private_extern__
+void
+load_NetworkInformation(CFBundleRef            bundle,
+                       SCLoggerRef             logger,
+                       Boolean                 *bundleVerbose,
+                       _nwi_sync_handler_t     syncHandler)
+{
+       xpc_connection_t        c;
+       const char              *name;
+
+       S_debug = bundleVerbose;
+       S_logger = logger;
+
+       /*
+        * keep track of Network information acknowledgements
+        */
+       _libSC_info_server_init(&S_nwi_info);
+
+       /*
+        * save the in-sync/not-in-sync handler
+        */
+       S_sync_handler = Block_copy(syncHandler);
+
+       // create XPC listener
+       name = getenv(NWI_SERVICE_NAME);
+       if (name == NULL) {
+               name = NWI_SERVICE_NAME;
+       }
+
+       c = xpc_connection_create_mach_service(name,
+                                              _nwi_state_server_queue(),
+                                              XPC_CONNECTION_MACH_SERVICE_LISTENER);
+
+       xpc_connection_set_event_handler(c, ^(xpc_object_t event) {
+               xpc_type_t      type;
+
+               type = xpc_get_type(event);
+               if (type == XPC_TYPE_CONNECTION) {
+                       process_new_connection(event);
+
+               } else if (type == XPC_TYPE_ERROR) {
+                       const char      *desc;
+
+                       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);
+                               xpc_release(c);
+                       } else if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
+                               SCLoggerLog(S_logger, LOG_ERR, CFSTR("Network information server: %s"), desc);
+                       } else {
+                               SCLoggerLog(S_logger, LOG_ERR,
+                                           CFSTR("Network information server: Connection error: %d : %s"),
+                                           event,
+                                           desc);
+                       }
+
+               } else {
+                       SCLoggerLog(S_logger, LOG_ERR,
+                                   CFSTR("Network information server: unknown event type : %x"),
+                                   type);
+
+               }
+       });
+
+       xpc_connection_resume(c);
+
+SCLoggerLog(S_logger, LOG_DEBUG, CFSTR("XPC server \"%s\" started"), name);
+
+       return;
+}
+
+
+__private_extern__
+void
+_nwi_state_signature(nwi_state         *state,
+                    unsigned char      *signature,
+                    size_t             signature_len)
+{
+       bzero(signature, signature_len);
+
+       if (state != NULL) {
+               CC_SHA1_CTX     ctx;
+               uint64_t        generation_save;
+               unsigned char   *sha1;
+               unsigned char   sha1_buf[CC_SHA1_DIGEST_LENGTH];
+
+               generation_save = state->generation_count;
+               state->generation_count = 0;
+
+               sha1 = (signature_len >= CC_SHA1_DIGEST_LENGTH) ? signature : sha1_buf;
+               CC_SHA1_Init(&ctx);
+               CC_SHA1_Update(&ctx,
+                              state,
+                              state->size);
+               CC_SHA1_Final(sha1, &ctx);
+               if (sha1 != signature) {
+                       bcopy(sha1, signature, signature_len);
+               }
+
+               state->generation_count = generation_save;
+       }
+
+       return;
+}
+
+
+__private_extern__
+_Bool
+_nwi_state_store(nwi_state *state)
+{
+       Boolean         in_sync;
+       uint64_t        new_generation  = 0;
+       CFDataRef       new_nwi_info    = NULL;
+       const char      *notify_key;
+
+       if (state != NULL) {
+               const UInt8     *bytes;
+               CFIndex         len;
+
+               new_generation = state->generation_count;
+
+               if (*S_debug) {
+                       SCLoggerLog(S_logger, LOG_INFO, CFSTR("Network information updated: %llu"),
+                                   new_generation);
+               }
+
+               bytes = (const UInt8 *)state;
+               len = state->size;
+
+               new_nwi_info = CFDataCreate(NULL, bytes, len);
+       }
+
+       dispatch_sync(_nwi_state_server_queue(), ^{
+               _libSC_info_server_set_data(&S_nwi_info, new_nwi_info, new_generation);
+       });
+
+       if (new_nwi_info != NULL) {
+               CFRelease(new_nwi_info);
+       }
+
+       // 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);
+
+       // and let everyone else know that the configuration has been updated
+       notify_key = nwi_state_get_notify_key();
+       if (notify_key != NULL) {
+               uint32_t        status;
+
+               _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);
+                       // notification posting failures are non-fatal
+               }
+       }
+
+       return TRUE;
+}
+
+
+#pragma mark -
+#pragma mark Testing
+
+
+#ifdef  MAIN
+
+int
+main(int argc, char **argv)
+{
+       static Boolean verbose = (argc > 1) ? TRUE : FALSE;
+       //      _sc_log     = FALSE;
+       _sc_verbose = (argc > 1) ? TRUE : FALSE;
+       _sc_debug   = TRUE;
+
+       load_NetworkInformation(CFBundleGetMainBundle(),        // bundle
+                               NULL,                           // SCLogger
+                               &verbose,                       // bundleVerbose
+                               ^(Boolean inSync) {             // sync handler
+                                     SCLoggerLog(NULL, LOG_INFO,
+                                           CFSTR("in sync: %s"),
+                                           inSync ? "Yes" : "No");
+                               });
+       CFRunLoopRun();
+       /* not reached */
+       exit(0);
+       return 0;
+}
+
+#endif  /* MAIN */
diff --git a/nwi/network_information_server.h b/nwi/network_information_server.h
new file mode 100644 (file)
index 0000000..bdd8b34
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 2013 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 _S_NETWORK_INFORMATION_SERVER_H
+#define _S_NETWORK_INFORMATION_SERVER_H
+
+#include <sys/cdefs.h>
+#include <stdbool.h>
+#include <mach/mach.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <network_information.h>
+
+typedef void (^_nwi_sync_handler_t)(Boolean inSync);
+
+__BEGIN_DECLS
+
+void
+load_NetworkInformation                (CFBundleRef            bundle,
+                                SCLoggerRef            logger,
+                                Boolean                *bundleVerbose,
+                                _nwi_sync_handler_t    syncHandler);
+
+void
+_nwi_state_signature           (nwi_state_t            state,
+                                unsigned char          *signature,
+                                size_t                 signature_len);
+
+_Bool
+_nwi_state_store               (nwi_state_t            state);
+
+__END_DECLS
+
+#endif /* !_S_NETWORK_INFORMATION_SERVER_H */
index 4d9e2780fef1526a18a8fea2b3beb22c9bb334ea..a5319b715e4ebcedef91ab8ae77c9cbaee355e25 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2009, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -49,7 +49,7 @@
 #include <SystemConfiguration/SCPrivate.h>
 
 #if    !TARGET_OS_IPHONE
 #include <SystemConfiguration/SCPrivate.h>
 
 #if    !TARGET_OS_IPHONE
-#include <Security/AuthSession.h>
+#include <Security/Authorization.h>
 #endif /* !TARGET_OS_IPHONE */
 
 
 #endif /* !TARGET_OS_IPHONE */
 
 
@@ -73,94 +73,6 @@ usage(const char *command)
 }
 
 
 }
 
 
-static Boolean
-isAdmin()
-{
-       gid_t   groups[NGROUPS_MAX];
-       int     ngroups;
-
-       if (getuid() == 0) {
-               return TRUE;    // if "root"
-       }
-
-       ngroups = getgroups(NGROUPS_MAX, groups);
-       if(ngroups > 0) {
-               struct group    *adminGroup;
-
-               adminGroup = getgrnam("admin");
-               if (adminGroup != NULL) {
-                       gid_t   adminGid = adminGroup->gr_gid;
-                       int     i;
-
-                       for (i = 0; i < ngroups; i++) {
-                               if (groups[i] == adminGid) {
-                                       return TRUE;    // if a member of group "admin"
-                               }
-                       }
-               }
-       }
-
-       return FALSE;
-}
-
-
-#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 OSStatus
-_SessionGetInfo(SecuritySessionId session, SecuritySessionId *sessionId, SessionAttributeBits *attributes)
-{
-       #undef SessionGetInfo
-       static typeof (SessionGetInfo) *dyfunc = NULL;
-       if (!dyfunc) {
-               void *image = __loadSecurity();
-               if (image) dyfunc = dlsym(image, "SessionGetInfo");
-       }
-       return dyfunc ? dyfunc(session, sessionId, attributes) : -1;
-}
-#define SessionGetInfo _SessionGetInfo
-#endif /* !TARGET_OS_IPHONE */
-
-static Boolean
-hasLocalConsoleAccess()
-{
-#if    !TARGET_OS_IPHONE
-       OSStatus                error;
-       SecuritySessionId       sessionID       = 0;
-       SessionAttributeBits    attributeBits   = 0;
-
-       error = SessionGetInfo(callerSecuritySession, &sessionID, &attributeBits);
-       if (error != noErr) {
-               /* Security check failed, must not permit access */
-               return FALSE;
-       }
-
-       return (attributeBits & (sessionHasGraphicAccess|sessionIsRemote)) == sessionHasGraphicAccess;
-#else  /* !TARGET_OS_IPHONE */
-       return TRUE;
-#endif /* !TARGET_OS_IPHONE */
-}
-
-
 int
 main(int argc, char **argv)
 {
 int
 main(int argc, char **argv)
 {
@@ -179,6 +91,13 @@ main(int argc, char **argv)
        const void              **setVals       = NULL;
        CFIndex                 i;
 
        const void              **setVals       = NULL;
        CFIndex                 i;
 
+#if    !TARGET_OS_IPHONE
+       AuthorizationRef        authorization   = NULL;
+       AuthorizationFlags      flags           = kAuthorizationFlagDefaults;
+       CFMutableDictionaryRef  options;
+       OSStatus                status;
+#endif // !TARGET_OS_IPHONE
+
        /* process any arguments */
 
        while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1) {
        /* process any arguments */
 
        while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1) {
@@ -228,12 +147,37 @@ main(int argc, char **argv)
                newSet = CFRetain(CFSTR(""));
        }
 
                newSet = CFRetain(CFSTR(""));
        }
 
+#if    !TARGET_OS_IPHONE
+       status = AuthorizationCreate(NULL,
+                                    kAuthorizationEmptyEnvironment,
+                                    flags,
+                                    &authorization);
+       if (status != errAuthorizationSuccess) {
+               SCPrint(TRUE,
+                       stderr,
+                       CFSTR("AuthorizationCreate() failed: status = %d\n"),
+                       status);
+               exit (1);
+       }
 
 
-       prefs = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL);
+       options = CFDictionaryCreateMutable(NULL,
+                                           0,
+                                           &kCFTypeDictionaryKeyCallBacks,
+                                           &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(options, kSCPreferencesOptionChangeNetworkSet, kCFBooleanTrue);
+       prefs = SCPreferencesCreateWithOptions(NULL, CFSTR("scselect"), NULL, authorization, options);
+       CFRelease(options);
        if (prefs == NULL) {
                SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
                exit (1);
        }
        if (prefs == NULL) {
                SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
                exit (1);
        }
+#else  // !TARGET_OS_IPHONE
+       prefs = SCPreferencesCreate(NULL, CFSTR("scselect"), NULL);
+       if (prefs == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
+               exit (1);
+       }
+#endif // !TARGET_OS_IPHONE
 
        sets = SCPreferencesGetValue(prefs, kSCPrefSets);
        if (sets == NULL) {
 
        sets = SCPreferencesGetValue(prefs, kSCPrefSets);
        if (sets == NULL) {
@@ -330,35 +274,43 @@ main(int argc, char **argv)
                        break;
        }
 
                        break;
        }
 
+       CFRelease(prefix);
        exit (0);
 
     found :
 
        exit (0);
 
     found :
 
-       if (!(isAdmin() || hasLocalConsoleAccess())) {
-               SCPrint(TRUE, stderr,
-                       CFSTR("Only local console users and administrators can change locations\n"));
-               exit (EX_NOPERM);
-       }
-
        CFRelease(current);
        current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
 
        if (!SCPreferencesSetValue(prefs, kSCPrefCurrentSet, current)) {
                SCPrint(TRUE, stderr,
        CFRelease(current);
        current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
 
        if (!SCPreferencesSetValue(prefs, kSCPrefCurrentSet, current)) {
                SCPrint(TRUE, stderr,
-                       CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"),
+                       CFSTR("SCPreferencesSetValue(...,%@,%@) failed: %s\n"),
                        kSCPrefCurrentSet,
                        kSCPrefCurrentSet,
-                       current);
+                       current,
+                       SCErrorString(SCError()));
                exit (1);
        }
 
        if (!SCPreferencesCommitChanges(prefs)) {
                exit (1);
        }
 
        if (!SCPreferencesCommitChanges(prefs)) {
-               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n"));
-               exit (1);
+               int     sc_status       = SCError();
+
+               if (sc_status == kSCStatusAccessError) {
+                       SCPrint(TRUE, stderr,
+                               CFSTR("Only local console users and administrators can change locations\n"));
+                       exit (EX_NOPERM);
+               } else {
+                       SCPrint(TRUE, stderr,
+                               CFSTR("SCPreferencesCommitChanges() failed: %s\n"),
+                               SCErrorString(sc_status));
+                       exit (1);
+               }
        }
 
        if (apply) {
                if (!SCPreferencesApplyChanges(prefs)) {
        }
 
        if (apply) {
                if (!SCPreferencesApplyChanges(prefs)) {
-                       SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n"));
+                       SCPrint(TRUE, stderr,
+                               CFSTR("SCPreferencesApplyChanges() failed %s\n"),
+                               SCErrorString(SCError()));
                        exit (1);
                }
        }
                        exit (1);
                }
        }
@@ -375,6 +327,11 @@ main(int argc, char **argv)
        CFRelease(prefix);
        CFRelease(prefs);
 
        CFRelease(prefix);
        CFRelease(prefs);
 
+#if    !TARGET_OS_IPHONE
+       AuthorizationFree(authorization, kAuthorizationFlagDefaults);
+//     AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
+#endif /* !TARGET_OS_IPHONE */
+
        exit (0);
        return 0;
 }
        exit (0);
        return 0;
 }
index 76fd819b716f1771ff6c5b4a2f320db7ea5dfb51..b8016e78367ddfa92c459415cecdf3616f085c59 100644 (file)
@@ -296,7 +296,7 @@ do_list(int argc, char **argv)
                        CFIndex n;
 
                        n = CFDictionaryGetCount(cached_set);
                        CFIndex n;
 
                        n = CFDictionaryGetCount(cached_set);
-                       if (n > 0){
+                       if (n > 0) {
                                const void *    cachedKeys_q[N_QUICK];
                                const void **   cachedKeys      = cachedKeys_q;
 
                                const void *    cachedKeys_q[N_QUICK];
                                const void **   cachedKeys      = cachedKeys_q;
 
index 551289cff59394c458efb77d136d7f7b84795da6..76ba1deb45d566c2e367a8e45c1bef8ee76dcc41 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2010-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2010-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include "nc.h"
 #include "prefs.h"
 
 #include "nc.h"
 #include "prefs.h"
 
+#include <SystemConfiguration/VPNConfiguration.h>
+
+#if    TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+#include <MobileInstallation/MobileInstallation.h>
+#endif // TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+
 #include <sys/time.h>
 
 #include <sys/time.h>
 
-CFStringRef                    username = NULL;
-CFStringRef                    password = NULL;
-CFStringRef                    sharedsecret = NULL;
+CFStringRef                    username        = NULL;
+CFStringRef                    password        = NULL;
+CFStringRef                    sharedsecret    = NULL;
+
+static Boolean                 ondemandwatch   = FALSE;
+static CFStringRef             ondemand_nodename = NULL;
 
 static SCNetworkConnectionRef  connection      = NULL;
 static int                     n_callback      = 0;
 
 static SCNetworkConnectionRef  connection      = NULL;
 static int                     n_callback      = 0;
@@ -143,7 +152,7 @@ nc_copy_service_from_arguments(int argc, char **argv, SCNetworkSetRef set) {
        SCNetworkServiceRef     service         = NULL;
 
        if (argc == 0) {
        SCNetworkServiceRef     service         = NULL;
 
        if (argc == 0) {
-               serviceID = _copyStringFromSTDIN();
+               serviceID = _copyStringFromSTDIN(CFSTR("Service"), NULL);
        } else {
                serviceID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
        } else {
                serviceID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
@@ -242,6 +251,70 @@ nc_create_connection(int argc, char **argv, Boolean exit_on_failure)
        }
 }
 
        }
 }
 
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+
+static void
+nc_trigger(int argc, char **argv)
+{
+       Boolean         background      = FALSE;
+       int             i;
+       CFStringRef     hostName        = NULL;
+       int             port            = 80;
+
+       for (i = 0; i < 3 && i < argc; i++) {
+               /* Parse host name. Must be first arg. */
+               if (i == 0) {
+                       hostName = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8);
+                       continue;
+               }
+
+               /* Check for optional background flag */
+               if (strcmp(argv[i], "background") == 0) {
+                       background = TRUE;
+                       continue;
+               }
+
+               /* Parse optional port number */
+               CFStringRef str = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8);
+               if (str) {
+                       int num = CFStringGetIntValue(str);
+                       if (num) {
+                               port = num;
+                       }
+                       my_CFRelease(&str);
+               }
+       }
+
+       if (hostName) {
+               CFReadStreamRef         readStream      = NULL;
+               CFWriteStreamRef        writeStream     = NULL;
+
+               CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostName, port, &readStream, &writeStream);
+
+               if (background) {
+                       CFReadStreamSetProperty(readStream, CFSTR("kCFStreamNetworkServiceType"), CFSTR("kCFStreamNetworkServiceTypeBackground"));
+                       CFWriteStreamSetProperty(writeStream, CFSTR("kCFStreamNetworkServiceType"), CFSTR("kCFStreamNetworkServiceTypeBackground"));
+               }
+
+               if (readStream && writeStream) {
+                       CFReadStreamOpen(readStream);
+                       CFWriteStreamOpen(writeStream);
+                       SCPrint(TRUE, stdout, CFSTR("Opened stream to %@, port %d%s\n"), hostName, port, background ? ", background traffic class" : "");
+                       sleep(1);
+               }
+
+               my_CFRelease(&readStream);
+               my_CFRelease(&writeStream);
+       } else {
+               SCPrint(TRUE, stderr, CFSTR("Invalid or missing host name\n"));
+       }
+
+       my_CFRelease(&hostName);
+
+       exit(0);
+}
+
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 static void
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 static void
@@ -402,7 +475,7 @@ nc_watch(int argc, char **argv)
 
        // setup watcher
        if (doDispatch) {
 
        // setup watcher
        if (doDispatch) {
-               if (!SCNetworkConnectionSetDispatchQueue(connection, dispatch_get_current_queue())) {
+               if (!SCNetworkConnectionSetDispatchQueue(connection, dispatch_get_main_queue())) {
                        SCPrint(TRUE, stderr, CFSTR("Unable to schedule watch process: %s\n"), SCErrorString(SCError()));
                        exit(1);
                }
                        SCPrint(TRUE, stderr, CFSTR("Unable to schedule watch process: %s\n"), SCErrorString(SCError()));
                        exit(1);
                }
@@ -486,6 +559,44 @@ checkOnDemandHost(SCDynamicStoreRef store, CFStringRef nodeName, Boolean retry)
        return;
 }
 
        return;
 }
 
+static void
+nc_ondemand_callback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+{
+       CFStringRef             key             = NULL;
+       CFDictionaryRef         ondemand_dict   = NULL;
+       struct tm               tm_now;
+       struct timeval          tv_now;
+
+       if (CFArrayGetCount(changedKeys) < 1) {
+               return;
+       }
+
+       (void)gettimeofday(&tv_now, NULL);
+       (void)localtime_r(&tv_now.tv_sec, &tm_now);
+
+       SCPrint(TRUE, stdout, CFSTR("\n*** %2d:%02d:%02d.%03d\n\n"),
+               tm_now.tm_hour,
+               tm_now.tm_min,
+               tm_now.tm_sec,
+               tv_now.tv_usec / 1000);
+
+       if (ondemand_nodename) {
+               checkOnDemandHost(store, ondemand_nodename, FALSE);
+               checkOnDemandHost(store, ondemand_nodename, TRUE);
+       } else {
+               key = CFArrayGetValueAtIndex(changedKeys, 0);
+
+               ondemand_dict = SCDynamicStoreCopyValue(store, key);
+               if (ondemand_dict) {
+                       SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), kSCEntNetOnDemand, ondemand_dict);
+               } else {
+                       SCPrint(TRUE, stdout, CFSTR("%@ not configured\n"), kSCEntNetOnDemand);
+               }
+
+               my_CFRelease(&ondemand_dict);
+       }
+}
+
 static void
 nc_ondemand(int argc, char **argv)
 {
 static void
 nc_ondemand(int argc, char **argv)
 {
@@ -494,28 +605,64 @@ nc_ondemand(int argc, char **argv)
        CFDictionaryRef         ondemand_dict   = NULL;
        SCDynamicStoreRef       store;
 
        CFDictionaryRef         ondemand_dict   = NULL;
        SCDynamicStoreRef       store;
 
-       store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), NULL, NULL);
+       store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), nc_ondemand_callback, NULL);
        if (store == NULL) {
                SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError()));
                goto done;
        }
 
        if (store == NULL) {
                SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError()));
                goto done;
        }
 
-       if (argc > 0) {
-               CFStringRef     nodeName;
+       if (argc == 1) {
+#if    !TARGET_IPHONE_SIMULATOR
+               if (strcmp("--refresh", argv[0]) == 0) {
+                       SCNetworkConnectionRef  connection      = NULL;
+
+                       connection = SCNetworkConnectionCreate(kCFAllocatorDefault, NULL, NULL);
+                       if (connection && SCNetworkConnectionRefreshOnDemandState(connection)) {
+                               exit_code = 0;
+                       }
+
+                       if (exit_code) {
+                               SCPrint(TRUE, stderr, CFSTR("Unable to refresh OnDemand state: %s\n"), SCErrorString(SCError()));
+                       }
 
 
-               nodeName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
-               checkOnDemandHost(store, nodeName, FALSE);
-               checkOnDemandHost(store, nodeName, TRUE);
+                       my_CFRelease(&connection);
+                       goto done;
+               }
+#endif // !TARGET_IPHONE_SIMULATOR
+
+               ondemand_nodename = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+       } else if (argc != 0) {
+               SCPrint(TRUE, stderr, CFSTR("Usage: scutil --nc ondemand [-W] [hostname]\n"
+                                           "       scutil --nc ondemand -- --refresh\n"));
                goto done;
        }
 
        key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetOnDemand);
 
                goto done;
        }
 
        key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetOnDemand);
 
-       ondemand_dict = SCDynamicStoreCopyValue(store, key);
-       if (ondemand_dict) {
-               SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), kSCEntNetOnDemand, ondemand_dict);
+       if (ondemand_nodename) {
+               checkOnDemandHost(store, ondemand_nodename, FALSE);
+               checkOnDemandHost(store, ondemand_nodename, TRUE);
        } else {
        } else {
-               SCPrint(TRUE, stdout, CFSTR("%@ not configured\n"), kSCEntNetOnDemand);
+               ondemand_dict = SCDynamicStoreCopyValue(store, key);
+               if (ondemand_dict) {
+                       SCPrint(TRUE, stdout, CFSTR("%@ %@\n"), kSCEntNetOnDemand, ondemand_dict);
+               } else {
+                       SCPrint(TRUE, stdout, CFSTR("%@ not configured\n"), kSCEntNetOnDemand);
+               }
+       }
+
+       if (ondemandwatch) {
+               CFMutableArrayRef       keys    = NULL;
+
+               keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               CFArrayAppendValue(keys, key);
+               SCDynamicStoreSetNotificationKeys(store, keys, NULL);
+
+               my_CFRelease(&keys);
+
+               SCDynamicStoreSetDispatchQueue(store, dispatch_get_main_queue());
+
+               CFRunLoopRun();
        }
 
        exit_code = 0;
        }
 
        exit_code = 0;
@@ -523,63 +670,97 @@ done:
        my_CFRelease(&ondemand_dict);
        my_CFRelease(&key);
        my_CFRelease(&store);
        my_CFRelease(&ondemand_dict);
        my_CFRelease(&key);
        my_CFRelease(&store);
+       my_CFRelease(&ondemand_nodename);
        exit(exit_code);
 }
 
 
 /* -----------------------------------------------------------------------------
  ----------------------------------------------------------------------------- */
        exit(exit_code);
 }
 
 
 /* -----------------------------------------------------------------------------
  ----------------------------------------------------------------------------- */
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-
 CFStringRef
 CFStringRef
-copy_padded_string(CFStringRef original, int width)
+copy_padded_string(CFStringRef original, int width, CFStringRef prefix, CFStringRef suffix)
 {
        CFMutableStringRef      padded;
 
 {
        CFMutableStringRef      padded;
 
-       padded = CFStringCreateMutableCopy(NULL, 0, original);
+       padded = CFStringCreateMutable(NULL, 0);
+       if (prefix != NULL) {
+               CFStringAppend(padded, prefix);
+       }
+       if (original != NULL) {
+               CFStringAppend(padded, original);
+       }
+       if (suffix != NULL) {
+               CFStringAppend(padded, suffix);
+       }
        CFStringPad(padded, CFSTR(" "), MAX(CFStringGetLength(original), width), 0);
        return padded;
 }
 
        CFStringPad(padded, CFSTR(" "), MAX(CFStringGetLength(original), width), 0);
        return padded;
 }
 
+CFStringRef
+copy_VPN_status(SCNetworkServiceRef service)
+{
+       CFStringRef output = NULL;
+       SCNetworkConnectionStatus status = kSCNetworkConnectionInvalid;
+       SCNetworkConnectionRef service_connection = NULL;
+
+       /* Only calculate status is the service is enabled. Default is invalid. */
+       if (SCNetworkServiceGetEnabled(service)) {
+               service_connection = SCNetworkConnectionCreateWithService(NULL, service, NULL, NULL);
+               if (service_connection == NULL) goto done;
+               status = SCNetworkConnectionGetStatus(service_connection);
+       }
+
+       output = CFStringCreateWithCString(NULL, nc_status_string(status), kCFStringEncodingUTF8);
+
+done:
+       my_CFRelease(&service_connection);
+       return output;
+}
 
 static void
 nc_print_VPN_service(SCNetworkServiceRef service)
 {
 
 static void
 nc_print_VPN_service(SCNetworkServiceRef service)
 {
-       CFStringRef type = NULL;
+       SCNetworkInterfaceRef interface = NULL;
+       CFStringRef display_name = NULL;
+       CFStringRef display_name_padded = NULL;
+       CFStringRef service_id = NULL;
+       CFStringRef service_name = NULL;
+       CFStringRef service_name_padded = NULL;
+       CFStringRef service_status = NULL;
+       CFStringRef service_status_padded = NULL;
        CFStringRef sub_type = NULL;
        CFStringRef sub_type = NULL;
+       CFStringRef type = NULL;
 
        nc_get_service_type_and_subtype(service, &type, &sub_type);
 
 
        nc_get_service_type_and_subtype(service, &type, &sub_type);
 
-       CFStringRef service_name = SCNetworkServiceGetName(service);
-       if (service_name == NULL)
-               service_name = CFSTR("");
-       CFStringRef service_name_quoted = CFStringCreateWithFormat(NULL, NULL, CFSTR("\"%@\""), service_name);
-       if (service_name_quoted == NULL) {
-               service_name_quoted = CFRetain(CFSTR(""));
-       }
-       CFStringRef service_name_padded = copy_padded_string(service_name, 30);
+       service_name = SCNetworkServiceGetName(service);
+       service_name_padded = copy_padded_string(service_name, 32, CFSTR("\""), CFSTR("\""));
 
 
-       CFStringRef service_id   = SCNetworkServiceGetServiceID(service);
-       SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
-       CFStringRef display_name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
-       if (display_name == NULL)
-               display_name = CFSTR("");
-       CFStringRef display_name_padded = copy_padded_string(display_name, 18);
+       service_id = SCNetworkServiceGetServiceID(service);
 
 
+       interface = SCNetworkServiceGetInterface(service);
+       display_name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+       display_name_padded = copy_padded_string(display_name, 18, NULL, NULL);
+
+       service_status = copy_VPN_status(service);
+       service_status_padded = copy_padded_string(service_status, 16, CFSTR("("), CFSTR(")"));
 
        SCPrint(TRUE,
                stdout,
 
        SCPrint(TRUE,
                stdout,
-               CFSTR("%@  %@ %@ %@ [%@%@%@]\n"),
+               CFSTR("%@ %@ %@ %@ %@ [%@%@%@]\n"),
                SCNetworkServiceGetEnabled(service) ? CFSTR("*") : CFSTR(" "),
                SCNetworkServiceGetEnabled(service) ? CFSTR("*") : CFSTR(" "),
+               service_status_padded,
                service_id,
                display_name_padded,
                service_name_padded,
                type,
                (sub_type == NULL) ? CFSTR("") : CFSTR(":"),
                (sub_type == NULL) ? CFSTR("") : sub_type);
                service_id,
                display_name_padded,
                service_name_padded,
                type,
                (sub_type == NULL) ? CFSTR("") : CFSTR(":"),
                (sub_type == NULL) ? CFSTR("") : sub_type);
-       CFRelease(service_name_quoted);
+
        CFRelease(display_name_padded);
        CFRelease(service_name_padded);
        CFRelease(display_name_padded);
        CFRelease(service_name_padded);
+       CFRelease(service_status_padded);
+       my_CFRelease(&service_status);
 }
 
 
 }
 
 
@@ -609,22 +790,309 @@ nc_list(int argc, char **argv)
        exit(0);
 }
 
        exit(0);
 }
 
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+static Boolean
+nc_enable_vpntype(CFStringRef vpnType)
+{
+       Boolean                 is_enabled = FALSE;
+       Boolean                 success = FALSE;
+
+       if (vpnType == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("No VPN type provided\n"));
+               goto done;
+       }
+
+       is_enabled = VPNConfigurationIsVPNTypeEnabled(vpnType);
+
+       if (is_enabled) {
+               SCPrint(TRUE, stdout, CFSTR("VPN is already enabled\n"));
+       } else {
+#if    !TARGET_OS_IPHONE
+               AuthorizationRef        authorization;
+
+               authorization = _prefs_AuthorizationCreate();
+               if ((authorization == NULL) ||
+                   !VPNConfigurationSetAuthorization(authorization)) {
+                       SCPrint(TRUE, stderr, CFSTR("VPNConfigurationSetAuthorization failed: %s\n"), SCErrorString(SCError()));
+                       goto done;
+               }
+#endif // !TARGET_OS_IPHONE
+
+               if (!VPNConfigurationEnableVPNType(vpnType)) {
+                       SCPrint(TRUE, stderr, CFSTR("VPN could not be enabled: %s\n"), SCErrorString(SCError()));
+                       goto done;
+               }
+
+#if    !TARGET_OS_IPHONE
+               _prefs_AuthorizationFree(authorization);
+#endif // !TARGET_OS_IPHONE
+
+               SCPrint(TRUE, stdout, CFSTR("VPN enabled\n"));
+       }
+       success = TRUE;
+
+done:
+       return success;
+}
+
+/* Turns a service ID or name into a vendor type, or preserves type */
+static CFStringRef
+nc_copy_vendor_type (CFStringRef input)
+{
+       SCNetworkInterfaceRef   child;
+       SCNetworkInterfaceRef   interface;
+       CFStringRef             output_name     = input;
+       SCNetworkServiceRef     service         = NULL;
+       CFStringRef             type;
+
+       if (input == NULL) {
+               goto done;
+       }
+
+       service = nc_copy_service(NULL, input);
+       if (service != NULL) {
+               interface = SCNetworkServiceGetInterface(service);
+               child = SCNetworkInterfaceGetInterface(interface);
+               type = SCNetworkInterfaceGetInterfaceType(interface);
+
+               /* Must be of type VPN */
+               if (!CFEqual(type, kSCNetworkInterfaceTypeVPN)) {
+                       output_name = NULL;
+                       goto done;
+               }
+               output_name = SCNetworkInterfaceGetInterfaceType(child);
+               goto done;
+       }
+
+done :
+       if (output_name != NULL) CFRetain(output_name);
+       my_CFRelease(&service);
+       return output_name;
+}
+
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+#if !TARGET_OS_IPHONE
+static const CFStringRef PREF_PREFIX                       = CFSTR("VPN-");
+static const CFStringRef PREF_SUFFIX                       = CFSTR(".plist");
+static void
+nc_set_application_url(CFStringRef subtype, CFStringRef directory)
+{
+       CFURLRef        directory_url           = NULL;
+       CFDataRef       directory_url_data      = NULL;
+       CFStringRef     vpnprefpath             = NULL;
+       char           *path                    = NULL;
+       CFIndex         path_len                = 0;
+
+       if (subtype == NULL || directory == NULL) {
+               goto done;
+       }
+
+       directory_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+                                                     directory,
+                                                     kCFURLPOSIXPathStyle,
+                                                     FALSE);
+       if (directory_url == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("CFURLCreateWithFileSystemPath failed\n"));
+               goto done;
+       }
+
+       directory_url_data = CFURLCreateBookmarkData(NULL, directory_url, 0, 0, 0, 0);
+       if (directory_url_data == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("CFURLCreateBookmarkData failed\n"));
+               goto done;
+       }
+
+       vpnprefpath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@"), PREF_PREFIX, subtype, PREF_SUFFIX );
+       if (vpnprefpath == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("CFStringCreateWithFormat failed\n"));
+               goto done;
+       }
+
+       path_len = CFStringGetLength(vpnprefpath) + 1;
+       path = malloc(path_len);
+       if (path == NULL) {
+               goto done;
+       }
+
+       if (!CFStringGetCString(vpnprefpath, path, path_len, kCFStringEncodingASCII)) {
+               SCPrint(TRUE, stderr, CFSTR("CFStringGetCString failed\n"));
+               goto done;
+       }
+
+       do_prefs_init();                /* initialization */
+       do_prefs_open(1, &path);        /* open prefs */
+
+       if (!SCPreferencesSetValue(prefs, CFSTR("ApplicationURL"), directory_url_data)) {
+               SCPrint(TRUE, stderr,
+                       CFSTR("SCPreferencesSetValue ApplicationURL failed, %s\n"),
+                       SCErrorString(SCError()));
+               goto done;
+       }
+
+       _prefs_save();
+
+done:
+       my_CFRelease(&directory_url);
+       my_CFRelease(&directory_url_data);
+       my_CFRelease(&vpnprefpath);
+       if (path) {
+               free(path);
+       }
+       _prefs_close();
+
+       exit(0);
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+static void
+nc_enablevpn(int argc, char **argv)
+{
+       CFStringRef             argument = NULL;
+       CFStringRef             vendorType = NULL;
+       int                     exit_code = 1;
+
+       if (argc == 0) {
+               SCPrint(TRUE, stderr, CFSTR("No service type or ID\n"));
+       } else {
+               argument = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+               vendorType = nc_copy_vendor_type(argument);
+               my_CFRelease(&argument);
+
+               if (!nc_enable_vpntype(vendorType)) {
+                       goto done;
+               }
+#if !TARGET_OS_IPHONE
+               if (argc >= 2) {
+                       argument = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8);
+                       nc_set_application_url(vendorType, argument);
+                       my_CFRelease(&argument);
+               }
+#endif
+       }
+
+       exit_code = 0;
+
+done:
+       my_CFRelease(&vendorType);
+       exit(exit_code);
+}
+
+
+#if TARGET_OS_EMBEDDED
+static void
+nc_print_VPN_app_info(CFStringRef appInfo, CFDictionaryRef appInfoDict)
+{
+       CFStringRef appName = NULL;
+       Boolean isEnabled = FALSE;
+       CFStringRef paddedAppInfo = NULL;
+       CFStringRef paddedAppName = NULL;
+
+       if (appInfo == NULL) {
+               return;
+       }
+
+       isEnabled = VPNConfigurationIsVPNTypeEnabled(appInfo);
+
+       CFDictionaryGetValueIfPresent(appInfoDict, CFSTR("CFBundleDisplayName"), (const void **)&appName);
+       paddedAppName = copy_padded_string((appName == NULL) ? CFSTR("") : appName, 12, NULL, NULL);
+       paddedAppInfo = copy_padded_string(appInfo, 30, NULL, NULL);
+
+       SCPrint(TRUE, stdout, CFSTR("%@ %@ [%@]\n"),
+               isEnabled ? CFSTR("(Enabled) ") : CFSTR("(Disabled)"),
+               paddedAppName,
+               appInfo);
+
+       my_CFRelease(&paddedAppName);
+       my_CFRelease(&paddedAppInfo);
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+#if    TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+static void
+nc_listvpn(int argc, char **argv)
+{
+
+       CFDictionaryRef         appDict = NULL;
+       CFArrayRef              appinfo = NULL;
+       int                     i, j, count, subtypecount;
+       const void * *          keys = NULL;
+       CFMutableDictionaryRef optionsDict = NULL;
+       const void * *          values = NULL;
+       CFStringRef             vpntype = NULL;
+
+       optionsDict = CFDictionaryCreateMutable(NULL, 0,
+                                               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(optionsDict, kLookupApplicationTypeKey, kApplicationTypeUser);
+       CFDictionarySetValue(optionsDict, kLookupAttributeKey, CFSTR("UIVPNPlugin"));
+
+       appDict = MobileInstallationLookup(optionsDict);
+       if (!isA_CFDictionary(appDict))
+               goto done;
+
+       count = CFDictionaryGetCount(appDict);
+       if (count > 0) {
+               keys = (const void * *)malloc(sizeof(CFTypeRef) * count);
+               values = (const void * *)malloc(sizeof(CFTypeRef) * count);
+
+               CFDictionaryGetKeysAndValues(appDict, keys, values);
+               for (i=0; i<count; i++) {
+                       appinfo = CFDictionaryGetValue(values[i], CFSTR("UIVPNPlugin"));
+                       if (appinfo) {
+
+
+
+                               if (isA_CFString(appinfo)) {
+                                       nc_print_VPN_app_info((CFStringRef)appinfo, (CFDictionaryRef)values[i]);
+                               }
+                               else if (isA_CFArray(appinfo)) {
+                                       subtypecount = CFArrayGetCount((CFArrayRef)appinfo);
+                                       for(j=0; j<subtypecount; j++) {
+                                               vpntype = (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)appinfo, j);
+                                               nc_print_VPN_app_info(vpntype, (CFDictionaryRef)values[i]);
+                                       }
+                               }
+                       }
+               }
+       }
+done:
+       if (keys) free(keys);
+       if (values) free(values);
+       my_CFRelease(&optionsDict);
+       my_CFRelease(&appDict);
+
+       exit(0);
+}
+#endif // TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
 
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 static void
 nc_show(int argc, char **argv)
 {
 
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 static void
 nc_show(int argc, char **argv)
 {
-       SCNetworkServiceRef     service = NULL;
-       SCDynamicStoreRef       store = NULL;
-       int                     exit_code = 1;
-       CFStringRef             serviceID = NULL;
-       CFStringRef             iftype = NULL;
-       CFStringRef             ifsubtype = NULL;
-       CFStringRef             type_entity_key = NULL;
-       CFStringRef             subtype_entity_key = NULL;
-       CFDictionaryRef         type_entity_dict = NULL;
-       CFDictionaryRef         subtype_entity_dict = NULL;
+       SCNetworkServiceRef     service                 = NULL;
+       SCDynamicStoreRef       store                   = NULL;
+       int                     exit_code               = 1;
+       CFStringRef             serviceID               = NULL;
+       CFStringRef             iftype                  = NULL;
+       CFStringRef             ifsubtype               = NULL;
+       CFStringRef             type_entity_key         = NULL;
+       CFStringRef             subtype_entity_key      = NULL;
+       CFDictionaryRef         type_entity_dict        = NULL;
+       CFDictionaryRef         subtype_entity_dict     = NULL;
+       CFStringRef             vpnprefpath             = NULL;
+#if !TARGET_OS_IPHONE
+       CFDataRef               bookmarkData            = NULL;
+       CFURLRef                directory               = NULL;
+       Boolean                 isStale                 = FALSE;
+       char                    *path                   = NULL;
+       CFIndex                 path_len                = 0;
+#endif
 
        service = nc_copy_service_from_arguments(argc, argv, NULL);
        if (service == NULL) {
 
        service = nc_copy_service_from_arguments(argc, argv, NULL);
        if (service == NULL) {
@@ -647,6 +1115,40 @@ nc_show(int argc, char **argv)
 
        nc_print_VPN_service(service);
 
 
        nc_print_VPN_service(service);
 
+#if !TARGET_OS_IPHONE
+       vpnprefpath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@"), PREF_PREFIX, ifsubtype, PREF_SUFFIX);
+       if (vpnprefpath == NULL) {
+               goto skipURL;
+       }
+
+       path_len = CFStringGetLength(vpnprefpath) + 1;
+       path = malloc(path_len);
+       if (path == NULL) {
+               goto skipURL;
+       }
+
+       if (!CFStringGetCString(vpnprefpath, path, path_len, kCFStringEncodingASCII)) {
+               SCPrint(TRUE, stderr, CFSTR("CFStringGetCString failed\n"));
+               goto done;
+       }
+
+       do_prefs_init();                /* initialization */
+       do_prefs_open(1, &path);        /* open prefs */
+
+       bookmarkData = SCPreferencesGetValue(prefs, CFSTR("ApplicationURL"));
+       if (bookmarkData == NULL) {
+               goto skipURL;
+       }
+
+       directory = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, bookmarkData, 0, NULL, NULL, &isStale, NULL);
+       if (directory == NULL) {
+               goto skipURL;
+       }
+
+       SCPrint(TRUE, stdout, CFSTR("ApplicationURL: %@\n"), directory);
+skipURL:
+#endif
+
        store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), NULL, NULL);
        if (store == NULL) {
                SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError()));
        store = SCDynamicStoreCreate(NULL, CFSTR("scutil --nc"), NULL, NULL);
        if (store == NULL) {
                SCPrint(TRUE, stderr, CFSTR("Unable to create dynamic store: %s\n"), SCErrorString(SCError()));
@@ -680,6 +1182,8 @@ done:
        my_CFRelease(&subtype_entity_dict);
        my_CFRelease(&store);
        my_CFRelease(&service);
        my_CFRelease(&subtype_entity_dict);
        my_CFRelease(&store);
        my_CFRelease(&service);
+       my_CFRelease(&vpnprefpath);
+       _prefs_close();
        exit(exit_code);
 }
 
        exit(exit_code);
 }
 
@@ -731,6 +1235,71 @@ done:
        exit(exit_code);
 }
 
        exit(exit_code);
 }
 
+/* -----------------------------------------------------------------------------
+ ----------------------------------------------------------------------------- */
+static void
+nc_help(int argc, char **argv)
+{
+       SCPrint(TRUE, stderr, CFSTR("Valid commands for scutil --nc (VPN connections)\n"));
+       SCPrint(TRUE, stderr, CFSTR("Usage: scutil --nc [command]\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tlist\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tList available network connection services in the current set\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tstatus <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tIndicate whether a given service is connected, as well as extended status information for the service\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tshow <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tDisplay configuration information for a given service\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tstatistics <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tProvide statistics on bytes, packets, and errors for a given service\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tselect <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tMake the given service active in the current set. This allows it to be started\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tstart <service> [--user user] [--password password] [--secret secret]\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tStart a given service. Can take optional arguments for user, password, and secret\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tstop <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tStop a given service\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tsuspend <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tSuspend a given service (PPP, Modem on Hold)\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tresume <service>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tResume a given service (PPP, Modem on Hold)\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tondemand [-W] [hostname]\n"));
+       SCPrint(TRUE, stderr, CFSTR("\tondemand -- --refresh\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tDisplay VPN on-demand information\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\ttrigger <hostname> [background] [port]\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tTrigger VPN on-demand with specified hostname, and optional port and background flag\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+#if TARGET_OS_EMBEDDED
+       SCPrint(TRUE, stderr, CFSTR("\tlistvpn\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tDisplay the installed VPN applications\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+#endif
+#if !TARGET_OS_IPHONE
+       SCPrint(TRUE, stderr, CFSTR("\tenablevpn <service or vpn type> [path]\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tEnables the given VPN application type. Takes either a service or VPN type. Pass a path to set ApplicationURL\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+#else
+       SCPrint(TRUE, stderr, CFSTR("\tenablevpn <service or vpn type>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tEnables the given VPN application type. Takes either a service or VPN type\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+#endif
+       SCPrint(TRUE, stderr, CFSTR("\tdisablevpn <service or vpn type>\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tDisables the given VPN application type. Takes either a service or VPN type\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("\thelp\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\tDisplay available commands for --nc\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       exit(0);
+}
+
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 typedef void (*nc_func) (int argc, char **argv);
 /* -----------------------------------------------------------------------------
 ----------------------------------------------------------------------------- */
 typedef void (*nc_func) (int argc, char **argv);
@@ -739,7 +1308,12 @@ static const struct {
        char            *cmd;
        nc_func         func;
 } nc_cmds[] = {
        char            *cmd;
        nc_func         func;
 } nc_cmds[] = {
+       { "enablevpn",          nc_enablevpn    },
+       { "help",               nc_help         },
        { "list",               nc_list         },
        { "list",               nc_list         },
+#if    TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+       { "listvpn",            nc_listvpn      },
+#endif // TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
        { "ondemand",           nc_ondemand     },
        { "resume",             nc_resume       },
        { "select",             nc_select       },
        { "ondemand",           nc_ondemand     },
        { "resume",             nc_resume       },
        { "select",             nc_select       },
@@ -749,6 +1323,7 @@ static const struct {
        { "status",             nc_status       },
        { "stop",               nc_stop         },
        { "suspend",            nc_suspend      },
        { "status",             nc_status       },
        { "stop",               nc_stop         },
        { "suspend",            nc_suspend      },
+       { "trigger",            nc_trigger      },
 };
 #define        N_NC_CMNDS      (sizeof(nc_cmds) / sizeof(nc_cmds[0]))
 
 };
 #define        N_NC_CMNDS      (sizeof(nc_cmds) / sizeof(nc_cmds[0]))
 
@@ -782,8 +1357,12 @@ do_nc_cmd(char *cmd, int argc, char **argv, Boolean watch)
                nc_func func;
 
                func = nc_cmds[i].func;
                nc_func func;
 
                func = nc_cmds[i].func;
-               if (watch && (func == nc_status)) {
-                       func = nc_watch;
+               if (watch) {
+                       if (func == nc_status) {
+                               func = nc_watch;
+                       } else if (func == nc_ondemand) {
+                               ondemandwatch = TRUE;
+                       }
                }
                (*func)(argc, argv);
        }
                }
                (*func)(argc, argv);
        }
index ba122042e16a110e3da0505014fae73e9c1458cf..61110c01d93cf40f854691180e0502b9c399f1f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include "net.h"
 #include "prefs.h"
 
 #include "net.h"
 #include "prefs.h"
 
-#include <SystemConfiguration/LinkConfiguration.h>
 
 
-
-#if    TARGET_OS_EMBEDDED
+#if    TARGET_OS_IPHONE
 #define        INLINE_PASSWORDS_USE_CFSTRING
 #define        INLINE_PASSWORDS_USE_CFSTRING
-#endif // TARGET_OS_EMBEDDED
+#endif // TARGET_OS_IPHONE
 
 
 #pragma mark -
 
 
 #pragma mark -
@@ -465,6 +463,7 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
        CFStringRef     if_localized_name;
        CFStringRef     if_mac_address;
        CFStringRef     if_type;
        CFStringRef     if_localized_name;
        CFStringRef     if_mac_address;
        CFStringRef     if_type;
+       Boolean         isPhysicalEthernet;
        CFArrayRef      supported;
 
        if_localized_name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
        CFArrayRef      supported;
 
        if_localized_name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
@@ -713,6 +712,10 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho
        }
        SCPrint(TRUE, stdout, CFSTR("\n"));
 
        }
        SCPrint(TRUE, stdout, CFSTR("\n"));
 
+       isPhysicalEthernet = _SCNetworkInterfaceIsPhysicalEthernet(interface);
+       SCPrint(TRUE, stdout, CFSTR("%@  is physical ethernet = %s \n"),
+               prefix, (isPhysicalEthernet == TRUE) ? "YES" : "NO");
+
        if (configuration != NULL) {
                CFMutableDictionaryRef  effective;
 
        if (configuration != NULL) {
                CFMutableDictionaryRef  effective;
 
@@ -920,6 +923,33 @@ show_interfaces(int argc, char **argv)
                                        interfaceName);
                        }
 
                                        interfaceName);
                        }
 
+                       if (_sc_debug) {
+                               CFMutableStringRef      desc;
+                               CFStringRef             str;
+
+                               str = CFCopyDescription(interface);
+                               desc = CFStringCreateMutableCopy(NULL, 0, str);
+                               CFRelease(str);
+
+                               CFStringFindAndReplace(desc,
+                                                      CFSTR(" {"),
+                                                      CFSTR("\n       {\n         "),
+                                                      CFRangeMake(0, CFStringGetLength(desc)),
+                                                      0);
+                               CFStringFindAndReplace(desc,
+                                                      CFSTR(", "),
+                                                      CFSTR(",\n         "),
+                                                      CFRangeMake(0, CFStringGetLength(desc)),
+                                                      0);
+                               CFStringFindAndReplace(desc,
+                                                      CFSTR("}"),
+                                                      CFSTR("\n       }"),
+                                                      CFRangeMake(0, CFStringGetLength(desc)),
+                                                      0);
+                               SCPrint(TRUE, stdout, CFSTR("\n     %@\n\n"), desc);
+                               CFRelease(desc);
+                       }
+
                        interface = SCNetworkInterfaceGetInterface(interface);
                        childIndex++;
                } while (interface != NULL);
                        interface = SCNetworkInterfaceGetInterface(interface);
                        childIndex++;
                } while (interface != NULL);
index 6dfc9daa0192229b1f90280e0c3dd23c61c014fb..3149566663ab047bef80d0521a2b51007f9e0266 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004, 2005, 2009-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2004, 2005, 2009-2011, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -504,6 +504,7 @@ __private_extern__
 void
 show_set(int argc, char **argv)
 {
 void
 show_set(int argc, char **argv)
 {
+       CFArrayRef      interfaces;
        CFArrayRef      services;
        SCNetworkSetRef set     = NULL;
        CFStringRef     setName;
        CFArrayRef      services;
        SCNetworkSetRef set     = NULL;
        CFStringRef     setName;
@@ -593,6 +594,25 @@ show_set(int argc, char **argv)
                CFRelease(services);
        }
 
                CFRelease(services);
        }
 
+       interfaces = SCNetworkSetCopyAvailableInterfaces(set);
+       if (interfaces != NULL) {
+               CFIndex                 i;
+               SCNetworkInterfaceRef   interface;
+               CFIndex                 n;
+
+               SCPrint(TRUE, stdout, CFSTR("available interfaces =\n"));
+
+               n = CFArrayGetCount(interfaces);
+               for (i = 0; i < n; i++) {
+                       interface = CFArrayGetValueAtIndex(interfaces, i);
+                       SCPrint(TRUE, stdout, CFSTR(" %2d: %@ \n"),
+                               i + 1,
+                               SCNetworkInterfaceGetLocalizedDisplayName(interface));
+               }
+
+               CFRelease(interfaces);
+       }
+
        if (_sc_debug) {
                SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
        }
        if (_sc_debug) {
                SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
        }
index a50302e85917c85c42d2d3c956d7ae7fcbdc12dd..19507fc74c832c8ced54acefa6cccf1b5bdaabc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004, 2008-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2008-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -286,7 +286,7 @@ _watcher(void *arg)
        }
 
        if (doDispatch) {
        }
 
        if (doDispatch) {
-               if (!SCDynamicStoreSetDispatchQueue(store, dispatch_get_current_queue())) {
+               if (!SCDynamicStoreSetDispatchQueue(store, dispatch_get_main_queue())) {
                        SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                        notifyRl = NULL;
                        return NULL;
                        SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                        notifyRl = NULL;
                        return NULL;
index 34e534d5a7990b0618d31b53a96a754172950817..d8761feb4879847e69ec65de11cf6fe2e192fb48 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2008, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -69,7 +69,7 @@ __loadSecurity(void) {
 }
 
 
 }
 
 
-__private_extern__ OSStatus
+static OSStatus
 _AuthorizationCreate(const AuthorizationRights *rights, const AuthorizationEnvironment *environment, AuthorizationFlags flags, AuthorizationRef *authorization)
 {
        #undef AuthorizationCreate
 _AuthorizationCreate(const AuthorizationRights *rights, const AuthorizationEnvironment *environment, AuthorizationFlags flags, AuthorizationRef *authorization)
 {
        #undef AuthorizationCreate
@@ -83,7 +83,7 @@ _AuthorizationCreate(const AuthorizationRights *rights, const AuthorizationEnvir
 #define AuthorizationCreate _AuthorizationCreate
 
 
 #define AuthorizationCreate _AuthorizationCreate
 
 
-__private_extern__ OSStatus
+static OSStatus
 _AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
 {
        #undef AuthorizationFree
 _AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
 {
        #undef AuthorizationFree
@@ -99,28 +99,47 @@ _AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
 
 /* -------------------- */
 
 
 /* -------------------- */
 
-
-static AuthorizationRef
-_createAuthorization()
+__private_extern__
+AuthorizationRef
+_prefs_AuthorizationCreate()
 {
        AuthorizationRef        authorization   = NULL;
 {
        AuthorizationRef        authorization   = NULL;
-       AuthorizationFlags      flags           = kAuthorizationFlagDefaults;
-       OSStatus                status;
-
-       status = AuthorizationCreate(NULL,
-                                    kAuthorizationEmptyEnvironment,
-                                    flags,
-                                    &authorization);
-       if (status != errAuthorizationSuccess) {
-               SCPrint(TRUE,
-                       stdout,
-                       CFSTR("AuthorizationCreate() failed: status = %d\n"),
-                       status);
-               return NULL;
+
+       if (getenv("SCPREFERENCES_USE_ENTITLEMENTS") != NULL) {
+               authorization = kSCPreferencesUseEntitlementAuthorization;
+       } else {
+               AuthorizationFlags      flags   = kAuthorizationFlagDefaults;
+               OSStatus                status;
+
+               status = AuthorizationCreate(NULL,
+                                            kAuthorizationEmptyEnvironment,
+                                            flags,
+                                            &authorization);
+               if (status != errAuthorizationSuccess) {
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("AuthorizationCreate() failed: status = %d\n"),
+                               status);
+                       return NULL;
+               }
        }
 
        return authorization;
 }
        }
 
        return authorization;
 }
+
+
+__private_extern__
+void
+_prefs_AuthorizationFree(AuthorizationRef authorization)
+{
+       if (authorization != kSCPreferencesUseEntitlementAuthorization) {
+               AuthorizationFree(authorization, kAuthorizationFlagDefaults);
+//             AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
+       }
+
+       return;
+}
+
 #endif /* !TARGET_OS_IPHONE */
 
 /* -------------------- */
 #endif /* !TARGET_OS_IPHONE */
 
 /* -------------------- */
@@ -144,9 +163,9 @@ _prefs_open(CFStringRef name, CFStringRef prefsID)
                useHelper = TRUE;
 
 #if    !TARGET_OS_IPHONE
                useHelper = TRUE;
 
 #if    !TARGET_OS_IPHONE
-               authorization = _createAuthorization();
+               authorization = _prefs_AuthorizationCreate();
 #else
 #else
-               authorization = (AuthorizationRef)kSCPreferencesUseEntitlementAuthorization;
+               authorization = kSCPreferencesUseEntitlementAuthorization;
 #endif /* !TARGET_OS_IPHONE */
        }
 
 #endif /* !TARGET_OS_IPHONE */
        }
 
@@ -228,8 +247,7 @@ _prefs_close()
 
        if (authorization != NULL) {
 #if    !TARGET_OS_IPHONE
 
        if (authorization != NULL) {
 #if    !TARGET_OS_IPHONE
-               AuthorizationFree(authorization, kAuthorizationFlagDefaults);
-//             AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
+               _prefs_AuthorizationFree(authorization);
 #else  /* !TARGET_OS_IPHONE */
                // Uh...if authorization isn't NULL, something went horribly wrong.
 #endif /* !TARGET_OS_IPHONE */
 #else  /* !TARGET_OS_IPHONE */
                // Uh...if authorization isn't NULL, something went horribly wrong.
 #endif /* !TARGET_OS_IPHONE */
@@ -320,7 +338,12 @@ set_ComputerName(int argc, char **argv)
        }
 
        if (argc == 0) {
        }
 
        if (argc == 0) {
-               hostname = _copyStringFromSTDIN();
+               CFStringEncoding        old_encoding;
+               CFStringRef             old_hostname;
+
+               old_hostname = SCDynamicStoreCopyComputerName(NULL, &old_encoding);
+               hostname = _copyStringFromSTDIN(CFSTR("ComputerName"), old_hostname);
+               if (old_hostname) CFRelease(old_hostname);
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
@@ -400,7 +423,7 @@ set_HostName(int argc, char **argv)
        }
 
        if (argc == 0) {
        }
 
        if (argc == 0) {
-               hostname = _copyStringFromSTDIN();
+               hostname = _copyStringFromSTDIN(CFSTR("HostName"), SCPreferencesGetHostName(prefs));
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
@@ -470,7 +493,11 @@ set_LocalHostName(int argc, char **argv)
        }
 
        if (argc == 0) {
        }
 
        if (argc == 0) {
-               hostname = _copyStringFromSTDIN();
+               CFStringRef     old_hostname;
+
+               old_hostname = SCDynamicStoreCopyLocalHostName(NULL);
+               hostname = _copyStringFromSTDIN(CFSTR("LocalHostName"), old_hostname);
+               if (old_hostname) CFRelease(old_hostname);
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
        } else {
                hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
        }
@@ -531,11 +558,37 @@ do_getPref(char *pref, int argc, char **argv)
 {
        int     i;
 
 {
        int     i;
 
-       i = findPref(pref);
-       if (i >= 0) {
-               (*pref_keys[i].get)(argc, argv);
+       if (argc == 0) {
+               i = findPref(pref);
+               if (i >= 0) {
+                       (*pref_keys[i].get)(argc, argv);
+               }
+               return;
        }
        }
-       return;
+
+       // Add support to parse out extended get
+       // ie. scutil --get <filename> <prefs path> <key>
+       do_prefs_init();
+       do_prefs_open(argc, argv);
+       do_prefs_get(--argc, ++argv);
+
+       if (value != NULL) {
+               CFStringRef key;
+               CFStringRef prefs_val;
+
+               key = CFStringCreateWithCString(NULL, *(++argv), kCFStringEncodingUTF8);
+               prefs_val = CFDictionaryGetValue(value, key);
+               CFRelease(key);
+
+               if (prefs_val != NULL) {
+                       SCPrint(TRUE, stdout, CFSTR("%@\n"), prefs_val);
+               } else {
+                       _prefs_close();
+                       exit(1);
+               }
+       }
+       _prefs_close();
+       exit(0);
 }
 
 
 }
 
 
@@ -917,3 +970,43 @@ do_prefs_remove(int argc, char **argv)
        CFRelease(path);
        return;
 }
        CFRelease(path);
        return;
 }
+
+/* -------------------- */
+
+#include "IPMonitorControlPrefs.h"
+
+__private_extern__
+void
+do_log(char * log, int argc, char **argv)
+{
+       if (strcmp(log, "IPMonitor")) {
+           exit(0);
+       }
+       if (argc == 0) {
+           printf("IPMonitor log is %s\n",
+                  IPMonitorControlPrefsIsVerbose() ? "on" : "off");
+       }
+       else {
+           Boolean     verbose = FALSE;
+
+           if (strcasecmp(argv[0], "on") == 0) {
+               verbose = TRUE;
+           }
+           else if (strcasecmp(argv[0], "off") == 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);
+           }
+       }
+       exit(0);
+       return;
+}
+
+
index feb55bea585828beb3c5fc012012755c119e3d82..f1a3437cb6115212eb4c12d1fc97b98311ddc8af 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003, 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2003, 2005-2007, 2012, 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -40,6 +40,9 @@ Boolean       _prefs_changed;
 
 __BEGIN_DECLS
 
 
 __BEGIN_DECLS
 
+AuthorizationRef       _prefs_AuthorizationCreate      (void);
+void                   _prefs_AuthorizationFree        (AuthorizationRef authorization);
+
 Boolean        _prefs_open             (CFStringRef name, CFStringRef prefsID);
 void   _prefs_save             (void);
 void   _prefs_close            (void);
 Boolean        _prefs_open             (CFStringRef name, CFStringRef prefsID);
 void   _prefs_save             (void);
 void   _prefs_close            (void);
@@ -65,6 +68,7 @@ void  do_prefs_get            (int argc, char **argv);
 void   do_prefs_set            (int argc, char **argv);
 void   do_prefs_remove         (int argc, char **argv);
 
 void   do_prefs_set            (int argc, char **argv);
 void   do_prefs_remove         (int argc, char **argv);
 
+void   do_log                  (char *pref, int argc, char **argv);
 __END_DECLS
 
 #endif /* !_PREFS_H */
 __END_DECLS
 
 #endif /* !_PREFS_H */
index 3350639259bc65fa31f6dc04390508989bdacaf6..d0583669e1289f89785a60d54adff97a6640020c 100644 (file)
@@ -32,6 +32,9 @@
 .Br
 .Nm
 .Fl -proxy
 .Br
 .Nm
 .Fl -proxy
+.Br
+.Nm
+.Fl -nc Ar nc-arguments
 .\".Br
 .\".Nm
 .\".Fl -net
 .\".Br
 .\".Nm
 .\".Fl -net
@@ -85,7 +88,7 @@ The
 .Fl -dns
 option reports the current DNS configuration.
 The first listed
 .Fl -dns
 option reports the current DNS configuration.
 The first listed
-.Xr resolver 5 
+.Xr resolver 5
 configuration is considered to be the
 .Qq default
 configuration.
 configuration is considered to be the
 .Qq default
 configuration.
@@ -101,6 +104,14 @@ configuration in addition to the first listed.
 The
 .Fl -proxy
 option reports the current system proxy configuration.
 The
 .Fl -proxy
 option reports the current system proxy configuration.
+.Pp
+The
+.Fl -nc
+option provides a set of commands for monitoring and interacting with VPN connections.
+Use
+.Fl -nc
+.Ar help
+for a full list of commands.
 .\".Pp
 .\"Lastly, the
 .\".Fl -net
 .\".Pp
 .\"Lastly, the
 .\".Fl -net
@@ -178,7 +189,7 @@ The user-friendly name for the system.
 The local (Bonjour) host name.
 .It HostName
 The name associated with
 The local (Bonjour) host name.
 .It HostName
 The name associated with
-.Xr hostname 1 
+.Xr hostname 1
 and
 .Xr gethostname 3 .
 .El
 and
 .Xr gethostname 3 .
 .El
@@ -198,6 +209,11 @@ option requires super-user access.
 Reports the current DNS configuration.
 .It Fl -proxy
 Reports the current proxy configuration.
 Reports the current DNS configuration.
 .It Fl -proxy
 Reports the current proxy configuration.
+.It Fl -nc Ar nc-arguments
+Provides a set of commands for monitoring and interacting with VPN connections. Use
+.Fl -nc
+.Ar help
+for a full list of commands.
 .\".It Fl -net
 .\"Provides a command line interface to the
 .\".Qq network configuration .
 .\".It Fl -net
 .\"Provides a command line interface to the
 .\".Qq network configuration .
index 7578f44cc43975e4593701e3994251fb2259cad9..c4bff2a6e9e4f98110c34444e01f69a50a68979c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -102,33 +102,77 @@ static const struct option longopts[] = {
        { "nwi",                no_argument,            NULL,   0       },
        { "prefs",              no_argument,            NULL,   0       },
        { "proxy",              no_argument,            NULL,   0       },
        { "nwi",                no_argument,            NULL,   0       },
        { "prefs",              no_argument,            NULL,   0       },
        { "proxy",              no_argument,            NULL,   0       },
+       { "renew",              required_argument,      NULL,   0       },
        { "set",                required_argument,      NULL,   0       },
        { "snapshot",           no_argument,            NULL,   0       },
        { "user",               required_argument,      NULL,   0       },
        { "password",           required_argument,      NULL,   0       },
        { "secret",             required_argument,      NULL,   0       },
        { "set",                required_argument,      NULL,   0       },
        { "snapshot",           no_argument,            NULL,   0       },
        { "user",               required_argument,      NULL,   0       },
        { "password",           required_argument,      NULL,   0       },
        { "secret",             required_argument,      NULL,   0       },
+       { "log",                required_argument,      NULL,   0       },
        { NULL,                 0,                      NULL,   0       }
 };
 
 
 __private_extern__
 CFStringRef
        { NULL,                 0,                      NULL,   0       }
 };
 
 
 __private_extern__
 CFStringRef
-_copyStringFromSTDIN()
+_copyStringFromSTDIN(CFStringRef prompt, CFStringRef defaultValue)
 {
        char            buf[1024];
 {
        char            buf[1024];
+       int             i;
+       Boolean         is_user_prompt = (prompt != NULL && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO));
        size_t          len;
        size_t          len;
+       char            *modbuf;
+       size_t          modlen;
        CFStringRef     utf8;
 
        CFStringRef     utf8;
 
+       /* Print out a prompt to user that entry is desired */
+       if (is_user_prompt) {
+               if (defaultValue != NULL) {
+                       SCPrint(TRUE, stdout, CFSTR("%@ [%@]: "), prompt, defaultValue);
+               } else {
+                       SCPrint(TRUE, stdout, CFSTR("%@: "), prompt);
+               }
+       }
+
+       /* Get user input */
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
                return NULL;
        }
 
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
                return NULL;
        }
 
+       /* Prepare for trim */
        len = strlen(buf);
        len = strlen(buf);
-       if (buf[len-1] == '\n') {
-               buf[--len] = '\0';
+       modbuf = buf;
+       modlen = len;
+
+       /* Trim new-line */
+       if ((modlen > 0) && (modbuf[modlen - 1] == '\n')) {
+               modbuf[modlen - 1] = '\0';
+               modlen--;
+       }
+
+       /* If nothing was entered at the user prompt, set default */
+       if (is_user_prompt && defaultValue != NULL && modlen == 0) {
+               CFRetain(defaultValue);
+               return defaultValue;
        }
 
        }
 
-       utf8 = CFStringCreateWithBytes(NULL, (UInt8 *)buf, len, kCFStringEncodingUTF8, TRUE);
+       /* Trim spaces from front */
+       while (modlen > 0 && isspace(modbuf[0])) {
+               modbuf = &modbuf[1];
+               modlen--;
+       }
+
+       /* Trim spaces  from back */
+       for (i = modlen - 1; i >= 0; i--) {
+               if (isspace(buf[i])) {
+                       buf[i] = '\0';
+                       modlen--;
+               } else {
+                       break;
+               }
+       }
+
+       utf8 = CFStringCreateWithBytes(NULL, (UInt8 *)modbuf, modlen, kCFStringEncodingUTF8, TRUE);
        return utf8;
 }
 
        return utf8;
 }
 
@@ -293,6 +337,7 @@ usage(const char *command)
        SCPrint(TRUE, stderr, CFSTR("\n"));
        SCPrint(TRUE, stderr, CFSTR("   or: %s --get pref\n"), command);
        SCPrint(TRUE, stderr, CFSTR("   or: %s --set pref [newval]\n"), command);
        SCPrint(TRUE, stderr, CFSTR("\n"));
        SCPrint(TRUE, stderr, CFSTR("   or: %s --get pref\n"), command);
        SCPrint(TRUE, stderr, CFSTR("   or: %s --set pref [newval]\n"), command);
+       SCPrint(TRUE, stderr, CFSTR("   or: %s --get filename path key  \n"), command);
        SCPrint(TRUE, stderr, CFSTR("\tpref\tdisplay (or set) the specified preference.  Valid preferences\n"));
        SCPrint(TRUE, stderr, CFSTR("\t\tinclude:\n"));
        SCPrint(TRUE, stderr, CFSTR("\t\t\tComputerName, LocalHostName, HostName\n"));
        SCPrint(TRUE, stderr, CFSTR("\tpref\tdisplay (or set) the specified preference.  Valid preferences\n"));
        SCPrint(TRUE, stderr, CFSTR("\t\tinclude:\n"));
        SCPrint(TRUE, stderr, CFSTR("\t\t\tComputerName, LocalHostName, HostName\n"));
@@ -307,6 +352,9 @@ usage(const char *command)
        SCPrint(TRUE, stderr, CFSTR("\n"));
        SCPrint(TRUE, stderr, CFSTR("   or: %s --nwi\n"), command);
        SCPrint(TRUE, stderr, CFSTR("\tshow network information\n"));
        SCPrint(TRUE, stderr, CFSTR("\n"));
        SCPrint(TRUE, stderr, CFSTR("   or: %s --nwi\n"), command);
        SCPrint(TRUE, stderr, CFSTR("\tshow network information\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("   or: %s --nc\n"), command);
+       SCPrint(TRUE, stderr, CFSTR("\tshow VPN network configuration information. Use --nc help for full command list\n"));
 
        if (getenv("ENABLE_EXPERIMENTAL_SCUTIL_COMMANDS")) {
                SCPrint(TRUE, stderr, CFSTR("\n"));
 
        if (getenv("ENABLE_EXPERIMENTAL_SCUTIL_COMMANDS")) {
                SCPrint(TRUE, stderr, CFSTR("\n"));
@@ -321,7 +369,11 @@ usage(const char *command)
 static char *
 prompt(EditLine *el)
 {
 static char *
 prompt(EditLine *el)
 {
+#if    !TARGET_IPHONE_SIMULATOR
        return "> ";
        return "> ";
+#else  // !TARGET_IPHONE_SIMULATOR
+       return "sim> ";
+#endif // !TARGET_IPHONE_SIMULATOR
 }
 
 
 }
 
 
@@ -336,10 +388,12 @@ main(int argc, char * const argv[])
        Boolean                 doReach = FALSE;
        Boolean                 doSnap  = FALSE;
        char                    *get    = NULL;
        Boolean                 doReach = FALSE;
        Boolean                 doSnap  = FALSE;
        char                    *get    = NULL;
+       char                    *log    = NULL;
        extern int              optind;
        int                     opt;
        int                     opti;
        const char              *prog   = argv[0];
        extern int              optind;
        int                     opt;
        int                     opti;
        const char              *prog   = argv[0];
+       char                    *renew  = NULL;
        char                    *set    = NULL;
        char                    *nc_cmd = NULL;
        InputRef                src;
        char                    *set    = NULL;
        char                    *nc_cmd = NULL;
        InputRef                src;
@@ -402,12 +456,18 @@ main(int argc, char * const argv[])
                        } else if (strcmp(longopts[opti].name, "proxy") == 0) {
                                doProxy = TRUE;
                                xStore++;
                        } else if (strcmp(longopts[opti].name, "proxy") == 0) {
                                doProxy = TRUE;
                                xStore++;
+                       } else if (strcmp(longopts[opti].name, "renew") == 0) {
+                               renew = optarg;
+                               xStore++;
                        } else if (strcmp(longopts[opti].name, "set") == 0) {
                                set = optarg;
                                xStore++;
                        } else if (strcmp(longopts[opti].name, "snapshot") == 0) {
                                doSnap = TRUE;
                                xStore++;
                        } else if (strcmp(longopts[opti].name, "set") == 0) {
                                set = optarg;
                                xStore++;
                        } else if (strcmp(longopts[opti].name, "snapshot") == 0) {
                                doSnap = TRUE;
                                xStore++;
+                       } else if (strcmp(longopts[opti].name, "log") == 0) {
+                               log = optarg;
+                               xStore++;
                        } else if (strcmp(longopts[opti].name, "user") == 0) {
                                username = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8);
                        } else if (strcmp(longopts[opti].name, "password") == 0) {
                        } else if (strcmp(longopts[opti].name, "user") == 0) {
                                username = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8);
                        } else if (strcmp(longopts[opti].name, "password") == 0) {
@@ -427,6 +487,7 @@ main(int argc, char * const argv[])
                // if we are attempting to process more than one type of request
                usage(prog);
        }
                // if we are attempting to process more than one type of request
                usage(prog);
        }
+
        /* are we checking (or watching) the reachability of a host/address */
        if (doReach) {
                if (argc < 1) {
        /* are we checking (or watching) the reachability of a host/address */
        if (doReach) {
                if (argc < 1) {
@@ -458,7 +519,11 @@ main(int argc, char * const argv[])
        }
 
        if (doSnap) {
        }
 
        if (doSnap) {
-               if (!enablePrivateAPI || (geteuid() != 0)) {
+               if (!enablePrivateAPI
+#if    !TARGET_IPHONE_SIMULATOR
+                   || (geteuid() != 0)
+#endif // !TARGET_IPHONE_SIMULATOR
+                  ) {
                        usage(prog);
                }
 
                        usage(prog);
                }
 
@@ -469,9 +534,17 @@ main(int argc, char * const argv[])
 
        /* are we looking up a preference value */
        if (get) {
 
        /* are we looking up a preference value */
        if (get) {
-               if (findPref(get) < 0) {
-                       usage(prog);
+               if (argc != 2) {
+                       if (findPref(get) < 0) {
+                               usage(prog);
+                       }
+               } else {
+                       /* need to go back one argument
+                        * for the filename */
+                       argc++;
+                       argv--;
                }
                }
+
                do_getPref(get, argc, (char **)argv);
                /* NOT REACHED */
        }
                do_getPref(get, argc, (char **)argv);
                /* NOT REACHED */
        }
@@ -491,6 +564,14 @@ main(int argc, char * const argv[])
                /* NOT REACHED */
        }
 
                /* NOT REACHED */
        }
 
+       /* verbose log */
+       if (log != NULL) {
+               if (strcasecmp(log, "IPMonitor")) {
+                       usage(prog);
+               }
+               do_log(log, argc, (char * *)argv);
+               /* NOT REACHED */
+       }
        /* network connection commands */
        if (nc_cmd) {
                if (find_nc_cmd(nc_cmd) < 0) {
        /* network connection commands */
        if (nc_cmd) {
                if (find_nc_cmd(nc_cmd) < 0) {
@@ -509,15 +590,15 @@ main(int argc, char * const argv[])
                        usage(prog);
                }
 
                        usage(prog);
                }
 
-               do_net_init();          /* initialization */
-               do_net_open(0, NULL);   /* open default prefs */
+               do_net_init();                          /* initialization */
+               do_net_open(argc, (char **)argv);       /* open prefs */
        } else if (doPrefs) {
                /* if we are going to be managing the network configuration */
                commands  = (cmdInfo *)commands_prefs;
                nCommands = nCommands_prefs;
 
        } else if (doPrefs) {
                /* if we are going to be managing the network configuration */
                commands  = (cmdInfo *)commands_prefs;
                nCommands = nCommands_prefs;
 
-               do_dictInit(0, NULL);   /* start with an empty dictionary */
-               do_prefs_init();        /* initialization */
+               do_dictInit(0, NULL);                   /* start with an empty dictionary */
+               do_prefs_init();                        /* initialization */
                do_prefs_open(argc, (char **)argv);     /* open prefs */
        } else {
                /* if we are going to be managing the dynamic store */
                do_prefs_open(argc, (char **)argv);     /* open prefs */
        } else {
                /* if we are going to be managing the dynamic store */
@@ -528,6 +609,12 @@ main(int argc, char * const argv[])
                do_open(0, NULL);       /* open the dynamic store */
        }
 
                do_open(0, NULL);       /* open the dynamic store */
        }
 
+       /* are we trying to renew a DHCP lease */
+       if (renew != NULL) {
+               do_renew(renew);
+               /* NOT REACHED */
+       }
+
        /* allocate command input stream */
        src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
        src->fp = stdin;
        /* allocate command input stream */
        src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
        src->fp = stdin;
index cbffecfedae16bff13c4525c7d0ebdf8b8e7a986..4c0d0b9580ef196e2cb74f4be5824c02550a493b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2005, 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -65,7 +65,8 @@ extern CFMutableArrayRef      watchedPatterns;
 __BEGIN_DECLS
 
 Boolean                process_line            (InputRef       src);
 __BEGIN_DECLS
 
 Boolean                process_line            (InputRef       src);
-CFStringRef    _copyStringFromSTDIN    ();
+CFStringRef    _copyStringFromSTDIN    (CFStringRef    prompt,
+                                        CFStringRef    defaultValue);
 
 __END_DECLS
 
 
 __END_DECLS
 
index bc9160eb2502c3e8e7fbde9a0311e2fb98e08ff1..9b75f7f8ab51ff11736a8797e8cf65e37e5a1bfc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -37,6 +37,7 @@
  */
 
 #include "scutil.h"
  */
 
 #include "scutil.h"
+#include "prefs.h"
 #include "tests.h"
 
 #include <netdb.h>
 #include "tests.h"
 
 #include <netdb.h>
 #include <arpa/inet.h>
 
 #include <dnsinfo.h>
 #include <arpa/inet.h>
 
 #include <dnsinfo.h>
+#include "dnsinfo_internal.h"
 #include <network_information.h>
 #include "SCNetworkReachabilityInternal.h"
 #include <network_information.h>
 #include "SCNetworkReachabilityInternal.h"
+#include <CommonCrypto/CommonDigest.h>
 
 
-static Boolean resolver_bypass;
+static Boolean resolver_bypass;
 
 static CF_RETURNS_RETAINED CFMutableDictionaryRef
 _setupReachabilityOptions(int argc, char **argv, const char *interface)
 {
 
 static CF_RETURNS_RETAINED CFMutableDictionaryRef
 _setupReachabilityOptions(int argc, char **argv, const char *interface)
 {
+       int                     i;
        CFMutableDictionaryRef  options;
 
        options = CFDictionaryCreateMutable(NULL,
        CFMutableDictionaryRef  options;
 
        options = CFDictionaryCreateMutable(NULL,
@@ -62,103 +66,54 @@ _setupReachabilityOptions(int argc, char **argv, const char *interface)
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
 
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
 
-       if (argc > 2) {
-               struct addrinfo         hints   = { 0 };
-               int                     n_hints = 0;
-               int                     i;
-
-               for (i = 2; i < argc; i++) {
-                       if (strcasecmp(argv[i], "interface") == 0) {
-                               if (++i >= argc) {
-                                       SCPrint(TRUE, stderr, CFSTR("No interface\n"));
-                                       CFRelease(options);
-                                       exit(1);
-                               }
-
-                               interface = argv[i];
-                               continue;
+       for (i = 0; i < argc; i++) {
+               if (strcasecmp(argv[i], "interface") == 0) {
+                       if (++i >= argc) {
+                               SCPrint(TRUE, stderr, CFSTR("No interface\n"));
+                               CFRelease(options);
+                               exit(1);
                        }
 
                        }
 
+                       interface = argv[i];
+                       continue;
+               }
 
 
-                       if (strcasecmp(argv[i], "llq") == 0) {
-                               CFDictionarySetValue(options,
-                                                    kSCNetworkReachabilityOptionLongLivedQueryBypass,
-                                                    kCFBooleanFalse);
-                               continue;
-                       } else if (strcasecmp(argv[i], "no-llq") == 0) {
-                               CFDictionarySetValue(options,
-                                                    kSCNetworkReachabilityOptionLongLivedQueryBypass,
-                                                    kCFBooleanTrue);
-                               continue;
-                       }
 
 
-                       if (strcasecmp(argv[i], "server") == 0) {
-                               CFDictionarySetValue(options,
-                                                    kSCNetworkReachabilityOptionServerBypass,
-                                                    kCFBooleanFalse);
-                               continue;
-                       } else if (strcasecmp(argv[i], "no-server") == 0) {
-                               CFDictionarySetValue(options,
-                                                    kSCNetworkReachabilityOptionServerBypass,
-                                                    kCFBooleanTrue);
-                               continue;
-                       }
+               if (strcasecmp(argv[i], "server") == 0) {
+                       CFDictionarySetValue(options,
+                                            kSCNetworkReachabilityOptionServerBypass,
+                                            kCFBooleanFalse);
+                       continue;
+               } else if (strcasecmp(argv[i], "no-server") == 0) {
+                       CFDictionarySetValue(options,
+                                            kSCNetworkReachabilityOptionServerBypass,
+                                            kCFBooleanTrue);
+                       continue;
+               }
 
 
-                       if (strcasecmp(argv[i], "no-resolve") == 0) {
-                               CFDictionarySetValue(options,
-                                                    kSCNetworkReachabilityOptionResolverBypass,
-                                                    kCFBooleanTrue);
-                               resolver_bypass = TRUE;
-                               continue;
-                       }
 
 
-                       if (strcasecmp(argv[i], "AI_ADDRCONFIG") == 0) {
-                               hints.ai_flags |= AI_ADDRCONFIG;
-                       } else if (strcasecmp(argv[i], "AI_ALL") == 0) {
-                               hints.ai_flags |= AI_ALL;
-                       } else if (strcasecmp(argv[i], "AI_V4MAPPED") == 0) {
-                               hints.ai_flags |= AI_V4MAPPED;
-                       } else if (strcasecmp(argv[i], "AI_V4MAPPED_CFG") == 0) {
-                               hints.ai_flags |= AI_V4MAPPED_CFG;
-                       } else if (strcasecmp(argv[i], "AI_ADDRCONFIG") == 0) {
-                               hints.ai_flags |= AI_ADDRCONFIG;
-                       } else if (strcasecmp(argv[i], "AI_V4MAPPED") == 0) {
-                               hints.ai_flags |= AI_V4MAPPED;
-                       } else if (strcasecmp(argv[i], "AI_DEFAULT") == 0) {
-                               hints.ai_flags |= AI_DEFAULT;
-#ifdef AI_PARALLEL
-                       } else if (strcasecmp(argv[i], "AI_PARALLEL") == 0) {
-                               hints.ai_flags |= AI_PARALLEL;
-#endif // AI_PARALLEL
-                       } else if (strcasecmp(argv[i], "PF_INET") == 0) {
-                               hints.ai_family = PF_INET;
-                       } else if (strcasecmp(argv[i], "PF_INET6") == 0) {
-                               hints.ai_family = PF_INET6;
-                       } else if (strcasecmp(argv[i], "SOCK_STREAM") == 0) {
-                               hints.ai_socktype = SOCK_STREAM;
-                       } else if (strcasecmp(argv[i], "SOCK_DGRAM") == 0) {
-                               hints.ai_socktype = SOCK_DGRAM;
-                       } else if (strcasecmp(argv[i], "SOCK_RAW") == 0) {
-                               hints.ai_socktype = SOCK_RAW;
-                       } else if (strcasecmp(argv[i], "IPPROTO_TCP") == 0) {
-                               hints.ai_protocol = IPPROTO_TCP;
-                       } else if (strcasecmp(argv[i], "IPPROTO_UDP") == 0) {
-                               hints.ai_protocol = IPPROTO_UDP;
-                       } else {
-                               SCPrint(TRUE, stderr, CFSTR("Unrecognized hint: %s\n"), argv[i]);
-                               CFRelease(options);
-                               exit(1);
-                       }
-                       n_hints++;
+               if (strcasecmp(argv[i], "no-connection-on-demand") == 0) {
+                       CFDictionarySetValue(options,
+                                            kSCNetworkReachabilityOptionConnectionOnDemandBypass,
+                                            kCFBooleanTrue);
+                       continue;
                }
 
                }
 
-               if (n_hints > 0) {
-                       CFDataRef       data;
+               if (strcasecmp(argv[i], "no-resolve") == 0) {
+                       CFDictionarySetValue(options,
+                                            kSCNetworkReachabilityOptionResolverBypass,
+                                            kCFBooleanTrue);
+                       resolver_bypass = TRUE;
+                       continue;
+               }
 
 
-                       data = CFDataCreate(NULL, (const UInt8 *)&hints, sizeof(hints));
-                       CFDictionarySetValue(options, kSCNetworkReachabilityOptionHints, data);
-                       CFRelease(data);
+               if (strlen(argv[i]) == 0) {
+                       continue;
                }
                }
+
+               SCPrint(TRUE, stderr, CFSTR("Unrecognized option: %s\n"), argv[i]);
+               CFRelease(options);
+               exit(1);
        }
 
        if (interface != NULL) {
        }
 
        if (interface != NULL) {
@@ -189,6 +144,8 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
        char                            *ip_address     = argv[0];
        const char                      *interface;
        CFMutableDictionaryRef          options         = NULL;
        char                            *ip_address     = argv[0];
        const char                      *interface;
        CFMutableDictionaryRef          options         = NULL;
+       char                            *remote_address = NULL;
+       struct sockaddr_in              r_sin;
        struct sockaddr_in              sin;
        struct sockaddr_in6             sin6;
        SCNetworkReachabilityRef        target          = NULL;
        struct sockaddr_in              sin;
        struct sockaddr_in6             sin6;
        SCNetworkReachabilityRef        target          = NULL;
@@ -209,9 +166,19 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
        }
 
        if (inet_aton(ip_address, &sin.sin_addr) == 1) {
        }
 
        if (inet_aton(ip_address, &sin.sin_addr) == 1) {
-               if ((argc == 1) ||
-                   ((argc > 1) && (strlen(argv[1]) == 0))) {
-                       options = _setupReachabilityOptions(argc, argv, interface);
+               if (argc > 1) {
+                       bzero(&r_sin, sizeof(r_sin));
+                       r_sin.sin_len    = sizeof(r_sin);
+                       r_sin.sin_family = AF_INET;
+                       remote_address   = argv[1];
+               }
+
+               if ((argc == 1)
+                   || ((argc > 1) && (strlen(argv[1]) == 0))
+                   || inet_aton(remote_address, &r_sin.sin_addr) == 0) {
+                       if (argc > 2) {
+                               options = _setupReachabilityOptions(argc - 2, argv + 2, interface);
+                       }
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
                                if (context != NULL) {
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
                                if (context != NULL) {
@@ -238,9 +205,7 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
                                }
                        }
                } else {
                                }
                        }
                } else {
-                       char                    *remote_address = argv[1];
                        const char              *interface2;
                        const char              *interface2;
-                       struct sockaddr_in      r_sin;
 
                        interface2 = strchr(argv[1], '%');
                        if (interface2 != NULL) {
 
                        interface2 = strchr(argv[1], '%');
                        if (interface2 != NULL) {
@@ -259,19 +224,11 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
                                interface = interface2;
                        }
 
                                interface = interface2;
                        }
 
-                       bzero(&r_sin, sizeof(r_sin));
-                       r_sin.sin_len    = sizeof(r_sin);
-                       r_sin.sin_family = AF_INET;
-                       if (inet_aton(remote_address, &r_sin.sin_addr) == 0) {
-                               SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), remote_address);
-                               exit(1);
-                       }
-
                        if (remote_address != argv[1]) {
                                free(remote_address);
                        }
 
                        if (remote_address != argv[1]) {
                                free(remote_address);
                        }
 
-                       options = _setupReachabilityOptions(argc, argv, interface);
+                       options = _setupReachabilityOptions(argc - 2, argv + 2, interface);
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddressPair(NULL,
                                                                                    (struct sockaddr *)&sin,
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddressPair(NULL,
                                                                                    (struct sockaddr *)&sin,
@@ -304,13 +261,24 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
                        }
                }
        } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
                        }
                }
        } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
+               struct sockaddr_in6     r_sin6;
+
                if (interface != NULL) {
                        sin6.sin6_scope_id = if_nametoindex(interface);
                }
 
                if (interface != NULL) {
                        sin6.sin6_scope_id = if_nametoindex(interface);
                }
 
-               if ((argc == 1) ||
-                   ((argc > 1) && (strlen(argv[1]) == 0))) {
-                       options = _setupReachabilityOptions(argc, argv, NULL);
+               if (argc >1) {
+                       bzero(&r_sin6, sizeof(r_sin6));
+                       r_sin6.sin6_len    = sizeof(r_sin6);
+                       r_sin6.sin6_family = AF_INET6;
+               }
+
+               if ((argc == 1)
+                   || ((argc > 1) && (strlen(argv[1]) == 0))
+                   || inet_pton(AF_INET6, argv[1], &r_sin6.sin6_addr) == 0) {
+                       if (argc > 2) {
+                               options = _setupReachabilityOptions(argc - 2, argv + 2, NULL);
+                       }
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
                                if (context != NULL) {
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
                                if (context != NULL) {
@@ -328,22 +296,12 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
                                }
                        }
                } else {
                                }
                        }
                } else {
-                       struct sockaddr_in6     r_sin6;
-
-                       bzero(&r_sin6, sizeof(r_sin6));
-                       r_sin6.sin6_len         = sizeof(r_sin6);
-                       r_sin6.sin6_family      = AF_INET6;
-                       if (inet_pton(AF_INET6, argv[1], &r_sin6.sin6_addr) == 0) {
-                               SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[1]);
-                               exit(1);
-                       }
-
                        interface = strchr(argv[1], '%');
                        if (interface != NULL) {
                                r_sin6.sin6_scope_id = if_nametoindex(interface);
                        }
 
                        interface = strchr(argv[1], '%');
                        if (interface != NULL) {
                                r_sin6.sin6_scope_id = if_nametoindex(interface);
                        }
 
-                       options = _setupReachabilityOptions(argc, argv, NULL);
+                       options = _setupReachabilityOptions(argc - 2, argv + 2, NULL);
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddressPair(NULL,
                                                                                    (struct sockaddr *)&sin6,
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithAddressPair(NULL,
                                                                                    (struct sockaddr *)&sin6,
@@ -367,60 +325,28 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
                        }
                }
        } else {
                        }
                }
        } else {
-               CFStringRef     str;
-
-               options = _setupReachabilityOptions(argc, argv, NULL);
-
-               if (((argc == 1) && (strlen(argv[0]) > 0)) ||
-                   ((argc > 1) && (strlen(argv[0]) > 0) && (strlen(argv[1]) == 0))) {
+               if (argc == 1) {
+                       target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
+                       if (context != NULL) {
+                               context->info = "by name";
+                       }
+               } else {
+                       options = _setupReachabilityOptions(argc - 1, argv + 1, NULL);
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
                                if (context != NULL) {
                                        context->info = "by name";
                                }
                        } else {
                        if (options == NULL) {
                                target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
                                if (context != NULL) {
                                        context->info = "by name";
                                }
                        } else {
-                               str  = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
-                               CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, str);
-                               CFRelease(str);
-
-                               if (context != NULL) {
-                                       context->info = "by name w/options";
-                               }
-                       }
-               } else {
-                       CFIndex         n_options;
-
-                       if (options == NULL) {
-                               options = CFDictionaryCreateMutable(NULL,
-                                                                   0,
-                                                                   &kCFTypeDictionaryKeyCallBacks,
-                                                                   &kCFTypeDictionaryValueCallBacks);
-                       }
-                       n_options = CFDictionaryGetCount(options);
+                               CFStringRef     str;
 
 
-                       if (strlen(argv[0]) > 0) {
                                str  = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, str);
                                CFRelease(str);
                                str  = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
                                CFDictionarySetValue(options, kSCNetworkReachabilityOptionNodeName, str);
                                CFRelease(str);
-                       }
-                       if (strlen(argv[1]) > 0) {
-                               str  = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8);
-                               CFDictionarySetValue(options, kSCNetworkReachabilityOptionServName, str);
-                               CFRelease(str);
-                       }
 
 
-                       if (CFDictionaryGetCount(options) > n_options) {
                                if (context != NULL) {
                                if (context != NULL) {
-                                       if (n_options == 0) {
-                                               context->info = "by (node and/or serv) name";
-                                       } else {
-                                               context->info = "by (node and/or serv) name w/options";
-                                       }
+                                       context->info = "by name w/options";
                                }
                                }
-                       } else {
-                               SCPrint(TRUE, stderr, CFSTR("Must specify nodename or servname\n"));
-                               CFRelease(options);
-                               exit(1);
                        }
                }
        }
                        }
                }
        }
@@ -437,66 +363,6 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context)
        return target;
 }
 
        return target;
 }
 
-static void
-_printReachabilityFlags(SCNetworkReachabilityFlags flags)
-{
-       if (flags != 0) {
-               if (flags & kSCNetworkReachabilityFlagsReachable) {
-                       SCPrint(TRUE, stdout, CFSTR("Reachable"));
-                       flags &= ~kSCNetworkReachabilityFlagsReachable;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
-                       SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
-                       flags &= ~kSCNetworkReachabilityFlagsTransientConnection;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
-                       SCPrint(TRUE, stdout, CFSTR("Connection Required"));
-                       flags &= ~kSCNetworkReachabilityFlagsConnectionRequired;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
-                       SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Traffic"));
-                       flags &= ~kSCNetworkReachabilityFlagsConnectionOnTraffic;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
-                       SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Demand"));
-                       flags &= ~kSCNetworkReachabilityFlagsConnectionOnDemand;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
-                       SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
-                       flags &= ~kSCNetworkReachabilityFlagsInterventionRequired;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
-                       SCPrint(TRUE, stdout, CFSTR("Local Address"));
-                       flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags & kSCNetworkReachabilityFlagsIsDirect) {
-                       SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
-                       flags &= ~kSCNetworkReachabilityFlagsIsDirect;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-#if    TARGET_OS_IPHONE
-               if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
-                       SCPrint(TRUE, stdout, CFSTR("WWAN"));
-                       flags &= ~kSCNetworkReachabilityFlagsIsWWAN;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-#endif // TARGET_OS_IPHONE
-               if (flags != 0) {
-                       SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
-               }
-       } else {
-               SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
-       }
-
-       return;
-}
 
 static void
 _printReachability(SCNetworkReachabilityRef target)
 
 static void
 _printReachability(SCNetworkReachabilityRef target)
@@ -506,21 +372,21 @@ _printReachability(SCNetworkReachabilityRef target)
 
        ok = SCNetworkReachabilityGetFlags(target, &flags);
        if (!ok) {
 
        ok = SCNetworkReachabilityGetFlags(target, &flags);
        if (!ok) {
-               printf("    could not determine reachability, %s\n", SCErrorString(SCError()));
+               SCPrint(TRUE, stderr, CFSTR("    could not determine reachability, %s\n"), SCErrorString(SCError()));
                return;
        }
 
        SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%08x ("), flags);
                return;
        }
 
        SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%08x ("), flags);
-       _printReachabilityFlags(flags);
+       __SCNetworkReachabilityPrintFlags(flags);
        SCPrint(_sc_debug, stdout, CFSTR(")"));
        SCPrint(_sc_debug, stdout, CFSTR(")"));
+       SCPrint(TRUE, stdout, CFSTR("\n"));
 
        if (resolver_bypass) {
 
        if (resolver_bypass) {
-               int if_index =
-                       SCNetworkReachabilityGetInterfaceIndex(target);
-               SCPrint(_sc_debug, stdout, CFSTR("interface index = %d"), if_index);
-       }
+               int     if_index;
 
 
-       SCPrint(TRUE, stdout, CFSTR("\n"));
+               if_index = SCNetworkReachabilityGetInterfaceIndex(target);
+               SCPrint(_sc_debug, stdout, CFSTR("interface index = %d\n"), if_index);
+       }
 
        return;
 }
 
        return;
 }
@@ -576,6 +442,50 @@ _printNWIFlags(nwi_ifstate_flags flags)
 }
 
 
 }
 
 
+static void
+_printNWIInfo(nwi_ifstate_t ifstate)
+{
+       nwi_ifstate_flags               ifstate_flags = nwi_ifstate_get_flags(ifstate);
+       SCNetworkReachabilityFlags      reach_flags = nwi_ifstate_get_reachability_flags(ifstate);
+       const uint8_t                   *signature;
+       int                             signature_length;
+       const struct sockaddr           *vpn_addr = nwi_ifstate_get_vpn_server(ifstate);
+
+       SCPrint(TRUE, stdout,
+               CFSTR(" %7s : flags %p"),
+               nwi_ifstate_get_ifname(ifstate),
+               ifstate_flags);
+       _printNWIFlags(ifstate_flags);
+
+       SCPrint(TRUE, stdout, CFSTR("\n           reach %p ("), reach_flags);
+       __SCNetworkReachabilityPrintFlags(reach_flags);
+       SCPrint(TRUE, stdout, CFSTR(")"));
+
+       if (vpn_addr != NULL) {
+               char vpn_ntopbuf[INET6_ADDRSTRLEN];
+
+               _SC_sockaddr_to_string(vpn_addr, vpn_ntopbuf, sizeof(vpn_ntopbuf));
+               SCPrint(TRUE, stdout, CFSTR("\n           VPN server: %s"), vpn_ntopbuf);
+       }
+
+       signature = nwi_ifstate_get_signature(ifstate, AF_UNSPEC, &signature_length);
+       if (signature != NULL) {
+               CFDataRef       digest  = NULL;
+
+               digest = CFDataCreate(NULL, signature, CC_SHA1_DIGEST_LENGTH);
+               SCPrint(TRUE, stdout, CFSTR("\n           Signature Hash: %@"), digest);
+               CFRelease(digest);
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("\n           Signature Hash: <empty>"));
+       }
+
+       SCPrint(TRUE, stdout, CFSTR("\n           generation %llu\n"),
+               nwi_ifstate_get_generation(ifstate));
+
+       return;
+}
+
+
 __private_extern__
 void
 do_nwi(int argc, char **argv)
 __private_extern__
 void
 do_nwi(int argc, char **argv)
@@ -591,15 +501,7 @@ do_nwi(int argc, char **argv)
        if (argc > 0) {
                ifstate = nwi_state_get_ifstate(state, argv[0]);
                if (ifstate != NULL) {
        if (argc > 0) {
                ifstate = nwi_state_get_ifstate(state, argv[0]);
                if (ifstate != NULL) {
-                       nwi_ifstate_flags       flags   = nwi_ifstate_get_flags(ifstate);
-
-                       SCPrint(TRUE, stdout, CFSTR("Network interface information\n"), argv[0]);
-                       SCPrint(TRUE, stdout,
-                               CFSTR(" %7s : flags %p"),
-                               nwi_ifstate_get_ifname(ifstate),
-                               flags);
-                       _printNWIFlags(flags);
-                       SCPrint(TRUE, stdout, CFSTR("\n"));
+                       _printNWIInfo(ifstate);
                } else {
                        SCPrint(TRUE, stdout, CFSTR("No network information (for %s)\n"), argv[0]);
                }
                } else {
                        SCPrint(TRUE, stdout, CFSTR("No network information (for %s)\n"), argv[0]);
                }
@@ -607,7 +509,9 @@ do_nwi(int argc, char **argv)
                goto done;
        }
 
                goto done;
        }
 
-       SCPrint(TRUE, stdout, CFSTR("Network information\n"));
+       SCPrint(TRUE, stdout, CFSTR("Network information (generation %llu)"),
+               nwi_state_get_generation(state));
+
        SCPrint(TRUE, stdout, CFSTR("\nIPv4 network interface information\n"));
        ifstate = nwi_state_get_first_ifstate(state, AF_INET);
 
        SCPrint(TRUE, stdout, CFSTR("\nIPv4 network interface information\n"));
        ifstate = nwi_state_get_first_ifstate(state, AF_INET);
 
@@ -616,14 +520,7 @@ do_nwi(int argc, char **argv)
        }
 
        while (ifstate != NULL) {
        }
 
        while (ifstate != NULL) {
-               nwi_ifstate_flags       flags   = nwi_ifstate_get_flags(ifstate);
-
-               SCPrint(TRUE, stdout,
-                       CFSTR(" %7s : flags %p"),
-                       nwi_ifstate_get_ifname(ifstate),
-                       flags);
-               _printNWIFlags(flags);
-               SCPrint(TRUE, stdout, CFSTR("\n"));
+               _printNWIInfo(ifstate);
                ifstate = nwi_ifstate_get_next(ifstate, AF_INET);
        }
 
                ifstate = nwi_ifstate_get_next(ifstate, AF_INET);
        }
 
@@ -635,14 +532,7 @@ do_nwi(int argc, char **argv)
        }
 
        while (ifstate != NULL) {
        }
 
        while (ifstate != NULL) {
-               nwi_ifstate_flags       flags   = nwi_ifstate_get_flags(ifstate);
-
-               SCPrint(TRUE, stdout,
-                       CFSTR(" %7s : flags %p"),
-                       nwi_ifstate_get_ifname(ifstate),
-                       flags);
-               _printNWIFlags(flags);
-               SCPrint(TRUE, stdout, CFSTR("\n"));
+               _printNWIInfo(ifstate);
                ifstate = nwi_ifstate_get_next(ifstate, AF_INET6);
        }
 
                ifstate = nwi_ifstate_get_next(ifstate, AF_INET6);
        }
 
@@ -726,7 +616,7 @@ do_watchReachability(int argc, char **argv)
        }
 
        if (doDispatch) {
        }
 
        if (doDispatch) {
-               if (!SCNetworkReachabilitySetDispatchQueue(target_async, dispatch_get_current_queue())) {
+               if (!SCNetworkReachabilitySetDispatchQueue(target_async, dispatch_get_main_queue())) {
                        printf("SCNetworkReachabilitySetDispatchQueue() failed: %s\n", SCErrorString(SCError()));
                        exit(1);
                }
                        printf("SCNetworkReachabilitySetDispatchQueue() failed: %s\n", SCErrorString(SCError()));
                        exit(1);
                }
@@ -749,99 +639,11 @@ do_watchReachability(int argc, char **argv)
 }
 
 
 }
 
 
-static void
-showResolver(dns_resolver_t *resolver, int index)
-{
-       int     i;
-
-       SCPrint(TRUE, stdout, CFSTR("\nresolver #%d\n"), index);
-
-       if (resolver->domain != NULL) {
-               SCPrint(TRUE, stdout, CFSTR("  domain   : %s\n"), resolver->domain);
-       }
-
-       for (i = 0; i < resolver->n_search; i++) {
-               SCPrint(TRUE, stdout, CFSTR("  search domain[%d] : %s\n"), i, resolver->search[i]);
-       }
-
-       for (i = 0; i < resolver->n_nameserver; i++) {
-               char    buf[128];
-
-               _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf));
-               SCPrint(TRUE, stdout, CFSTR("  nameserver[%d] : %s\n"), i, buf);
-       }
-
-       for (i = 0; i < resolver->n_sortaddr; i++) {
-               char    abuf[32];
-               char    mbuf[32];
-
-               (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->address, abuf, sizeof(abuf));
-               (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->mask,    mbuf, sizeof(mbuf));
-               SCPrint(TRUE, stdout, CFSTR("  sortaddr[%d] : %s/%s\n"), i, abuf, mbuf);
-       }
-
-       if (resolver->options != NULL) {
-               SCPrint(TRUE, stdout, CFSTR("  options  : %s\n"), resolver->options);
-       }
-
-       if (resolver->port != 0) {
-               SCPrint(TRUE, stdout, CFSTR("  port     : %hd\n"), resolver->port);
-       }
-
-       if (resolver->timeout != 0) {
-               SCPrint(TRUE, stdout, CFSTR("  timeout  : %d\n"), resolver->timeout);
-       }
-
-       if (resolver->if_index != 0) {
-               char    buf[IFNAMSIZ];
-               char    *if_name;
-
-               if_name = if_indextoname(resolver->if_index, buf);
-               SCPrint(TRUE, stdout, CFSTR("  if_index : %d (%s)\n"),
-                       resolver->if_index,
-                       (if_name != NULL) ? if_name : "?");
-       }
-
-       if (resolver->flags != 0) {
-               uint32_t        flags   = resolver->flags;
-
-               SCPrint(TRUE, stdout, CFSTR("  flags    : "));
-               SCPrint(_sc_debug, stdout, CFSTR("0x%08x ("), flags);
-               if (flags & DNS_RESOLVER_FLAGS_SCOPED) {
-                       SCPrint(TRUE, stdout, CFSTR("Scoped"));
-                       flags &= ~DNS_RESOLVER_FLAGS_SCOPED;
-                       SCPrint(flags != 0, stdout, CFSTR(","));
-               }
-               if (flags != 0) {
-                       SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
-               }
-               SCPrint(_sc_debug, stdout, CFSTR(")"));
-               SCPrint(TRUE, stdout, CFSTR("\n"));
-       }
-
-       if (resolver->reach_flags != 0) {
-               uint32_t        flags   = resolver->reach_flags;
-
-               SCPrint(TRUE, stdout, CFSTR("  reach    : "));
-               SCPrint(_sc_debug, stdout, CFSTR("0x%08x ("), flags);
-               _printReachabilityFlags(flags);
-               SCPrint(_sc_debug, stdout, CFSTR(")"));
-               SCPrint(TRUE, stdout, CFSTR("\n"));
-       }
-
-       if (resolver->search_order != 0) {
-               SCPrint(TRUE, stdout, CFSTR("  order    : %d\n"), resolver->search_order);
-       }
-
-       return;
-}
-
-
 __private_extern__
 void
 do_showDNSConfiguration(int argc, char **argv)
 {
 __private_extern__
 void
 do_showDNSConfiguration(int argc, char **argv)
 {
-       dns_config_t                    *dns_config;
+       dns_config_t    *dns_config;
        SCNetworkReachabilityRef        target;
 
        dns_config = dns_configuration_copy();
        SCNetworkReachabilityRef        target;
 
        dns_config = dns_configuration_copy();
@@ -852,10 +654,10 @@ do_showDNSConfiguration(int argc, char **argv)
        }
 
        if (argc > 1) {
        }
 
        if (argc > 1) {
-               int                             dns_config_index        = -1;
-               SCNetworkReachabilityFlags      flags                   = 0;
-               Boolean                         haveDNS                 = FALSE;
-               Boolean                         ok                      = FALSE;
+               int                             dns_config_index = -1;
+               SCNetworkReachabilityFlags      flags = 0;
+               Boolean                         haveDNS = FALSE;
+               Boolean                         ok = FALSE;
                dns_resolver_t                  *resolver;
                uint32_t                        resolver_if_index;
                SCNetworkReachabilityPrivateRef targetPrivate;
                dns_resolver_t                  *resolver;
                uint32_t                        resolver_if_index;
                SCNetworkReachabilityPrivateRef targetPrivate;
@@ -870,7 +672,7 @@ do_showDNSConfiguration(int argc, char **argv)
                }
 
                ok = __SC_checkResolverReachabilityInternal(&store, &flags,
                }
 
                ok = __SC_checkResolverReachabilityInternal(&store, &flags,
-                                                           &haveDNS, targetPrivate->name, NULL,
+                                                           &haveDNS, targetPrivate->name,
                                                            &resolver_if_index, &dns_config_index);
 
                if (!ok) {
                                                            &resolver_if_index, &dns_config_index);
 
                if (!ok) {
@@ -887,29 +689,15 @@ do_showDNSConfiguration(int argc, char **argv)
                        resolver = dns_config->scoped_resolver[dns_config_index];
                }
 
                        resolver = dns_config->scoped_resolver[dns_config_index];
                }
 
-               showResolver(resolver, dns_config_index + 1);
+               _dns_resolver_print(resolver, dns_config_index + 1);
 
                if (target != NULL) CFRelease(target);
        } else {
 
                if (target != NULL) CFRelease(target);
        } else {
-               int     i;
-
-               SCPrint(TRUE, stdout, CFSTR("DNS configuration\n"));
-
-               for (i = 0; i < dns_config->n_resolver; i++) {
-                       dns_resolver_t  *resolver       = dns_config->resolver[i];
-
-                       showResolver(resolver, i + 1);
-               }
-
-               if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) {
-                       SCPrint(TRUE, stdout, CFSTR("\nDNS configuration (for scoped queries)\n"));
-
-                       for (i = 0; i < dns_config->n_scoped_resolver; i++) {
-                               dns_resolver_t  *resolver       = dns_config->scoped_resolver[i];
+               _dns_configuration_print(dns_config);
+       }
 
 
-                               showResolver(resolver, i + 1);
-                       }
-               }
+       if (_sc_debug) {
+               SCPrint(TRUE, stdout, CFSTR("\ngeneration = %lu\n"), dns_config->generation);
        }
 
        dns_configuration_free(dns_config);
        }
 
        dns_configuration_free(dns_config);
@@ -924,8 +712,9 @@ showProxy(CFDictionaryRef proxy)
 
        if (!_sc_debug) {
                cleaned = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
 
        if (!_sc_debug) {
                cleaned = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
-               CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesSupplemental);
                CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesScoped);
                CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesScoped);
+               CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesServices);
+               CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesSupplemental);
                proxy = cleaned;
        }
 
                proxy = cleaned;
        }
 
@@ -939,9 +728,22 @@ __private_extern__
 void
 do_showProxyConfiguration(int argc, char **argv)
 {
 void
 do_showProxyConfiguration(int argc, char **argv)
 {
-       CFDictionaryRef proxies;
+       CFMutableDictionaryRef  options = NULL;
+       CFDictionaryRef         proxies;
+
+       if (getenv("BYPASS_GLOBAL_PROXY") != NULL) {
+               options = CFDictionaryCreateMutable(NULL, 0,
+                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                   &kCFTypeDictionaryValueCallBacks);
+               CFDictionaryAddValue(options, kSCProxiesNoGlobal, kCFBooleanTrue);
+       }
+
+       proxies = SCDynamicStoreCopyProxiesWithOptions(NULL, options);
+
+       if (options != NULL) {
+               CFRelease(options);
+       }
 
 
-       proxies = SCDynamicStoreCopyProxies(NULL);
        if (proxies != NULL) {
                CFStringRef     interface       = NULL;
                CFStringRef     server          = NULL;
        if (proxies != NULL) {
                CFStringRef     interface       = NULL;
                CFStringRef     server          = NULL;
@@ -1044,6 +846,117 @@ do_snapshot(int argc, char **argv)
 }
 
 
 }
 
 
+__private_extern__
+void
+do_renew(char *if_name)
+{
+       CFArrayRef      services;
+       Boolean         ok      = FALSE;
+
+       if ((if_name == NULL) || (strlen(if_name) == 0)) {
+               SCPrint(TRUE, stderr, CFSTR("No interface name\n"));
+               exit(1);
+       }
+
+       if (getenv("ATTEMPT_DHCP_RENEW_WITH_SCDYNAMICSTORE") != NULL) {
+               CFArrayRef      interfaces;
+
+               interfaces = SCNetworkInterfaceCopyAll();
+               if (interfaces != NULL) {
+                       CFIndex         i;
+                       CFStringRef     match_name;
+                       CFIndex         n;
+
+                       match_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII);
+                       assert(match_name != NULL);
+
+                       n = CFArrayGetCount(interfaces);
+                       for (i = 0; i < n; i++) {
+                               CFStringRef             bsd_name;
+                               SCNetworkInterfaceRef   interface;
+
+                               interface = CFArrayGetValueAtIndex(interfaces, i);
+                               bsd_name = SCNetworkInterfaceGetBSDName(interface);
+                               if (_SC_CFEqual(bsd_name, match_name)) {
+                                       // if match
+                                       ok = SCNetworkInterfaceForceConfigurationRefresh(interface);
+                                       if (!ok) {
+                                               int     status;
+
+                                               status = SCError();
+                                               if (status != kSCStatusAccessError) {
+                                                       SCPrint(TRUE, stderr, CFSTR("%s\n"), SCErrorString(status));
+                                                       exit(1);
+                                               }
+
+                                               // ... and if can't write the SCDynamicStore, try w/prefs
+                                       }
+
+                                       break;
+                               }
+                       }
+
+                       CFRelease(match_name);
+                       CFRelease(interfaces);
+               }
+
+               if (ok) {
+                       exit(0);
+               }
+       }
+
+       do_prefs_init();        /* initialization */
+       do_prefs_open(0, NULL); /* open default prefs */
+
+       services = SCNetworkServiceCopyAll(prefs);
+       if (services != NULL) {
+               CFIndex         i;
+               CFStringRef     match_name;
+               CFIndex         n;
+
+               match_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII);
+               assert(match_name != NULL);
+
+               n = CFArrayGetCount(services);
+               for (i = 0; i < n; i++) {
+                       CFStringRef             bsd_name;
+                       SCNetworkInterfaceRef   interface;
+                       SCNetworkServiceRef     service;
+
+                       service = CFArrayGetValueAtIndex(services, i);
+                       interface = SCNetworkServiceGetInterface(service);
+                       if (interface == NULL) {
+                               // if no interface
+                               continue;
+                       }
+
+                       bsd_name = SCNetworkInterfaceGetBSDName(interface);
+                       if (_SC_CFEqual(bsd_name, match_name)) {
+                               // if match
+                               ok = SCNetworkInterfaceForceConfigurationRefresh(interface);
+                               if (!ok) {
+                                       SCPrint(TRUE, stderr, CFSTR("%s\n"), SCErrorString(SCError()));
+                                       exit(1);
+                               }
+
+                               break;
+                       }
+               }
+
+               CFRelease(match_name);
+               CFRelease(services);
+       }
+
+       if (!ok) {
+               SCPrint(TRUE, stderr, CFSTR("No interface\n"));
+               exit(1);
+       }
+
+       _prefs_close();
+       exit(0);
+}
+
+
 static void
 waitKeyFound()
 {
 static void
 waitKeyFound()
 {
@@ -1116,8 +1029,9 @@ do_wait(char *waitKey, int timeout)
        CFRunLoopRun();
 }
 
        CFRunLoopRun();
 }
 
-#ifdef TEST_DNS_CONFIGURATION_COPY
+#ifdef TEST_DNS_CONFIGURATION
 
 
+Boolean                        doDispatch      = FALSE;
 CFRunLoopSourceRef     notifyRls       = NULL;
 SCDynamicStoreRef      store           = NULL;
 CFPropertyListRef      value           = NULL;
 CFRunLoopSourceRef     notifyRls       = NULL;
 SCDynamicStoreRef      store           = NULL;
 CFPropertyListRef      value           = NULL;
@@ -1125,8 +1039,26 @@ CFPropertyListRef        value           = NULL;
 int
 main(int argc, char **argv)
 {
 int
 main(int argc, char **argv)
 {
+       dns_config_t    *dns_config;
+
+fprintf(stdout, "copy configuration\n");
+       dns_config = dns_configuration_copy();
+       if (dns_config != NULL) {
+
+fprintf(stdout, "sleeping for 120 seconds\n");
+sleep(120);
+
+fprintf(stdout, "sending ack\n");
+               _dns_configuration_ack(dns_config, "TEST_DNS_CONFIGURATION");
+
+fprintf(stdout, "sleeping for 120 seconds\n");
+sleep(120);
+
+               dns_configuration_free(dns_config);
+       }
+
        do_showDNSConfiguration(argc, argv);
        exit(0);
 }
 
        do_showDNSConfiguration(argc, argv);
        exit(0);
 }
 
-#endif // TEST_DNS_CONFIGURATION_COPY
+#endif // TEST_DNS_CONFIGURATION
index 6b5c0e9ad8e9a00f187fd1022255a6419e85984a..996a64e814483be4a705bbc469bcbd0a933ab197 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000, 2001, 2004, 2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2004, 2007, 2011, 2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -42,6 +42,7 @@ __BEGIN_DECLS
 
 void   do_checkReachability            (int argc, char **argv);
 void   do_watchReachability            (int argc, char **argv);
 
 void   do_checkReachability            (int argc, char **argv);
 void   do_watchReachability            (int argc, char **argv);
+void   do_renew                        (char *interface);
 void   do_showDNSConfiguration         (int argc, char **argv);
 void   do_showProxyConfiguration       (int argc, char **argv);
 void   do_snapshot                     (int argc, char **argv);
 void   do_showDNSConfiguration         (int argc, char **argv);
 void   do_showProxyConfiguration       (int argc, char **argv);
 void   do_snapshot                     (int argc, char **argv);
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644 (file)
index 0000000..5079e8f
--- /dev/null
@@ -0,0 +1,24 @@
+PLATFORM=iphoneos
+
+ifeq ($(PLATFORM),iphoneos)
+ARCHS=armv7
+endif
+
+ifeq ($(PLATFORM),macosx)
+ARCHS=i386 x86_64
+endif
+
+FRAMEWORKS=CoreFoundation SystemConfiguration CFNetwork
+SDK=$(PLATFORM).internal
+SYSROOT=$(shell xcodebuild -version -sdk $(SDK) Path)
+PF_INC=-F$(SYSROOT)/System/Library/PrivateFrameworks
+ARCH_FLAGS=$(foreach a,$(ARCHS),-arch $(a))
+FW_FLAGS=$(foreach f,$(FRAMEWORKS),-framework $(f))
+CC=xcrun -sdk $(SDK) cc
+
+ReachabilityTester : ReachabilityTester.c
+       $(CC) $(ARCH_FLAGS) -isysroot $(SYSROOT) $(PF_INC) $(FW_FLAGS) -g -o $@ $<
+       tar -czf $@.tgz $@ $@.dSYM $<
+
+clean :
+       rm -rf ReachabilityTester ReachabilityTester.dSYM ReachabilityTester.tgz
diff --git a/tests/ReachabilityTester.c b/tests/ReachabilityTester.c
new file mode 100644 (file)
index 0000000..41ee485
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2012 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 <stdio.h>
+#include <pthread.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CFNetwork/CFNetwork.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+static SCNetworkReachabilityRef g_reachability = NULL;
+static CFURLRef g_url = NULL;
+static CFReadStreamRef g_rstream = NULL;
+
+static char *
+string2CString(CFStringRef str)
+{
+    UInt8 *buffer;
+    CFIndex clen;
+    CFRange r = CFRangeMake(0, CFStringGetLength(str));
+
+    if (CFStringGetBytes(str, r, kCFStringEncodingASCII, 0, false, NULL, 0, &clen) > 0) {
+       buffer = (UInt8 *)CFAllocatorAllocate(kCFAllocatorDefault, (clen + 1) * sizeof(UInt8), 0);
+
+       if (buffer != NULL) {
+           if (CFStringGetBytes(str, r, kCFStringEncodingASCII, 0, false, buffer, clen, NULL)) {
+               buffer[clen] = '\0';
+               return (char *)buffer;
+           }
+           CFAllocatorDeallocate(kCFAllocatorDefault, buffer);
+       }
+    }
+
+    return NULL;
+}
+
+static void
+printReachabilityFlags(const char *source, SCNetworkReachabilityFlags flags)
+{
+    printf("[%s] Reachability flags (%x):\n", source, flags);
+    if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
+       printf("[%s]  transient\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsReachable) {
+       printf("[%s]  reachable\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
+       printf("[%s]  connection required\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
+       printf("[%s]  connection on traffic\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
+       printf("[%s]  intervention required\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
+       printf("[%s]  connection on demand\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
+       printf("[%s]  local address\n", source);
+    }
+    if (flags & kSCNetworkReachabilityFlagsIsDirect) {
+       printf("[%s]  direct\n", source);
+    }
+#if TARGET_OS_EMBEDDED
+    if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
+       printf("[%s]  wwan\n", source);
+    }
+#endif
+}
+
+static void
+handleReachabilityUpdate(
+       SCNetworkReachabilityRef target,
+       SCNetworkReachabilityFlags flags,
+       void *info)
+{
+    printReachabilityFlags("RunLoop", flags);
+}
+
+static SCNetworkReachabilityRef
+createReachabilityWithCFHost(CFHostRef theHost)
+{
+    SCNetworkReachabilityRef reachRef = NULL;
+    Boolean resolved = FALSE;
+    CFArrayRef addrs = CFHostGetAddressing(theHost, &resolved);
+
+    if (resolved && addrs != NULL && CFArrayGetCount(addrs) > 0) {
+       CFDataRef addr = (CFDataRef)CFArrayGetValueAtIndex(addrs, 0);
+
+       reachRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr *)CFDataGetBytePtr(addr));
+    } else {
+       CFArrayRef names = CFHostGetNames(theHost, NULL);
+
+       if (names != NULL && CFArrayGetCount(names) > 0) {
+           CFStringRef host = (CFStringRef)CFArrayGetValueAtIndex(names, 0);
+           char *chost = string2CString(host);
+
+           reachRef = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, chost);
+
+           CFAllocatorDeallocate(kCFAllocatorDefault, chost);
+       }
+    }
+
+    if (reachRef != NULL) {
+       SCNetworkReachabilityContext reach_ctx = { 0, NULL, NULL, NULL, NULL };
+       SCNetworkReachabilitySetCallback(reachRef, handleReachabilityUpdate,
+                                        &reach_ctx);
+       CFShow(reachRef);
+    } else {
+       fprintf(stderr, "Failed to create a reachability object\n");
+    }
+
+    return reachRef;
+}
+
+static void
+handleDownload(CFReadStreamRef rstream, CFStreamEventType eventType, void *info)
+{
+    Boolean done = FALSE;
+
+    if (eventType == kCFStreamEventHasBytesAvailable) {
+       UInt8 buffer[1024];
+
+       while (CFReadStreamHasBytesAvailable(rstream)) {
+           CFIndex count = CFReadStreamRead(rstream, buffer, sizeof(buffer));
+           if (count == 0) {
+               done = TRUE;
+           }
+       }
+    } else if (eventType == kCFStreamEventEndEncountered) {
+       printf("Download completed\n");
+       done = TRUE;
+    } else if (eventType == kCFStreamEventErrorOccurred) {
+       printf("Download error\n");
+       done = TRUE;
+    } else {
+       printf("Got stream event: %lu\n", eventType);
+    }
+
+    if (!done) {
+       return;
+    }
+
+    CFReadStreamUnscheduleFromRunLoop(rstream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    CFReadStreamClose(rstream);
+    CFRelease(rstream);
+
+    g_rstream = NULL;
+}
+
+static void
+startDownload(void)
+{
+    CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), g_url, kCFHTTPVersion1_1);
+    CFReadStreamRef rstream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
+    CFStreamClientContext ctx = { 0, NULL, NULL, NULL, NULL };
+
+    printf("Starting download\n");
+
+    CFReadStreamSetClient(rstream,
+                         kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred | kCFStreamEventHasBytesAvailable, 
+                         handleDownload,
+                         &ctx);
+
+    CFReadStreamScheduleWithRunLoop(rstream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+
+    CFReadStreamOpen(rstream);
+
+    g_rstream = rstream;
+
+    CFRelease(request);
+}
+
+static void
+downloadTimerFired(CFRunLoopTimerRef timer, void *info)
+{
+    if (g_rstream != NULL) {
+       handleDownload(g_rstream, kCFStreamEventErrorOccurred, NULL);
+    }
+
+
+    SCNetworkReachabilityUnscheduleFromRunLoop(g_reachability, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+
+    startDownload();
+
+    SCNetworkReachabilityScheduleWithRunLoop(g_reachability, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+}
+
+static void
+startDownloadLoop(void)
+{
+    CFRunLoopTimerRef timer;
+    CFRunLoopTimerContext ctx = { 0, NULL, NULL, NULL, NULL };
+    CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+
+    timer = CFRunLoopTimerCreate(kCFAllocatorDefault, 
+                                now + 0.1,
+                                7.0,
+                                0,
+                                0,
+                                downloadTimerFired,
+                                &ctx);
+
+    CFRunLoopAddTimer(CFRunLoopGetMain(), timer, kCFRunLoopCommonModes);
+}
+
+static void *
+reachabilityLoop(void *arg)
+{
+    while (1) {
+       SCNetworkReachabilityFlags flags;
+       SCNetworkReachabilityGetFlags(g_reachability, &flags);
+
+       printReachabilityFlags("thread", flags);
+
+       sleep(1);
+    }
+
+    return NULL;
+}
+
+static void
+startReachabilityThread(void)
+{
+    pthread_attr_t tattr;
+    pthread_t th;
+
+    pthread_attr_init(&tattr);
+    pthread_create(&th, &tattr, reachabilityLoop, NULL);
+    pthread_attr_destroy(&tattr);
+}
+
+static void
+addressResolutionCallback(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info)
+{
+    g_reachability = createReachabilityWithCFHost(theHost);
+
+    if (g_reachability != NULL) {
+       startDownloadLoop();
+       startReachabilityThread();
+    }
+
+    CFRelease(theHost);
+}
+
+static void
+startAddressResolution(Boolean resolve)
+{
+    CFStringRef hostStr = CFURLCopyHostName(g_url);
+    CFHostRef cfhost = CFHostCreateWithName(kCFAllocatorDefault, hostStr);
+    CFHostClientContext ctx = { 0, NULL, NULL, NULL, NULL };
+    CFStreamError err;
+
+    if (resolve) {
+       CFHostSetClient(cfhost, addressResolutionCallback, &ctx);
+       CFHostScheduleWithRunLoop(cfhost, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+       CFHostStartInfoResolution(cfhost, kCFHostAddresses, &err);
+    } else {
+       addressResolutionCallback(cfhost, kCFHostNames, NULL, NULL);
+    }
+
+    CFRelease(hostStr);
+}
+
+int
+main(int argc, char *argv[])
+{
+    CFStringRef urlStr;
+    Boolean resolve = TRUE;
+
+    if (argc < 2) {
+       fprintf(stderr, "usage: %s <url> [-byname]", argv[0]);
+       return 1;
+    }
+
+    urlStr = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingASCII);
+    g_url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL);
+
+    CFRelease(urlStr);
+
+    if (argc > 2 && !strcmp(argv[2], "-byname")) {
+       resolve = FALSE;
+    }
+
+    startAddressResolution(resolve);
+
+    CFRunLoopRun();
+
+    CFRelease(g_url);
+
+    SCNetworkReachabilityUnscheduleFromRunLoop(g_reachability, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+    CFRelease(g_reachability);
+
+    return 0;
+}