From 5e9ce69ef59d7d98ff13748ce18266968031faaf Mon Sep 17 00:00:00 2001 From: Apple Date: Tue, 29 Oct 2013 00:03:35 +0000 Subject: [PATCH] configd-596.12.tar.gz --- IPMonitorLogging.mobileconfig | 51 + Makefile | 4 + Plugins/IPMonitor/Info.plist | 4 +- Plugins/IPMonitor/Makefile | 77 +- .../IPMonitor/com.apple.networking.IPMonitor | 1 + Plugins/IPMonitor/dns-configuration.c | 579 ++- Plugins/IPMonitor/dns-configuration.h | 5 +- Plugins/IPMonitor/ip_plugin.c | 2692 ++++++++--- Plugins/IPMonitor/ip_plugin.h | 63 + Plugins/IPMonitor/proxy-configuration.c | 125 +- Plugins/IPMonitor/proxy-configuration.h | 7 +- Plugins/IPMonitor/set-hostname.c | 78 +- Plugins/IPMonitor/set-hostname.h | 3 +- Plugins/IPMonitor/smb-configuration.c | 89 +- Plugins/IPMonitor/smb-configuration.h | 3 +- .../IPMonitor/test_ipv4_routelist_filter.sh | 9 +- .../test_ipv4_routelist_reference.txt | 94 +- Plugins/IPMonitor/test_reference.sh | 4 +- Plugins/InterfaceNamer/Info.plist | 4 +- Plugins/InterfaceNamer/ifnamer.c | 316 +- Plugins/KernelEventMonitor/Info.plist | 4 +- Plugins/KernelEventMonitor/ev_dlil.c | 74 +- Plugins/KernelEventMonitor/ev_dlil.h | 15 +- Plugins/KernelEventMonitor/ev_ipv4.h | 5 +- Plugins/KernelEventMonitor/ev_ipv6.c | 5 +- Plugins/KernelEventMonitor/ev_ipv6.h | 3 +- Plugins/KernelEventMonitor/eventmon.c | 40 +- Plugins/KernelEventMonitor/eventmon.h | 3 +- Plugins/LinkConfiguration/Info.plist | 4 +- Plugins/LinkConfiguration/linkconfig.c | 5 +- Plugins/Logger/Info-Embedded.plist | 4 +- Plugins/Logger/Info.plist | 4 +- Plugins/Logger/logger.c | 8 +- Plugins/PreferencesMonitor/Info.plist | 4 +- Plugins/PreferencesMonitor/prefsmon.c | 10 +- Plugins/SCNetworkReachability/Info.plist | 4 +- Plugins/SimulatorSupport/Info.plist | 26 + Plugins/SimulatorSupport/simulator_support.c | 311 ++ Plugins/common/IPMonitorControlPrefs.c | 282 ++ Plugins/common/IPMonitorControlPrefs.h | 54 + SCMonitor/Info.plist | 4 +- SCMonitor/monitor.c | 8 +- SystemConfiguration.fproj/BondConfiguration.c | 177 +- .../BridgeConfiguration.c | 101 +- SystemConfiguration.fproj/CaptiveNetwork.c | 10 +- SystemConfiguration.fproj/CaptiveNetwork.h | 6 +- .../English.lproj/NetworkInterface.strings | Bin 5856 -> 6418 bytes SystemConfiguration.fproj/Info-Embedded.plist | 6 +- SystemConfiguration.fproj/Info.plist | 6 +- SystemConfiguration.fproj/LinkConfiguration.c | 89 +- SystemConfiguration.fproj/LinkConfiguration.h | 126 - SystemConfiguration.fproj/SCD.c | 471 +- .../SCDNotifierInformViaCallback.c | 38 +- SystemConfiguration.fproj/SCDOpen.c | 71 +- SystemConfiguration.fproj/SCDPlugin.c | 26 +- SystemConfiguration.fproj/SCDPrivate.c | 112 +- .../SCDynamicStoreCopyDHCPInfo.h | 6 +- .../SCDynamicStoreInternal.h | 2 +- .../SCDynamicStorePrivate.h | 3 +- .../SCNetworkConfigurationInternal.c | 23 +- .../SCNetworkConfigurationInternal.h | 12 +- .../SCNetworkConfigurationPrivate.h | 146 +- .../SCNetworkConnection.c | 2561 +++++++++-- .../SCNetworkConnectionInternal.h | 39 +- .../SCNetworkConnectionPrivate.c | 4 +- .../SCNetworkConnectionPrivate.h | 350 +- .../SCNetworkInterface.c | 345 +- .../SCNetworkReachability.c | 2845 +++++++----- .../SCNetworkReachabilityInternal.h | 169 +- SystemConfiguration.fproj/SCNetworkService.c | 141 +- SystemConfiguration.fproj/SCNetworkSet.c | 321 +- .../SCNetworkSignature.c | 166 +- .../SCNetworkSignature.h | 9 +- .../SCNetworkSignaturePrivate.h | 10 +- SystemConfiguration.fproj/SCPCommit.c | 9 +- SystemConfiguration.fproj/SCPOpen.c | 139 +- SystemConfiguration.fproj/SCPPath.c | 4 +- .../SCPreferencesInternal.h | 3 +- .../SCPreferencesPrivate.h | 26 +- SystemConfiguration.fproj/SCPrivate.h | 168 +- SystemConfiguration.fproj/SCProxies.c | 158 +- .../SCSchemaDefinitions.c | 54 + .../SCSchemaDefinitions.h | 75 +- .../SCSchemaDefinitionsPrivate.h | 716 ++- SystemConfiguration.fproj/SNHelper.c | 138 + SystemConfiguration.fproj/SNHelperPrivate.h | 32 + .../SystemConfiguration.h | 5 +- SystemConfiguration.fproj/VLANConfiguration.c | 184 +- SystemConfiguration.fproj/VPNAppLayer.c | 5 + .../VPNAppLayerPrivate.h | 5 + SystemConfiguration.fproj/VPNConfiguration.c | 2 +- SystemConfiguration.fproj/VPNConfiguration.h | 2 +- SystemConfiguration.fproj/VPNFlow.c | 4 + SystemConfiguration.fproj/VPNFlow.h | 4 + SystemConfiguration.fproj/VPNFlowPrivate.h | 4 + SystemConfiguration.fproj/VPNPrivate.c | 2 +- SystemConfiguration.fproj/VPNService.c | 423 ++ SystemConfiguration.fproj/VPNTunnel.c | 2 +- SystemConfiguration.fproj/VPNTunnel.h | 2 +- SystemConfiguration.fproj/VPNTunnelPrivate.h | 2 +- SystemConfiguration.fproj/config_types.h | 7 +- SystemConfiguration.fproj/dy_framework.c | 7 +- SystemConfiguration.fproj/dy_framework.h | 13 +- SystemConfiguration.fproj/genSCPreferences.c | 242 +- .../helper/SCHelper_server.c | 560 ++- .../helper/com.apple.SCHelper-embedded.plist | 2 + .../helper/com.apple.SCHelper.plist | 4 +- .../SCNetworkReachabilityServer_client.c | 239 +- .../SCNetworkReachabilityServer_server.c | 381 +- SystemConfiguration.fproj/reachability/rb.c | 1323 ------ SystemConfiguration.fproj/reachability/rb.h | 195 - SystemConfiguration.fproj/scprefs_observer.c | 333 ++ SystemConfiguration.fproj/scprefs_observer.h | 60 + SystemConfiguration.fproj/update-headers | 2 + configd.tproj/_SCD.c | 15 +- configd.tproj/_configadd.c | 4 +- configd.tproj/_configclose.c | 4 +- configd.tproj/_confignotify.c | 4 +- configd.tproj/_configremove.c | 4 +- configd.tproj/_configset.c | 68 +- configd.tproj/_notifyremove.c | 4 +- configd.tproj/com.apple.configd.plist | 4 + configd.tproj/com.apple.configd_sim.plist | 32 + configd.tproj/configd.8 | 4 +- configd.tproj/configd.m | 12 +- configd.tproj/configd_server.c | 25 +- configd.tproj/entitlements.plist | 9 + configd.tproj/pattern.c | 140 +- configd.tproj/pattern.h | 5 +- configd.tproj/plugin_support.c | 66 +- configd.tproj/session.c | 274 +- configd.tproj/session.h | 35 +- configd.xcodeproj/project.pbxproj | 4065 +++++++---------- dnsinfo/dnsinfo.h | 18 +- dnsinfo/dnsinfo_copy.c | 354 +- dnsinfo/dnsinfo_create.c | 267 +- dnsinfo/dnsinfo_create.h | 72 +- dnsinfo/dnsinfo_flatfile.c | 55 +- dnsinfo/dnsinfo_internal.h | 185 + dnsinfo/dnsinfo_private.c | 92 - dnsinfo/dnsinfo_private.h | 27 +- dnsinfo/dnsinfo_server.c | 489 +- dnsinfo/dnsinfo_server.h | 37 +- dnsinfo/shared_dns_info.defs | 76 - get-mobility-info | 1025 ++--- .../libSystemConfiguration_client.c | 208 + .../libSystemConfiguration_client.h | 116 + .../libSystemConfiguration_server.c | 364 ++ .../libSystemConfiguration_server.h | 115 + nwi/network_information.c | 426 +- nwi/network_information.h | 93 +- nwi/network_information_priv.c | 374 +- nwi/network_information_priv.h | 132 +- nwi/network_information_server.c | 511 +++ nwi/network_information_server.h | 53 + scselect.tproj/scselect.c | 161 +- scutil.tproj/cache.c | 2 +- scutil.tproj/nc.c | 677 ++- scutil.tproj/net_interface.c | 40 +- scutil.tproj/net_set.c | 22 +- scutil.tproj/notifications.c | 4 +- scutil.tproj/prefs.c | 153 +- scutil.tproj/prefs.h | 6 +- scutil.tproj/scutil.8 | 20 +- scutil.tproj/scutil.c | 111 +- scutil.tproj/scutil.h | 5 +- scutil.tproj/tests.c | 672 ++- scutil.tproj/tests.h | 3 +- tests/Makefile | 24 + tests/ReachabilityTester.c | 316 ++ 170 files changed, 20728 insertions(+), 10363 deletions(-) create mode 100644 IPMonitorLogging.mobileconfig create mode 100644 Plugins/IPMonitor/com.apple.networking.IPMonitor create mode 100644 Plugins/IPMonitor/ip_plugin.h create mode 100644 Plugins/SimulatorSupport/Info.plist create mode 100644 Plugins/SimulatorSupport/simulator_support.c create mode 100644 Plugins/common/IPMonitorControlPrefs.c create mode 100644 Plugins/common/IPMonitorControlPrefs.h delete mode 100644 SystemConfiguration.fproj/LinkConfiguration.h rename dnsinfo/shared_dns_info_types.h => SystemConfiguration.fproj/SCNetworkConnectionInternal.h (55%) create mode 100644 SystemConfiguration.fproj/SNHelper.c create mode 100644 SystemConfiguration.fproj/SNHelperPrivate.h create mode 100644 SystemConfiguration.fproj/VPNAppLayer.c create mode 100644 SystemConfiguration.fproj/VPNAppLayerPrivate.h create mode 100644 SystemConfiguration.fproj/VPNFlow.c create mode 100644 SystemConfiguration.fproj/VPNFlow.h create mode 100644 SystemConfiguration.fproj/VPNFlowPrivate.h create mode 100644 SystemConfiguration.fproj/VPNService.c delete mode 100644 SystemConfiguration.fproj/reachability/rb.c delete mode 100644 SystemConfiguration.fproj/reachability/rb.h create mode 100644 SystemConfiguration.fproj/scprefs_observer.c create mode 100644 SystemConfiguration.fproj/scprefs_observer.h create mode 100644 configd.tproj/com.apple.configd_sim.plist create mode 100644 dnsinfo/dnsinfo_internal.h delete mode 100644 dnsinfo/dnsinfo_private.c delete mode 100644 dnsinfo/shared_dns_info.defs create mode 100644 libSystemConfiguration/libSystemConfiguration_client.c create mode 100644 libSystemConfiguration/libSystemConfiguration_client.h create mode 100644 libSystemConfiguration/libSystemConfiguration_server.c create mode 100644 libSystemConfiguration/libSystemConfiguration_server.h create mode 100644 nwi/network_information_server.c create mode 100644 nwi/network_information_server.h create mode 100644 tests/Makefile create mode 100644 tests/ReachabilityTester.c diff --git a/IPMonitorLogging.mobileconfig b/IPMonitorLogging.mobileconfig new file mode 100644 index 0000000..6599da7 --- /dev/null +++ b/IPMonitorLogging.mobileconfig @@ -0,0 +1,51 @@ + + + + + PayloadContent + + + PayloadDescription + Enables IPMonitor verbose logging. + PayloadDisplayName + IPMonitor Logging + PayloadIdentifier + com.apple.defaults.managed.IPMonitor.control + PayloadOrganization + Apple, Inc + PayloadType + com.apple.defaults.managed + PayloadUUID + CA2DD325-2123-487C-BF89-170AF64FD8C0 + PayloadVersion + 1 + PayloadContent + + + DefaultsDomainName + com.apple.IPMonitor.control + DefaultsData + + Verbose + + + + + + + PayloadDescription + Enables IPMonitor verbose logging. + PayloadDisplayName + IPMonitor Logging + PayloadIdentifier + com.apple.IPMonitor.control + PayloadOrganization + Apple, Inc + PayloadType + Configuration + PayloadUUID + CA2DD325-2123-487C-BF89-170AF64FD8C0 + PayloadVersion + 1 + + diff --git a/Makefile b/Makefile index af81588..79147d2 100644 --- 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_SDKROOT=$(shell xcodebuild -version -sdk macosx10.7internal Path) + 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)" \ + -- \ + SDKROOT=$(LION_SDKROOT) \ diff --git a/Plugins/IPMonitor/Info.plist b/Plugins/IPMonitor/Info.plist index 09072ba..91375db 100644 --- a/Plugins/IPMonitor/Info.plist +++ b/Plugins/IPMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Requires com.apple.SystemConfiguration.IPConfiguration diff --git a/Plugins/IPMonitor/Makefile b/Plugins/IPMonitor/Makefile index 5b0750c..41bb910 100644 --- a/Plugins/IPMonitor/Makefile +++ b/Plugins/IPMonitor/Makefile @@ -1,58 +1,78 @@ 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 - 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 - 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 - 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 - 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 - 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 - 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 @@ -63,16 +83,15 @@ test_ipv4_routelist_test: test_ipv4_routelist # ---------- 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 \ - 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 \ diff --git a/Plugins/IPMonitor/com.apple.networking.IPMonitor b/Plugins/IPMonitor/com.apple.networking.IPMonitor new file mode 100644 index 0000000..2f4a10a --- /dev/null +++ b/Plugins/IPMonitor/com.apple.networking.IPMonitor @@ -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) diff --git a/Plugins/IPMonitor/dns-configuration.c b/Plugins/IPMonitor/dns-configuration.c index bd20b75..5815609 100644 --- a/Plugins/IPMonitor/dns-configuration.c +++ b/Plugins/IPMonitor/dns-configuration.c @@ -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@ * @@ -51,16 +51,20 @@ extern uint32_t notify_monitor_file(int token, const char *name, int flags); #include #include #include +#include "ip_plugin.h" #include "dns-configuration.h" #include -#include +#include "dnsinfo_create.h" +#include "dnsinfo_server.h" #ifdef MAIN #undef MAIN #include "dnsinfo_copy.c" +#include "dnsinfo_internal.h" #define MAIN +#define DNS_CONFIGURATION_DEBUG #endif // MAIN #include @@ -82,6 +86,119 @@ static CFNumberRef S_mdns_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) { @@ -93,7 +210,7 @@ add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver) order = CFDictionaryGetValue(resolver, kSCPropNetDNSSearchOrder); if (!isA_CFNumber(order) || - !CFNumberGetValue(order, kCFNumberIntType, &order_val)) { + !CFNumberGetValue(order, kCFNumberSInt32Type, &order_val)) { 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) || - !CFNumberGetValue(match_order, kCFNumberIntType, &match_order_val)) { + !CFNumberGetValue(match_order, kCFNumberSInt32Type, &match_order_val)) { match_order_val = 0; } @@ -142,7 +259,7 @@ add_resolver(CFMutableArrayRef resolvers, CFMutableDictionaryRef resolver) 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]; @@ -258,7 +375,11 @@ add_supplemental(CFMutableArrayRef resolvers, CFDictionaryRef dns, uint32_t defa 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; @@ -282,19 +403,59 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef services 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(dns)) { + dns = isA_CFDictionary(dns); + if (dns == NULL) { 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); @@ -304,7 +465,52 @@ add_supplemental_resolvers(CFMutableArrayRef resolvers, CFDictionaryRef 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) { @@ -416,13 +622,13 @@ compareBySearchOrder(const void *val1, const void *val2, void *context) 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) || - !CFNumberGetValue(num2, kCFNumberIntType, &order2)) { + !CFNumberGetValue(num2, kCFNumberSInt32Type, &order2)) { 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) && - CFNumberGetValue(num1, kCFNumberIntType, &order1) && - CFNumberGetValue(num2, kCFNumberIntType, &order2)) { + CFNumberGetValue(num1, kCFNumberSInt32Type, &order1) && + CFNumberGetValue(num2, kCFNumberSInt32Type, &order2)) { 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) || - !CFNumberGetValue(num, kCFNumberIntType, &defaultOrder)) { + !CFNumberGetValue(num, kCFNumberSInt32Type, &defaultOrder)) { 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; + int noSearch; CFNumberRef num; CFStringRef options; CFStringRef supplementalDomain; @@ -607,6 +814,14 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme 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); @@ -619,7 +834,7 @@ extract_search_domains(CFMutableDictionaryRef defaultDomain, CFArrayRef suppleme num = CFDictionaryGetValue(dns, kSCPropNetDNSSearchOrder); if (!isA_CFNumber(num) || - !CFNumberGetValue(num, kCFNumberIntType, &supplementalOrder)) { + !CFNumberGetValue(num, kCFNumberSInt32Type, &supplementalOrder)) { 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); - } else{ + } else { order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } @@ -714,6 +929,7 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray CFArrayRef searchDomains; CFDictionaryRef service; CFStringRef serviceID; + uint32_t these_flags; serviceID = CFArrayGetValueAtIndex(order, i); service = CFDictionaryGetValue(services, serviceID); @@ -729,10 +945,16 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray } 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; } + 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; + + 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); @@ -773,7 +1003,13 @@ add_scoped_resolvers(CFMutableArrayRef scoped, CFDictionaryRef services, CFArray CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains); CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchOrders); + // add the [scoped] resolver add_resolver(scoped, newDNS); + + // add any supplemental resolver configurations for this interface + add_supplemental_resolvers(scoped, services, service_order, interface, service); + + skip: 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, @@ -801,12 +1105,13 @@ add_default_resolver(CFMutableArrayRef resolvers, } 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) || - !CFNumberGetValue(order, kCFNumberIntType, &myOrder)) { + !CFNumberGetValue(order, kCFNumberSInt32Type, &myOrder)) { 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) { @@ -851,7 +1139,6 @@ create_resolver(CFDictionaryRef dns) CFNumberRef num; dns_create_resolver_t _resolver; CFStringRef str; - CFMutableArrayRef serverAddresses = NULL; 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 + // 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); - serverAddresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - 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]; - CFDataRef serverAddress; str = CFArrayGetValueAtIndex(list, i); if (!isA_CFString(str)) { @@ -948,10 +1243,6 @@ create_resolver(CFDictionaryRef dns) } _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 (CFNumberGetValue(num, kCFNumberIntType, &order)) { + if (CFNumberGetValue(num, kCFNumberSInt32Type, &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)) { - 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); } @@ -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) { @@ -1256,11 +1499,12 @@ dns_configuration_set(CFDictionaryRef defaultResolver, CFArrayRef privateResolvers) { dns_create_config_t _config; - Boolean changed = FALSE; + Boolean changed = FALSE; + uint32_t dns_resolver_flags = 0; 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]; @@ -1269,10 +1513,11 @@ dns_configuration_set(CFDictionaryRef defaultResolver, // establish list of resolvers resolvers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + assert(resolvers != NULL); // 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 @@ -1290,6 +1535,10 @@ dns_configuration_set(CFDictionaryRef defaultResolver, 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); @@ -1349,36 +1598,80 @@ dns_configuration_set(CFDictionaryRef defaultResolver, */ _config = _dns_configuration_create(); - // add resolvers + CFDictionaryApplyFunction(services, add_dns_query_flags , &dns_resolver_flags); for (i = 0; i < n_resolvers; i++) { + boolean_t is_default_resolver; 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); + + if (is_default_resolver) { + CFRelease(resolver); + } } #if !TARGET_OS_IPHONE // add flatfile resolvers + _dnsinfo_flatfile_set_flags(dns_resolver_flags); _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) { + // 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; } - 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); @@ -1408,7 +1701,7 @@ dns_configuration_changed(CFMachPortRef port, void *msg, CFIndex size, void *inf } 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); @@ -1433,13 +1726,13 @@ dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callou status = notify_register_mach_port(_PATH_RESOLVER_DIR, ¬ify_port, 0, ¬ify_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) { - 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; } @@ -1451,7 +1744,7 @@ dns_configuration_monitor(SCDynamicStoreRef store, SCDynamicStoreCallBack callou 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; @@ -1513,7 +1806,21 @@ split(const void * key, const void * value, void * context) 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) { @@ -1525,9 +1832,9 @@ split(const void * key, const void * value, void * context) 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); diff --git a/Plugins/IPMonitor/dns-configuration.h b/Plugins/IPMonitor/dns-configuration.h index 08dc9e1..b218d3a 100644 --- a/Plugins/IPMonitor/dns-configuration.h +++ b/Plugins/IPMonitor/dns-configuration.h @@ -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@ * @@ -34,17 +34,14 @@ __BEGIN_DECLS -__private_extern__ void dns_configuration_init (CFBundleRef bundle); #if !TARGET_OS_IPHONE -__private_extern__ void dns_configuration_monitor (SCDynamicStoreRef store, SCDynamicStoreCallBack callout); #endif // !TARGET_OS_IPHONE -__private_extern__ Boolean dns_configuration_set (CFDictionaryRef defaultResolver, CFDictionaryRef services, CFArrayRef serviceOrder, diff --git a/Plugins/IPMonitor/ip_plugin.c b/Plugins/IPMonitor/ip_plugin.c index cb683f4..328ceb9 100644 --- a/Plugins/IPMonitor/ip_plugin.c +++ b/Plugins/IPMonitor/ip_plugin.c @@ -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@ * @@ -88,15 +88,22 @@ #include #include #include +#include +#include #include #include #include +#include #include /* for SCLog() */ +#include "SCNetworkReachabilityInternal.h" +#include "SCNetworkSignaturePrivate.h" #include -#if !TARGET_OS_IPHONE -#include -#endif /* !TARGET_OS_IPHONE */ +#include "dnsinfo_server.h" + +#if defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS) +#include +#endif // !defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS) #include #ifndef kDNSServiceCompMulticastDNS @@ -107,6 +114,8 @@ #endif #include #include "network_information_priv.h" +#include "network_information_server.h" +#include enum { kProtocolFlagsNone = 0x0, @@ -130,19 +139,43 @@ enum { #define ROUTELIST_DEBUG(a, f) #endif +#if !TARGET_IPHONE_SIMULATOR #include "set-hostname.h" +#endif /* !TARGET_IPHONE_SIMULATOR */ + #include "dns-configuration.h" #include "proxy-configuration.h" + #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] +#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 */ @@ -153,6 +186,7 @@ enum { kRouteIsDirectToInterfaceFlag = 0x00000001, kRouteIsNotSubnetLocalFlag = 0x00000002, kRouteIsScopedFlag = 0x00000004, + kRouteIsNULLFlag = 0x00000008 }; typedef struct { @@ -169,6 +203,7 @@ typedef struct { typedef struct { int count; int size; + boolean_t exclude_from_nwi; IPv4Route list[1]; /* variable length */ } IPv4RouteList, *IPv4RouteListRef; @@ -177,27 +212,49 @@ enum { 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; - 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. * - * 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) @@ -241,6 +298,7 @@ static SCDynamicStoreRef S_session = NULL; /* 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; @@ -268,6 +326,10 @@ static CFStringRef S_primary_ipv6 = 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; @@ -279,18 +341,40 @@ static CFStringRef S_setup_service_prefix = NULL; static CFStringRef S_multicast_resolvers = NULL; static CFStringRef S_private_resolvers = NULL; +#if !TARGET_IPHONE_SIMULATOR 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 CFDictionaryRef S_dns_dict = NULL; + +static Boolean S_dnsinfo_synced = TRUE; + 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; +static CFDictionaryRef S_smb_dict = NULL; #endif /* !TARGET_OS_IPHONE */ #if !TARGET_OS_IPHONE @@ -314,6 +398,7 @@ enum { kEntityTypeSMB, #endif /* !TARGET_OS_IPHONE */ ENTITY_TYPES_COUNT, + kEntityTypeVPNStatus, kEntityTypeServiceOptions = 31 }; typedef uint32_t EntityType; @@ -328,13 +413,20 @@ static const CFStringRef *entityTypeNames[ENTITY_TYPES_COUNT] = { #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) @@ -346,7 +438,7 @@ ipv4_dict_get_routelist(CFDictionaryRef ipv4_dict) return (NULL); } - routes = CFDictionaryGetValue(ipv4_dict, kSCEntNetIPv4RouteList); + routes = CFDictionaryGetValue(ipv4_dict, kIPv4DictRoutes); 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, - kSCEntNetIPv4ServiceDict); + kIPv4DictService); if (isA_CFDictionary(ipv4_service_dict) == NULL) { return NULL; @@ -458,6 +550,14 @@ keyChangeListFree(keyChangeListRef keys) 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) { @@ -482,13 +582,11 @@ keyChangeListSetValue(keyChangeListRef keys, CFStringRef key, CFTypeRef value) } 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; - int status; if (CFArrayGetCount(notify) == 0) { notify = NULL; @@ -504,32 +602,87 @@ keyChangeListApplyToStore(keyChangeListRef keys, SCDynamicStoreRef session, } 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) { - SCLog(TRUE, LOG_NOTICE, CFSTR("IPMonitor: Removing:\n%@"), - remove); + my_log(LOG_DEBUG, "IPMonitor: Removing:\n%@", remove); } 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); - 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 = "); + 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; } @@ -547,6 +700,7 @@ S_is_network_boot() return (netboot); } +#if !TARGET_IPHONE_SIMULATOR 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 */ +#endif /* !TARGET_IPHONE_SIMULATOR */ #ifdef RTF_IFSCOPE static boolean_t @@ -597,7 +752,7 @@ S_is_scoped_routing_enabled() &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); } @@ -612,7 +767,7 @@ S_is_scoped_v6_routing_enabled() &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); } @@ -706,13 +861,15 @@ cfstring_to_ipvx(int family, CFStringRef str, void * addr, int addr_size) 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))); } -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))); @@ -838,14 +995,17 @@ IPv4RouteCopyDescriptionWithString(IPv4RouteRef r, CFMutableStringRef str) IP_LIST(&r->gateway), (r->ifname[0] != '\0') ? r->ifname : "", 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; @@ -857,10 +1017,10 @@ IPv4RouteCopyDescriptionWithString(IPv4RouteRef r, CFMutableStringRef str) break; default: break; - } - - if ((r->flags & kRouteIsScopedFlag) != 0) { - CFStringAppend(str, CFSTR(" [SCOPED]")); + } + if ((r->flags & kRouteIsScopedFlag) != 0) { + CFStringAppend(str, CFSTR(" [SCOPED]")); + } } return; } @@ -886,11 +1046,11 @@ IPv4RoutePrint(IPv4RouteRef route) } static __inline__ void -IPv4RouteLog(IPv4RouteRef route) +IPv4RouteLog(int level, IPv4RouteRef route) { CFStringRef str = IPv4RouteCopyDescription(route); - SCLog(TRUE, LOG_NOTICE, CFSTR("%@"), str); + my_log(level, "%@", str); CFRelease(str); return; } @@ -936,8 +1096,8 @@ IPv4RouteCompare(IPv4RouteRef a, Rank a_rank, } 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); } @@ -973,11 +1133,11 @@ IPv4RouteListPrint(IPv4RouteListRef routes) } static __inline__ void -IPv4RouteListLog(IPv4RouteListRef routes) +IPv4RouteListLog(int level, IPv4RouteListRef routes) { CFStringRef str = IPv4RouteListCopyDescription(routes); - SCLog(TRUE, LOG_NOTICE, CFSTR("%@"), str); + my_log(level, "%@", str); CFRelease(str); return; } @@ -988,6 +1148,7 @@ IPv4RouteListComputeSize(unsigned int n) return (offsetof(IPv4RouteList, list[n])); } +#if !TARGET_IPHONE_SIMULATOR static IPv4RouteRef IPv4RouteListFindRoute(IPv4RouteListRef routes, IPv4RouteRef route) { @@ -1054,6 +1215,7 @@ IPv4RouteListApply(IPv4RouteListRef old_routes, IPv4RouteListRef new_routes, } return; } +#endif /* !TARGET_IPHONE_SIMULATOR */ /* * Function: IPv4RouteListAddRoute @@ -1088,6 +1250,7 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size, if (routes == NULL) { routes = (IPv4RouteListRef)malloc(IPv4RouteListComputeSize(init_size)); + bzero(routes, sizeof(*routes)); routes->size = init_size; routes->count = 0; } @@ -1144,7 +1307,8 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size, 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; @@ -1208,6 +1372,9 @@ IPv4RouteListAddRoute(IPv4RouteListRef routes, int init_size, /* 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) { @@ -1284,6 +1451,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, CFStringRef primaryRank) { struct in_addr addr = { 0 }; + boolean_t exclude_from_nwi = FALSE; 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++; + } else if (router.s_addr == 0) { + exclude_from_nwi = TRUE; } } if (addr.s_addr == 0) { @@ -1331,8 +1501,19 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, 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; - rank = kRankAssertionLast; + if (primaryRank != NULL + && PrimaryRankGetRankAssertion(primaryRank) == kRankAssertionNever) { + rank = kRankAssertionNever; + } + else { + rank = kRankAssertionLast; + } } 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; } @@ -1370,6 +1556,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, } bzero(routes, IPv4RouteListComputeSize(n)); routes->count = n; + routes->exclude_from_nwi = exclude_from_nwi; /* start at the beginning */ r = routes->list; @@ -1387,14 +1574,14 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, r->gateway = addr; } r->rank = rank; - if (r->rank == kRankAssertionNever) { - r->flags |= kRouteIsScopedFlag; - } r++; } /* add the subnet route */ if (add_subnet) { + if ((flags & kRouteIsNULLFlag) != 0) { + r->flags |= kRouteIsNULLFlag; + } 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; - if (r->rank == kRankAssertionNever) { - r->flags |= kRouteIsScopedFlag; - } } - return (routes); } @@ -1467,8 +1650,8 @@ service_dict_copy(CFStringRef serviceID) } 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; @@ -1477,14 +1660,14 @@ dump_service_entity(CFStringRef serviceID, CFStringRef entity, 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)); } - service_dict = CFDictionaryGetValue(val, kSCEntNetIPv4ServiceDict); + service_dict = CFDictionaryGetValue(val, kIPv4DictService); 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(""); } - 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; } @@ -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) { - 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; @@ -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) { - 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; @@ -1576,7 +1759,7 @@ copy_dhcp_hostname(CFStringRef serviceID) } service_dict = - CFDictionaryGetValue(dict, kSCEntNetIPv4ServiceDict); + CFDictionaryGetValue(dict, kIPv4DictService); if (service_dict == NULL || isA_CFDictionary(service_dict) == NULL) { @@ -1593,8 +1776,9 @@ copy_dhcp_hostname(CFStringRef serviceID) 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; @@ -1626,15 +1810,16 @@ ipv6_service_dict_set(CFStringRef serviceID, CFDictionaryRef new_val) } 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); } - 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)) { @@ -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) { - syslog(LOG_ERR, + my_log(LOG_ERR, "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) { - syslog(LOG_NOTICE, + my_log(LOG_DEBUG, "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 */ - 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 */ @@ -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) { - syslog(LOG_ERR, + my_log(LOG_ERR, "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) { - syslog(LOG_NOTICE, + my_log(LOG_DEBUG, "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); - done: + done: #endif /* SIOCDRADD_IN6 */ - return (service_dict_set(serviceID, kSCEntNetIPv6, new_val)); + return; } +#endif /* !TARGET_IPHONE_SIMULATOR */ #define ALLOW_EMPTY_STRING 0x1 @@ -1863,19 +2050,19 @@ get_ipv4_changes(CFStringRef serviceID, CFDictionaryRef state_dict, } } 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]; - keys[0] = kSCEntNetIPv4ServiceDict; + keys[0] = kIPv4DictService; values[0] = dict; - keys[1] = kSCEntNetIPv4RouteList; + keys[1] = kIPv4DictRoutes; 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) { - 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; } @@ -1947,7 +2134,12 @@ get_ipv6_changes(CFStringRef serviceID, CFDictionaryRef state_dict, 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); @@ -1965,18 +2157,21 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos, 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; + 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) { - syslog(LOG_NOTICE, + my_log(LOG_DEBUG, "IPMonitor: no IPv4 connectivity, " - "ignoring DNS server address " IP_FORMAT, + "ignoring DNS server address ", IP_FORMAT, 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]; - syslog(LOG_NOTICE, + my_log(LOG_DEBUG, "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; } @@ -2015,9 +2210,9 @@ accumulate_dns_servers(CFArrayRef in_servers, ProtocolFlags active_protos, } 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; } @@ -2127,6 +2322,8 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict, kSCPropNetDNSSearchOrder, kSCPropNetDNSServerPort, kSCPropNetDNSServerTimeout, + kSCPropNetDNSServiceIdentifier, + kSCPropNetDNSSupplementalMatchDomainsNoSearch, }; IPv4RouteListRef routes = NULL; @@ -2216,7 +2413,7 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict, } 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 */ @@ -2224,6 +2421,18 @@ get_dns_changes(CFStringRef serviceID, CFDictionaryRef state_dict, 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; } @@ -2663,11 +2872,67 @@ services_info_get_interface(CFDictionaryRef services_info, 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; + CFBooleanRef ip_is_coupled = 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 */ - if (isA_CFDictionary(setup_options)) { - setup_rank = CFDictionaryGetValue(setup_options, kSCPropNetServicePrimaryRank); - setup_rank = isA_CFString(setup_rank); - } 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); + 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)) || @@ -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) { - SCLog(TRUE, LOG_NOTICE, - CFSTR("serviceID %@ interface %@ rank = %@"), - serviceID, interface, - (new_rank != NULL) ? new_rank : CFSTR("")); + my_log(LOG_DEBUG, + "serviceID %@ interface %@ rank = %@", + serviceID, interface, + (new_rank != NULL) ? new_rank : CFSTR("")); } } } - 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); - 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); @@ -2758,14 +3048,14 @@ if_rank_set(CFStringRef ifname, CFDictionaryRef rank_dict) /* 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) { - SCLog(TRUE, LOG_NOTICE, CFSTR("Interface %@ removed rank."), - ifname); + my_log(LOG_DEBUG, "Interface %@ removed rank", + ifname); } CFDictionaryRemoveValue(S_if_rank_dict, ifname); } @@ -2843,10 +3133,59 @@ add_service_keys(CFStringRef serviceID, CFMutableArrayRef keys, CFMutableArrayRe 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; } +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) @@ -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); + 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++) { @@ -2889,20 +3233,24 @@ services_info_copy(SCDynamicStoreRef session, CFArrayRef service_list, 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) { - 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); } +#endif /* !TARGET_IPHONE_SIMULATOR */ /* * Define: ROUTE_MSG_ADDRS_SPACE @@ -2919,6 +3267,7 @@ typedef struct { 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, @@ -2941,11 +3290,16 @@ ipv4_route(int sockfd, 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); } + 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; @@ -2966,7 +3320,7 @@ ipv4_route(int sockfd, } 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); @@ -3029,7 +3383,9 @@ ipv4_route(int sockfd, } 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) @@ -3110,9 +3466,9 @@ ipv6_route(int cmd, struct in6_addr gateway, struct in6_addr netaddr, } 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; } @@ -3126,7 +3482,7 @@ static boolean_t 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)); @@ -3139,17 +3495,19 @@ ipv6_default_route_add(struct in6_addr router, char * ifname, 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)); } +#endif /* !TARGET_IPHONE_SIMULATOR */ +#if !TARGET_IPHONE_SIMULATOR 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)); } +#endif /* !TARGET_IPHONE_SIMULATOR */ +#if !TARGET_IPHONE_SIMULATOR #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) { - 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) { - 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; @@ -3215,6 +3575,7 @@ set_ipv6_router(struct in6_addr * router, char * ifname, boolean_t is_direct) } return; } +#endif /* !TARGET_IPHONE_SIMULATOR */ #if !TARGET_OS_IPHONE static __inline__ void @@ -3296,6 +3657,7 @@ set_dns(CFArrayRef val_search_domains, } #endif /* !TARGET_OS_IPHONE */ +#if !TARGET_IPHONE_SIMULATOR 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); } +#endif /* !TARGET_IPHONE_SIMULATOR */ static IPv4RouteListRef service_dict_get_ipv4_routelist(CFDictionaryRef service_dict) { CFDictionaryRef dict; - IPv4RouteListRef routes = NULL; 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; @@ -3372,14 +3759,14 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg) 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) { - 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, @@ -3399,16 +3786,16 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg) 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) { - 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: @@ -3418,30 +3805,30 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg) 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) { - 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) { - 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) { - 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; @@ -3450,6 +3837,7 @@ apply_ipv4_route(IPv4RouteListApplyCommand cmd, IPv4RouteRef route, void * arg) } return; } +#endif /* !TARGET_IPHONE_SIMULATOR */ /* * Function: update_ipv4 @@ -3465,7 +3853,9 @@ update_ipv4(CFStringRef primary, IPv4RouteListRef new_routelist, keyChangeListRef keys) { +#if !TARGET_IPHONE_SIMULATOR apply_ipv4_route_context_t context; +#endif /* !TARGET_IPHONE_SIMULATOR */ 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) { - SCLog(TRUE, LOG_NOTICE, CFSTR("Old Routes = ")); + my_log(LOG_DEBUG, "Old Routes = "); } 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) { - SCLog(TRUE, LOG_NOTICE, CFSTR("New Routes = ")); + my_log(LOG_DEBUG, "New Routes = "); } 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; @@ -3550,64 +3941,75 @@ update_ipv4(CFStringRef primary, free(S_ipv4_routelist); } S_ipv4_routelist = new_routelist; +#endif /* !TARGET_IPHONE_SIMULATOR */ + return; } static void -update_ipv6(CFDictionaryRef services_info, - CFStringRef primary, +update_ipv6(CFStringRef primary, 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 !TARGET_IPHONE_SIMULATOR CFArrayRef addrs; +#endif /* !TARGET_IPHONE_SIMULATOR */ CFMutableDictionaryRef dict = NULL; CFStringRef if_name = NULL; +#if !TARGET_IPHONE_SIMULATOR 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); - val_router = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Router); + +#if !TARGET_IPHONE_SIMULATOR addrs = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Addresses); +#endif /* !TARGET_IPHONE_SIMULATOR */ + + val_router = CFDictionaryGetValue(ipv6_dict, kSCPropNetIPv6Router); 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); +#endif /* !TARGET_IPHONE_SIMULATOR */ + /* no router if router is one of our IP addresses */ CFDictionarySetValue(dict, kSCPropNetIPv6Router, val_router); } +#if !TARGET_IPHONE_SIMULATOR 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 !TARGET_IPHONE_SIMULATOR 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); +#if !TARGET_IPHONE_SIMULATOR #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); } +#endif /* !TARGET_IPHONE_SIMULATOR */ } else { keyChangeListRemoveValue(keys, S_state_global_ipv6); +#if !TARGET_IPHONE_SIMULATOR #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); } +#endif /* !TARGET_IPHONE_SIMULATOR */ } return; } -static void +static Boolean update_dns(CFDictionaryRef services_info, CFStringRef primary, keyChangeListRef keys) { - CFDictionaryRef dict = NULL; + Boolean changed = FALSE; + CFDictionaryRef dict = NULL; if (primary != NULL) { CFDictionaryRef service_dict; @@ -3649,33 +4055,41 @@ update_dns(CFDictionaryRef services_info, dict = CFDictionaryGetValue(service_dict, kSCEntNetDNS); } } - if (dict == NULL) { + + if (!_SC_CFEqual(S_dns_dict, dict)) { + if (dict == NULL) { #if !TARGET_OS_IPHONE - empty_dns(); + empty_dns(); #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 - 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 */ - 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, @@ -3706,15 +4120,42 @@ update_dnsinfo(CFDictionaryRef services_info, 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) { + Boolean changed = FALSE; 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, - 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 -static void +static Boolean update_smb(CFDictionaryRef services_info, CFStringRef primary, keyChangeListRef keys) { + Boolean changed = FALSE; CFDictionaryRef dict = NULL; if (primary != NULL) { @@ -3756,14 +4204,21 @@ update_smb(CFDictionaryRef services_info, 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 */ @@ -3830,371 +4285,930 @@ rank_dict_set_service_rank(CFMutableDictionaryRef rank_dict, 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// + */ + 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 -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; } } - 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; } -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 -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; } + 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 -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; } - 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; } - values_count = CFDictionaryGetCount(S_service_state_dict); - if (values_count == 0) { + if (CFEqual(if_name, CFSTR("lo0"))) { + /* don't ever elect loopback */ 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; } + /* - * Function: elect_new_primary + * Function: elect_ipv6 * 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 @@ -4224,6 +5238,11 @@ service_changed(CFDictionaryRef services_info, CFStringRef serviceID) changed |= (1 << i); } } + + if (get_transient_service_changes(serviceID, services_info)) { + changed |= (1 << kEntityTypeVPNStatus); + } + 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) { - 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) { - 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) { - 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; @@ -4305,13 +5324,6 @@ rank_service_entity(CFDictionaryRef rank_dict, CFStringRef 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) { @@ -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) { - 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); @@ -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) { - 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); @@ -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; @@ -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); - } else if (S_primary_dns != NULL){ + } else if (S_primary_dns != NULL) { CFStringAppendFormat(log_output, NULL, CFSTR(" DNS")); } @@ -4549,11 +5538,161 @@ generate_log_changes(nwi_state_t changes_state, 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; + uint32_t changes = 0; 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; - CFStringRef network_change_msg; + CFStringRef network_change_msg = 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; + boolean_t reachability_changed = FALSE; 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) { - 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) { @@ -4636,32 +5776,43 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys, #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])) { - status_changed = TRUE; 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)) { + int j; + 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); @@ -4684,8 +5835,8 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys, 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); } @@ -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) { - 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)) { - update_dns(services_info, serviceID, &keys); + dns_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)) { - update_smb(services_info, serviceID, &keys); + smb_changed = TRUE; } } -#endif /* !TARGET_OS_IPHONE */ +#endif } + if ((changes & (1 <count = 0; - list->size = size; - } + IPv4RouteListRef new_routelist = NULL; + /* IPv4 */ 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); } + 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")) { - update_dns(services_info, S_primary_dns, &keys); 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")) { - update_smb(services_info, S_primary_smb, &keys); 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_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) { - 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 - 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); - 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 - smb_changed, - old_primary_smb + smb_changed, + old_primary_smb #else // !TARGET_OS_IPHONE - FALSE, - NULL + FALSE, // smb_changed + NULL // old_primary_smb #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 + + 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) { @@ -4947,6 +6158,78 @@ IPMonitorNotify(SCDynamicStoreRef session, CFArrayRef changed_keys, 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() { @@ -4972,9 +6255,9 @@ ip_plugin_init() 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 @@ -5034,8 +6317,20 @@ ip_plugin_init() /* 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 */ - add_status_keys(patterns); + add_status_keys(kSCCompAnyRegex, patterns); /* 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)) { - 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) { - 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; } @@ -5092,6 +6387,7 @@ ip_plugin_init() #endif /* !TARGET_OS_IPHONE */ if_rank_dict_init(); + watch_proxies(); done: my_CFRelease(&keys); @@ -5129,6 +6425,7 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) CFDictionaryRef info_dict; info_dict = CFBundleGetInfoDictionary(bundle); + 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; - } + 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); + proxy_configuration_init(bundle); + ip_plugin_init(); #if !TARGET_OS_IPHONE @@ -5149,7 +6487,10 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) } #endif /* !TARGET_OS_IPHONE */ +#if !TARGET_IPHONE_SIMULATOR 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 */ @@ -5163,8 +6504,12 @@ load_IPMonitor(CFBundleRef bundle, Boolean bundleVerbose) #ifdef TEST_IPMONITOR + #include "dns-configuration.c" + +#if !TARGET_IPHONE_SIMULATOR #include "set-hostname.c" +#endif /* !TARGET_IPHONE_SIMULATOR */ int main(int argc, char **argv) @@ -5178,6 +6523,7 @@ main(int argc, char **argv) load_IPMonitor(CFBundleGetMainBundle(), FALSE); prime_IPMonitor(); + S_IPMonitor_debug = kDebugFlag1; CFRunLoopRun(); /* not reached */ exit(0); @@ -5186,8 +6532,12 @@ main(int argc, char **argv) #endif /* TEST_IPMONITOR */ #ifdef TEST_IPV4_ROUTELIST + #include "dns-configuration.c" + +#if !TARGET_IPHONE_SIMULATOR #include "set-hostname.c" +#endif /* !TARGET_IPHONE_SIMULATOR */ 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 }; +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, @@ -5407,6 +6761,11 @@ struct ipv4_service_contents * test14[] = { NULL }; +struct ipv4_service_contents * test15[] = { + &en0_linklocal, + NULL +}; + 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); - SCLog(TRUE, LOG_NOTICE, CFSTR("test: Adding %@"), descr); + SCPrint(TRUE, stdout, CFSTR("test: Adding %@\n"), 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); - SCLog(TRUE, LOG_NOTICE, CFSTR("Routes are %@"), descr); + SCPrint(TRUE, stdout, CFSTR("Routes are %@\n"), 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); - SCLog(TRUE, LOG_NOTICE, CFSTR("test: Adding %@"), descr); + SCPrint(TRUE, stdout, CFSTR("test: Adding %@\n"), descr); 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); - SCLog(TRUE, LOG_NOTICE, CFSTR("Routes are %@"), descr); + SCPrint(TRUE, stdout, CFSTR("Routes are %@\n"), descr); CFRelease(descr); } } @@ -5736,6 +7095,11 @@ main(int argc, char **argv) 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); diff --git a/Plugins/IPMonitor/ip_plugin.h b/Plugins/IPMonitor/ip_plugin.h new file mode 100644 index 0000000..ab52f1f --- /dev/null +++ b/Plugins/IPMonitor/ip_plugin.h @@ -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 + +#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 diff --git a/Plugins/IPMonitor/proxy-configuration.c b/Plugins/IPMonitor/proxy-configuration.c index 76d60fa..f8ac69c 100644 --- a/Plugins/IPMonitor/proxy-configuration.c +++ b/Plugins/IPMonitor/proxy-configuration.c @@ -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@ * @@ -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; @@ -332,11 +332,12 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_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) { - return NULL; // if no services + // if no services + return NULL; } // 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); - } else{ + } else { 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++) { - CFStringRef serviceID = (CFStringRef)keys[i]; + CFStringRef serviceID = (CFStringRef)keys[i]; 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); } + 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 + n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0; for (i = 0; i < n_order; i++) { + CFMutableDictionaryRef newProxy; 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; + CFDictionaryRef proxy; CFDictionaryRef service; CFStringRef serviceID; @@ -425,7 +509,6 @@ copy_scoped_proxies(CFDictionaryRef services, CFArrayRef service_order) CFRelease(interface); } - CFRelease(order); return scoped; } @@ -548,7 +631,8 @@ __private_extern__ CF_RETURNS_RETAINED CFDictionaryRef proxy_configuration_update(CFDictionaryRef defaultProxy, CFDictionaryRef services, - CFArrayRef serviceOrder) + CFArrayRef serviceOrder, + CFDictionaryRef servicesInfo) { CFIndex i; CFMutableDictionaryRef myDefault; @@ -618,8 +702,10 @@ proxy_configuration_update(CFDictionaryRef defaultProxy, // establish proxy configuration if (n_proxies > 0) { + CFDictionaryRef app_layer; CFDictionaryRef scoped; - Boolean skip = FALSE; + CFArrayRef serviceOrderAll; + Boolean skip = FALSE; CFArrayRef supplemental; proxy = CFArrayGetValueAtIndex(proxies, 0); @@ -636,6 +722,8 @@ proxy_configuration_update(CFDictionaryRef defaultProxy, &kCFTypeDictionaryValueCallBacks); } + serviceOrderAll = service_order_copy_all(services, serviceOrder); + // 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 - scoped = copy_scoped_proxies(services, serviceOrder); + scoped = copy_scoped_proxies(services, serviceOrderAll); 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; } @@ -866,7 +966,8 @@ main(int argc, char **argv) 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); diff --git a/Plugins/IPMonitor/proxy-configuration.h b/Plugins/IPMonitor/proxy-configuration.h index fbb233c..e86bd53 100644 --- a/Plugins/IPMonitor/proxy-configuration.h +++ b/Plugins/IPMonitor/proxy-configuration.h @@ -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@ * @@ -34,16 +34,15 @@ CFBooleanRef G_supplemental_proxies_follow_dns; __BEGIN_DECLS -__private_extern__ void proxy_configuration_init (CFBundleRef bundle); -__private_extern__ CF_RETURNS_RETAINED CFDictionaryRef proxy_configuration_update (CFDictionaryRef defaultProxy, CFDictionaryRef services, - CFArrayRef serviceOrder); + CFArrayRef serviceOrder, + CFDictionaryRef servicesInfo); __END_DECLS diff --git a/Plugins/IPMonitor/set-hostname.c b/Plugins/IPMonitor/set-hostname.c index 6ebcafd..b9ff913 100644 --- a/Plugins/IPMonitor/set-hostname.c +++ b/Plugins/IPMonitor/set-hostname.c @@ -40,6 +40,7 @@ #include #include +#include "ip_plugin.h" 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) { - SCLog(TRUE, LOG_ERR, CFSTR("gethostname() failed: %s"), strerror(errno)); + my_log(LOG_ERR, "gethostname() failed: %s", strerror(errno)); old_name[0] = '\0'; } @@ -71,7 +72,7 @@ set_hostname(CFStringRef hostname) 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'; } @@ -81,22 +82,22 @@ set_hostname(CFStringRef hostname) 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) { - 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 { - 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); - 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 @@ -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) { - 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; @@ -356,7 +358,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) /* * 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 @@ -365,8 +367,9 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) 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); + assert(localName != NULL); 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. - SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo_async_handleCFReply(): port != dnsPort")); + my_log(LOG_ERR, "getnameinfo_async_handleCFReply(): port != dnsPort"); 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) { - 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 */ - SCLog(TRUE, LOG_ERR, CFSTR("could not parse [primary] address")); + my_log(LOG_ERR, "could not parse [primary] address"); return; } @@ -543,7 +546,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) 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; } @@ -552,7 +555,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) 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; } @@ -568,7 +571,7 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) 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; } @@ -590,8 +593,9 @@ update_hostname(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) 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); + assert(localName != NULL); 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) { - SCLog(TRUE, LOG_ERR, - CFSTR("SCDynamicStoreCreate() failed: %s"), - SCErrorString(SCError())); + my_log(LOG_ERR, + "SCDynamicStoreCreate() failed: %s", + SCErrorString(SCError())); goto error; } @@ -673,17 +677,17 @@ load_hostname(Boolean verbose) /* 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) { - 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); diff --git a/Plugins/IPMonitor/set-hostname.h b/Plugins/IPMonitor/set-hostname.h index 3315cce..c8a686e 100644 --- a/Plugins/IPMonitor/set-hostname.h +++ b/Plugins/IPMonitor/set-hostname.h @@ -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@ * @@ -29,7 +29,6 @@ __BEGIN_DECLS -__private_extern__ void load_hostname (Boolean verbose); __END_DECLS diff --git a/Plugins/IPMonitor/smb-configuration.c b/Plugins/IPMonitor/smb-configuration.c index 8c06cd6..01027ee 100644 --- a/Plugins/IPMonitor/smb-configuration.c +++ b/Plugins/IPMonitor/smb-configuration.c @@ -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@ * @@ -51,6 +51,8 @@ #include #include // for SCLog(), SCPrint() +#include "ip_plugin.h" + #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) { - 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; } @@ -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) { - 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; } @@ -278,17 +280,17 @@ smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict) 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) { - 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; } @@ -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); - 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); } @@ -381,17 +384,19 @@ smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict) 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) { - 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; } } @@ -479,11 +484,13 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) (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); @@ -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)) { - SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (network configuration) = %@"), name); + my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name); goto set; } @@ -514,7 +521,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) 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); @@ -541,7 +548,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) /* * 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 @@ -550,7 +557,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) 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); @@ -566,7 +573,7 @@ reverseDNSComplete(int32_t status, char *host, char *serv, void *context) 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); @@ -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. - SCLog(TRUE, LOG_ERR, CFSTR("getnameinfo_async_handleCFReply(): port != dnsPort")); + my_log(LOG_ERR, "getnameinfo_async_handleCFReply(): port != dnsPort"); 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) { - 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 */ - SCLog(TRUE, LOG_ERR, CFSTR("could not parse [primary] address")); + my_log(LOG_ERR, "could not parse [primary] address"); 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)) { - SCLog(TRUE, LOG_INFO, CFSTR("NetBIOS name (network configuration) = %@"), name); + my_log(LOG_INFO, "NetBIOS name (network configuration) = %@", name); goto set; } @@ -763,7 +770,7 @@ smb_update_configuration(__unused CFRunLoopTimerRef _timer, void *info) 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); @@ -779,7 +786,7 @@ smb_update_configuration(__unused CFRunLoopTimerRef _timer, void *info) 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); @@ -867,9 +874,9 @@ load_smb_configuration(Boolean verbose) 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; } @@ -911,17 +918,17 @@ load_smb_configuration(Boolean verbose) /* 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) { - 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); diff --git a/Plugins/IPMonitor/smb-configuration.h b/Plugins/IPMonitor/smb-configuration.h index d1fdf3a..babfb1b 100644 --- a/Plugins/IPMonitor/smb-configuration.h +++ b/Plugins/IPMonitor/smb-configuration.h @@ -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@ * @@ -28,7 +28,6 @@ __BEGIN_DECLS -__private_extern__ void load_smb_configuration (Boolean verbose); __END_DECLS diff --git a/Plugins/IPMonitor/test_ipv4_routelist_filter.sh b/Plugins/IPMonitor/test_ipv4_routelist_filter.sh index 924de28..90cb275 100644 --- a/Plugins/IPMonitor/test_ipv4_routelist_filter.sh +++ b/Plugins/IPMonitor/test_ipv4_routelist_filter.sh @@ -1,2 +1,9 @@ #!/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/' diff --git a/Plugins/IPMonitor/test_ipv4_routelist_reference.txt b/Plugins/IPMonitor/test_ipv4_routelist_reference.txt index 410103d..aaadc62 100644 --- a/Plugins/IPMonitor/test_ipv4_routelist_reference.txt +++ b/Plugins/IPMonitor/test_ipv4_routelist_reference.txt @@ -4,37 +4,30 @@ test: Adding = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 @@ -95,32 +79,26 @@ test: Adding = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 @@ -176,27 +146,22 @@ test: Adding = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 @@ -247,27 +205,22 @@ test: Adding = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { 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 = { + 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 = { + 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 = { + 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 = { + 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: @@ -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 +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. diff --git a/Plugins/IPMonitor/test_reference.sh b/Plugins/IPMonitor/test_reference.sh index c4df41f..b21ea5e 100644 --- a/Plugins/IPMonitor/test_reference.sh +++ b/Plugins/IPMonitor/test_reference.sh @@ -11,7 +11,7 @@ cleanup() exit 1 } -trap cleanup 1 2 3 15 +trap cleanup 1 2 3 15 run_program() { @@ -84,4 +84,4 @@ else usage "${0}" fi -exit 0 \ No newline at end of file +exit 0 diff --git a/Plugins/InterfaceNamer/Info.plist b/Plugins/InterfaceNamer/Info.plist index bd0a960..7e483e3 100644 --- a/Plugins/InterfaceNamer/Info.plist +++ b/Plugins/InterfaceNamer/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 diff --git a/Plugins/InterfaceNamer/ifnamer.c b/Plugins/InterfaceNamer/ifnamer.c index 639f9ae..4ba2a56 100644 --- a/Plugins/InterfaceNamer/ifnamer.c +++ b/Plugins/InterfaceNamer/ifnamer.c @@ -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@ * @@ -63,14 +63,11 @@ #include #include #include -#include -#include #include #include #include #include #include -#include #include #include #include @@ -590,6 +587,40 @@ updateVirtualNetworkInterfaceConfiguration(SCPreferencesRef prefs, 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) { @@ -612,6 +643,11 @@ createInterfaceDict(SCNetworkInterfaceRef interface) 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); @@ -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); - CFRelease(known_info); - CFRelease(match_info); + if (known_info != NULL) CFRelease(known_info); + if (match_info != NULL) CFRelease(match_info); } return match; @@ -873,6 +909,83 @@ matchUnnamed(const void *value, void *context) 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 * @@ -908,8 +1021,8 @@ lookupMatchingInterface(SCNetworkInterfaceRef interface, 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)), @@ -917,8 +1030,8 @@ lookupMatchingInterface(SCNetworkInterfaceRef interface, &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; @@ -946,18 +1059,15 @@ lookupMatchingInterface(SCNetworkInterfaceRef interface, 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; } - close(sock); } } @@ -1013,6 +1123,11 @@ insertInterface(CFMutableArrayRef db_list, SCNetworkInterfaceRef interface) } CFArrayAppendValue(S_dblist, if_dict); + +#if !TARGET_OS_EMBEDDED + updateBTPANInformation(if_dict, NULL); +#endif // !TARGET_OS_EMBEDDED + CFRelease(if_dict); return; } @@ -1179,7 +1294,6 @@ copyInterfaceForIORegistryEntryID(uint64_t entryID) IOObjectRelease(iterator); } return (interface); - } static SCNetworkInterfaceRef @@ -1295,6 +1409,47 @@ displayInterface(SCNetworkInterfaceRef interface) 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) { @@ -1418,10 +1573,31 @@ nameInterfaces(CFMutableArrayRef if_list) 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); - } 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); @@ -1433,8 +1609,9 @@ nameInterfaces(CFMutableArrayRef if_list) 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)"), @@ -1563,6 +1740,73 @@ nameInterfaces(CFMutableArrayRef if_list) 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() { @@ -1592,6 +1836,19 @@ updateInterfaces() */ 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) { @@ -1961,6 +2218,7 @@ iterateRegistryBusy(io_iterator_t iterator, CFArrayRef nodes, CFMutableStringRef } else { newNodes = CFArrayCreateMutableCopy(NULL, 0, nodes); } + assert(newNodes != NULL); kr = IORegistryEntryGetName(obj, name); if (kr != kIOReturnSuccess) { @@ -2257,6 +2515,16 @@ setup_IOKit(CFBundleRef bundle) } #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: diff --git a/Plugins/KernelEventMonitor/Info.plist b/Plugins/KernelEventMonitor/Info.plist index dd41426..a138cb7 100644 --- a/Plugins/KernelEventMonitor/Info.plist +++ b/Plugins/KernelEventMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/KernelEventMonitor/ev_dlil.c b/Plugins/KernelEventMonitor/ev_dlil.c index 0830019..364fd6d 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.c +++ b/Plugins/KernelEventMonitor/ev_dlil.c @@ -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@ * @@ -189,6 +189,66 @@ done: #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) @@ -206,6 +266,7 @@ interface_detaching(const char *if_name) return; } + static void interface_remove(const char *if_name) { @@ -215,11 +276,17 @@ interface_remove(const char *if_name) 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); -#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; } @@ -269,7 +336,6 @@ link_update_status(const char *if_name, boolean_t attach) return; } - __private_extern__ void link_add(const char *if_name) diff --git a/Plugins/KernelEventMonitor/ev_dlil.h b/Plugins/KernelEventMonitor/ev_dlil.h index f78ce84..ae3b001 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.h +++ b/Plugins/KernelEventMonitor/ev_dlil.h @@ -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@ * @@ -34,22 +34,23 @@ __BEGIN_DECLS -__private_extern__ void interface_detaching (const char *if_name); -__private_extern__ 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); -__private_extern__ void link_add (const char *if_name); -__private_extern__ void link_remove (const char *if_name); -__private_extern__ void link_update_status (const char *if_name, boolean_t attach); __END_DECLS diff --git a/Plugins/KernelEventMonitor/ev_ipv4.h b/Plugins/KernelEventMonitor/ev_ipv4.h index 0e75b21..241d41f 100644 --- a/Plugins/KernelEventMonitor/ev_ipv4.h +++ b/Plugins/KernelEventMonitor/ev_ipv4.h @@ -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@ * @@ -37,16 +37,13 @@ __BEGIN_DECLS -__private_extern__ 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 -__private_extern__ void port_in_use_ipv4 (uint16_t port, pid_t req_pid); #endif /* !TARGET_OS_IPHONE */ diff --git a/Plugins/KernelEventMonitor/ev_ipv6.c b/Plugins/KernelEventMonitor/ev_ipv6.c index abe37ff..f30d3a7 100644 --- a/Plugins/KernelEventMonitor/ev_ipv6.c +++ b/Plugins/KernelEventMonitor/ev_ipv6.c @@ -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@ * @@ -344,7 +344,8 @@ interface_update_ipv6(struct ifaddrs *ifap, const char *if_name) 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. */ diff --git a/Plugins/KernelEventMonitor/ev_ipv6.h b/Plugins/KernelEventMonitor/ev_ipv6.h index 4cdd378..a009255 100644 --- a/Plugins/KernelEventMonitor/ev_ipv6.h +++ b/Plugins/KernelEventMonitor/ev_ipv6.h @@ -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@ * @@ -36,7 +36,6 @@ __BEGIN_DECLS -__private_extern__ void interface_update_ipv6 (struct ifaddrs *ifap, const char *if_name); __END_DECLS diff --git a/Plugins/KernelEventMonitor/eventmon.c b/Plugins/KernelEventMonitor/eventmon.c index c2cad27..231b763 100644 --- a/Plugins/KernelEventMonitor/eventmon.c +++ b/Plugins/KernelEventMonitor/eventmon.c @@ -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@ * @@ -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_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[] = { @@ -191,7 +203,7 @@ post_network_changed(void) 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); } @@ -260,6 +272,8 @@ copy_if_name(struct net_event_data * ev, char * ifr_name, int ifr_len) return; } +static uint8_t info_zero[DLIL_MODARGLEN]; + 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 +#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 : diff --git a/Plugins/KernelEventMonitor/eventmon.h b/Plugins/KernelEventMonitor/eventmon.h index af70ff1..9bce032 100644 --- a/Plugins/KernelEventMonitor/eventmon.h +++ b/Plugins/KernelEventMonitor/eventmon.h @@ -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@ * @@ -63,7 +63,6 @@ extern Boolean _verbose; __BEGIN_DECLS -__private_extern__ int dgram_socket (int domain); __END_DECLS diff --git a/Plugins/LinkConfiguration/Info.plist b/Plugins/LinkConfiguration/Info.plist index 788c103..ebb5b27 100644 --- a/Plugins/LinkConfiguration/Info.plist +++ b/Plugins/LinkConfiguration/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/LinkConfiguration/linkconfig.c b/Plugins/LinkConfiguration/linkconfig.c index 619bac4..aa11307 100644 --- a/Plugins/LinkConfiguration/linkconfig.c +++ b/Plugins/LinkConfiguration/linkconfig.c @@ -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@ * @@ -40,7 +40,6 @@ #include #include #include -#include #include // for _SCDPluginExecCommand #include "SCNetworkConfigurationInternal.h" @@ -785,7 +784,7 @@ main(int argc, char **argv) service = CFArrayGetValueAtIndex(services, i); interface = SCNetworkServiceGetInterface(service); if ((interface != NULL) && - !CFSetContainsValue(seen, interface)){ + !CFSetContainsValue(seen, interface)) { CFDictionaryRef capabilities; capabilities = SCNetworkInterfaceCopyCapability(interface, NULL); diff --git a/Plugins/Logger/Info-Embedded.plist b/Plugins/Logger/Info-Embedded.plist index 55b61a5..7963f2d 100644 --- a/Plugins/Logger/Info-Embedded.plist +++ b/Plugins/Logger/Info-Embedded.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Enabled Verbose diff --git a/Plugins/Logger/Info.plist b/Plugins/Logger/Info.plist index be89fde..3a86ea7 100644 --- a/Plugins/Logger/Info.plist +++ b/Plugins/Logger/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Enabled Verbose diff --git a/Plugins/Logger/logger.c b/Plugins/Logger/logger.c index 81b7c6e..ff5ea31 100644 --- a/Plugins/Logger/logger.c +++ b/Plugins/Logger/logger.c @@ -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@ * @@ -1259,7 +1259,7 @@ console_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *cont 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("?"), @@ -1512,8 +1512,6 @@ add_nwi_notification() #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) { @@ -1534,7 +1532,7 @@ add_network_notification() CFRunLoopSourceRef rls; uint32_t status; - status = notify_register_mach_port(NETWORKCHANGED_NOTIFY_KEY, + status = notify_register_mach_port(_SC_NOTIFY_NETWORK_CHANGE, ¬ify_port, 0, ¬ify_token); diff --git a/Plugins/PreferencesMonitor/Info.plist b/Plugins/PreferencesMonitor/Info.plist index 4648c9d..f7ba563 100644 --- a/Plugins/PreferencesMonitor/Info.plist +++ b/Plugins/PreferencesMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 Builtin Requires diff --git a/Plugins/PreferencesMonitor/prefsmon.c b/Plugins/PreferencesMonitor/prefsmon.c index 0200299..d11aa6d 100644 --- a/Plugins/PreferencesMonitor/prefsmon.c +++ b/Plugins/PreferencesMonitor/prefsmon.c @@ -135,7 +135,11 @@ establishNewPreferences() 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); } } @@ -144,7 +148,6 @@ establishNewPreferences() CFRelease(keys); } } - /* Set the new model */ SCPreferencesSetValue(prefs, MODEL, new_model); } @@ -299,6 +302,9 @@ watchQuietEnable() return; } + + + static void watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { diff --git a/Plugins/SCNetworkReachability/Info.plist b/Plugins/SCNetworkReachability/Info.plist index 6b407f5..e2077df 100644 --- a/Plugins/SCNetworkReachability/Info.plist +++ b/Plugins/SCNetworkReachability/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 diff --git a/Plugins/SimulatorSupport/Info.plist b/Plugins/SimulatorSupport/Info.plist new file mode 100644 index 0000000..72ccafd --- /dev/null +++ b/Plugins/SimulatorSupport/Info.plist @@ -0,0 +1,26 @@ + + + + + Builtin + + CFBundleDevelopmentRegion + English + CFBundleExecutable + SimulatorSupport + CFBundleIdentifier + com.apple.SystemConfiguration.SimulatorSupport + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + com.apple.SystemConfiguration.SimulatorSupport + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.13 + CFBundleSignature + ???? + CFBundleVersion + 1.13 + + diff --git a/Plugins/SimulatorSupport/simulator_support.c b/Plugins/SimulatorSupport/simulator_support.c new file mode 100644 index 0000000..529dcb8 --- /dev/null +++ b/Plugins/SimulatorSupport/simulator_support.c @@ -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 + * - initial revision + */ + + +#include +#include +#include + +#include +#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 index 0000000..c82153e --- /dev/null +++ b/Plugins/common/IPMonitorControlPrefs.c @@ -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 +#include +#include +#include +#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 index 0000000..e34d378 --- /dev/null +++ b/Plugins/common/IPMonitorControlPrefs.h @@ -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 +#include + +typedef void (*IPMonitorControlPrefsCallBack)(SCPreferencesRef prefs); + +SCPreferencesRef +IPMonitorControlPrefsInit(CFRunLoopRef runloop, + IPMonitorControlPrefsCallBack callback); + +Boolean +IPMonitorControlPrefsIsVerbose(void); + +Boolean +IPMonitorControlPrefsSetVerbose(Boolean verbose); + +#endif /* _COMMON_IPMONITORCONTROLPREFS_H */ diff --git a/SCMonitor/Info.plist b/SCMonitor/Info.plist index 22482f2..e930da3 100644 --- a/SCMonitor/Info.plist +++ b/SCMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 CFPlugInDynamicRegistration NO CFPlugInFactories diff --git a/SCMonitor/monitor.c b/SCMonitor/monitor.c index 27d67de..7f34e34 100644 --- a/SCMonitor/monitor.c +++ b/SCMonitor/monitor.c @@ -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 - * SCHelper write operations (kSCPreferencesWriteAuthorizationRight) + * SCHelper write operations (kSCPreferencesAuthorizationRight_write) * 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; - items[0].name = kSCPreferencesWriteAuthorizationRight; + items[0].name = kSCPreferencesAuthorizationRight_write; items[0].value = NULL; items[0].valueLength = 0; items[0].flags = 0; @@ -722,7 +722,7 @@ watcher_add_lan(MyType *myInstance) 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). @@ -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 - // "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). diff --git a/SystemConfiguration.fproj/BondConfiguration.c b/SystemConfiguration.fproj/BondConfiguration.c index 4b48910..d3c5960 100644 --- a/SystemConfiguration.fproj/BondConfiguration.c +++ b/SystemConfiguration.fproj/BondConfiguration.c @@ -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@ * @@ -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; } -#pragma mark - -#pragma mark SCBondInterface APIs - - CFArrayRef SCBondInterfaceCopyAll(SCPreferencesRef prefs) { @@ -373,20 +265,10 @@ SCBondInterfaceCopyAll(SCPreferencesRef prefs) kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeBond); dict = SCPreferencesPathGetValue(prefs, path); + CFRelease(path); 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; } @@ -563,6 +445,7 @@ _SCBondInterfaceCopyActive(void) // set the mode int_val = ibsr_p->ibsr_mode; mode = CFNumberCreate(NULL, kCFNumberIntType, &int_val); + assert(mode != NULL); _SCBondInterfaceSetMode(bond, mode); CFRelease(mode); @@ -595,7 +478,9 @@ _SCBondInterfaceCopyActive(void) done : - (void) close(s); + if (s != -1) { + (void) close(s); + } freeifaddrs(ifap); return bonds; } @@ -625,7 +510,7 @@ SCBondInterfaceCreate(SCPreferencesRef prefs) 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("/%@/%@/%@"), @@ -774,8 +659,9 @@ _SCBondInterfaceSetMemberInterfaces(SCBondInterfaceRef bond, CFArrayRef members) 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); } @@ -925,7 +811,9 @@ SCBondInterfaceSetLocalizedDisplayName(SCBondInterfaceRef bond, CFStringRef newN } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } @@ -987,7 +875,9 @@ SCBondInterfaceSetOptions(SCBondInterfaceRef bond, CFDictionaryRef newOptions) } else { CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBondOptions); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } @@ -1014,6 +904,8 @@ _SCBondInterfaceSetMode(SCBondInterfaceRef bond, CFNumberRef mode) Boolean needs_release = FALSE; Boolean ok = TRUE; + assert(bond != NULL); + 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); - - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } diff --git a/SystemConfiguration.fproj/BridgeConfiguration.c b/SystemConfiguration.fproj/BridgeConfiguration.c index 3124eb1..d291a3c 100644 --- a/SystemConfiguration.fproj/BridgeConfiguration.c +++ b/SystemConfiguration.fproj/BridgeConfiguration.c @@ -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@ * @@ -155,7 +155,7 @@ static void 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; @@ -164,10 +164,16 @@ add_configured_interface(const void *key, const void *value, void *context) 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); + 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); @@ -185,21 +191,24 @@ add_configured_interface(const void *key, const void *value, void *context) 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); + 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); @@ -212,6 +221,22 @@ add_configured_interface(const void *key, const void *value, void *context) #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) { @@ -229,7 +254,7 @@ SCBridgeInterfaceCopyAll(SCPreferencesRef prefs) kSCNetworkInterfaceTypeBridge); dict = SCPreferencesPathGetValue(prefs, path); if (isA_CFDictionary(dict)) { - CFDictionaryApplyFunction(dict, add_configured_interface, &context); + my_CFDictionaryApplyFunction(dict, add_configured_interface, &context); } CFRelease(path); @@ -378,6 +403,7 @@ _SCBridgeInterfaceCopyActive(void) 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 @@ -386,6 +412,18 @@ _SCBridgeInterfaceCopyActive(void) 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) { @@ -436,7 +474,9 @@ _SCBridgeInterfaceCopyActive(void) done : - (void) close(s); + if (s != -1) { + (void) close(s); + } freeifaddrs(ifap); return bridges; } @@ -466,7 +506,7 @@ SCBridgeInterfaceCreate(SCPreferencesRef prefs) 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("/%@/%@/%@"), @@ -615,8 +655,9 @@ _SCBridgeInterfaceSetMemberInterfaces(SCBridgeInterfaceRef bridge, CFArrayRef me 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); } @@ -766,7 +807,9 @@ SCBridgeInterfaceSetLocalizedDisplayName(SCBridgeInterfaceRef bridge, CFStringRe } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } @@ -828,7 +871,9 @@ SCBridgeInterfaceSetOptions(SCBridgeInterfaceRef bridge, CFDictionaryRef newOpti } else { CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesBridgeOptions); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } @@ -840,7 +885,23 @@ SCBridgeInterfaceSetOptions(SCBridgeInterfaceRef bridge, CFDictionaryRef newOpti interfacePrivate->bridge.options = NULL; } if (newOptions != NULL) { + CFStringRef name_auto = NULL; + 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); - 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_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; diff --git a/SystemConfiguration.fproj/CaptiveNetwork.c b/SystemConfiguration.fproj/CaptiveNetwork.c index f295bb6..94577fe 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.c +++ b/SystemConfiguration.fproj/CaptiveNetwork.c @@ -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@ * @@ -34,11 +34,11 @@ #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"); -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE static void * @@ -109,7 +109,7 @@ CNCopySupportedInterfaces(void) } -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE CFDictionaryRef CNCopyCurrentNetworkInfo(CFStringRef interfaceName) { @@ -120,4 +120,4 @@ CNCopyCurrentNetworkInfo(CFStringRef interfaceName) } return dyfunc ? dyfunc(interfaceName) : NULL; } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE diff --git a/SystemConfiguration.fproj/CaptiveNetwork.h b/SystemConfiguration.fproj/CaptiveNetwork.h index 12fd409..316c31b 100644 --- a/SystemConfiguration.fproj/CaptiveNetwork.h +++ b/SystemConfiguration.fproj/CaptiveNetwork.h @@ -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@ * @@ -106,8 +106,6 @@ CNMarkPortalOffline (CFStringRef interfaceName) __OSX_AVAILABLE_STARTING(__MAC_ 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 @@ -148,8 +146,6 @@ extern const CFStringRef kCNNetworkInfoKeyBSSID __OSX_AVAILABLE_STARTING(__MAC CFDictionaryRef CNCopyCurrentNetworkInfo (CFStringRef interfaceName) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); -#endif // TARGET_OS_EMBEDDED - __END_DECLS #endif /* _CAPTIVENETWORK_H */ diff --git a/SystemConfiguration.fproj/English.lproj/NetworkInterface.strings b/SystemConfiguration.fproj/English.lproj/NetworkInterface.strings index 2ea9adbd461f62b0138ef5fe896af55aabf9e37e..927ee05c3d43326cdda91f41184d66c6a82ec2ca 100644 GIT binary patch delta 152 zcmaE$JIQFn54Oo>Ok$HSG09B+z$hcA#9+<9#h}EH%TUUY!%)JIIe9OmI8asyC@VL4 z6Qc@m5C0}(cm tqRD(r0u$>vfJ}|aJVIQPcd+Vho+He}Jb8nV)?@==F6Kmrl*zqf!2sG>DsKP) delta 33 pcmbPa^gwsR54Ooh5_*#Zn7Jmu;uP5&!;!?Zd4lKCFBundleExecutable SystemConfiguration CFBundleGetInfoString - 1.12.2 + 1.13 CFBundleIdentifier com.apple.SystemConfiguration CFBundleInfoDictionaryVersion @@ -17,10 +17,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 diff --git a/SystemConfiguration.fproj/Info.plist b/SystemConfiguration.fproj/Info.plist index 87f9a94..9f9b512 100644 --- a/SystemConfiguration.fproj/Info.plist +++ b/SystemConfiguration.fproj/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable SystemConfiguration CFBundleGetInfoString - 1.12.2 + 1.13 CFBundleIdentifier com.apple.SystemConfiguration CFBundleInfoDictionaryVersion @@ -17,10 +17,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.12.2 + 1.13 CFBundleSignature ???? CFBundleVersion - 1.12.2 + 1.13 diff --git a/SystemConfiguration.fproj/LinkConfiguration.c b/SystemConfiguration.fproj/LinkConfiguration.c index 85249b0..f75743f 100644 --- a/SystemConfiguration.fproj/LinkConfiguration.c +++ b/SystemConfiguration.fproj/LinkConfiguration.c @@ -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@ * @@ -121,7 +121,15 @@ __getCapabilities(CFStringRef interfaceName, 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; } @@ -867,6 +875,15 @@ _SCNetworkInterfaceIsPhysicalEthernet(SCNetworkInterfaceRef interface) 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); @@ -1235,71 +1252,3 @@ SCNetworkInterfaceSetMTU(SCNetworkInterfaceRef interface, 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 index 6a6c53f..0000000 --- a/SystemConfiguration.fproj/LinkConfiguration.h +++ /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 -#include -#include - -/*! - @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. , - ). 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 */ - diff --git a/SystemConfiguration.fproj/SCD.c b/SystemConfiguration.fproj/SCD.c index 43a2101..d6b8710 100644 --- a/SystemConfiguration.fproj/SCD.c +++ b/SystemConfiguration.fproj/SCD.c @@ -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@ * @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include @@ -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, - 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 - @@ -87,7 +89,6 @@ __SCThreadSpecificDataRef __SCGetThreadSpecificData() { __SCThreadSpecificDataRef tsd; - pthread_once(&tsKeyInitialized, __SCThreadSpecificKeyInitialize); tsd = pthread_getspecific(tsDataKey); @@ -107,6 +108,10 @@ __SCGetThreadSpecificData() #pragma mark Logging +#define kASLModule "ASLModule" +#define kASLOption "ASLOption" +#define kLoggerID "LoggerID" + #define ENABLE_SC_FORMATTING #ifdef ENABLE_SC_FORMATTING // from @@ -178,26 +183,26 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) 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; } - if (!formatOptions || + if ((formatOptions == NULL) || !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) { prefix2 = prefix1; } - if (formatOptions) { + if (formatOptions != NULL) { nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions); } else { nFormatOptions = CFDictionaryCreateMutable(NULL, @@ -205,6 +210,7 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } + assert(nFormatOptions != NULL); #define N_QUICK 32 @@ -229,7 +235,7 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) CFStringRef nStr; CFStringRef vStr; - nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%u"), i); + nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), i); nPrefix1 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix1, @@ -355,7 +361,6 @@ _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - 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(®isterLoggerOnce, __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 @@ -618,6 +1049,7 @@ static const struct sc_errmsg { 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" }, @@ -639,7 +1071,6 @@ static const struct sc_errmsg { }; #define nSC_ERRMSGS (sizeof(sc_errmsgs)/sizeof(struct sc_errmsg)) - void _SCErrorSet(int error) { @@ -689,7 +1120,7 @@ SCCopyLastError(void) domain = kCFErrorDomainMach; - done : + done : error = CFErrorCreate(NULL, domain, code, userInfo); if (userInfo != NULL) CFRelease(userInfo); diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c index 2652bc4..02e7d48 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c @@ -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@ * @@ -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) { @@ -200,10 +190,9 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) __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); @@ -278,13 +267,20 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) } if (storePrivate->rlsNotifyPort != NULL) { - /* invalidate port */ + mach_port_t mp; + + mp = CFMachPortGetPort(storePrivate->rlsNotifyPort); __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; + + /* 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) { @@ -343,8 +339,10 @@ rlsPerform(void *info) 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); } diff --git a/SystemConfiguration.fproj/SCDOpen.c b/SystemConfiguration.fproj/SCDOpen.c index c8090bb..abe9727 100644 --- a/SystemConfiguration.fproj/SCDOpen.c +++ b/SystemConfiguration.fproj/SCDOpen.c @@ -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@ * @@ -73,7 +73,7 @@ __SCDynamicStoreCopyDescription(CFTypeRef cf) { result = CFStringCreateMutable(allocator, 0); CFStringAppendFormat(result, NULL, CFSTR(" {"), 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")); } @@ -236,25 +236,27 @@ __SCDynamicStoreInitialize(void) 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"); - if (!server_name) { + + + if (server_name == NULL) { 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); -#else // BOOTSTRAP_PRIVILEGED_SERVER +#else // defined(BOOTSTRAP_PRIVILEGED_SERVER) && !TARGET_IPHONE_SIMULATOR *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 : @@ -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) { @@ -390,6 +417,11 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) /* 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) { @@ -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 @@ -495,6 +512,7 @@ __SCDynamicStoreNullSession(void) CFSTR("NULL session"), NULL, NULL); + assert(storePrivate != NULL); storePrivate->server = _sc_server; storePrivate->serverNullSession = TRUE; #else @@ -508,6 +526,7 @@ __SCDynamicStoreNullSession(void) CFSTR("Thread local session"), NULL, NULL); + assert(storePrivate != NULL); /* * 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 */ + SCDynamicStoreRef SCDynamicStoreCreateWithOptions(CFAllocatorRef allocator, CFStringRef name, @@ -756,7 +776,10 @@ SCDynamicStoreCreateWithOptions(CFAllocatorRef allocator, } // set "options" - storePrivate->options = (storeOptions != NULL) ? CFRetain(storeOptions) : NULL; + + if (storeOptions != NULL) { + storePrivate->options = CFRetain(storeOptions); + } // establish SCDynamicStore session ok = __SCDynamicStoreAddSession(storePrivate); diff --git a/SystemConfiguration.fproj/SCDPlugin.c b/SystemConfiguration.fproj/SCDPlugin.c index 8431f3c..926500f 100644 --- a/SystemConfiguration.fproj/SCDPlugin.c +++ b/SystemConfiguration.fproj/SCDPlugin.c @@ -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@ * @@ -278,11 +278,22 @@ _SCDPluginExecCommand2(SCDPluginExecCallBack callout, 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); + // 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(); @@ -325,15 +336,8 @@ _SCDPluginExecCommand2(SCDPluginExecCallBack callout, (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) { diff --git a/SystemConfiguration.fproj/SCDPrivate.c b/SystemConfiguration.fproj/SCDPrivate.c index 0f3e346..5610bb7 100644 --- a/SystemConfiguration.fproj/SCDPrivate.c +++ b/SystemConfiguration.fproj/SCDPrivate.c @@ -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@ * @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -56,9 +57,9 @@ #include -#if TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM) +#if TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM) #include -#endif // TARGET_OS_EMBEDDED && !TARGET_OS_EMBEDDED_OTHER && !defined(DO_NOT_INFORM) +#endif // TARGET_OS_EMBEDDED && !defined(DO_NOT_INFORM) #define N_QUICK 32 @@ -161,15 +162,6 @@ _SC_sockaddr_to_string(const struct sockaddr *address, char *buf, size_t bufLen) } 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; @@ -542,6 +534,7 @@ _SCUnserializeData(CFDataRef *data, void *dataRef, CFIndex dataLen) CF_RETURNS_RETAINED CFDictionaryRef _SCSerializeMultiple(CFDictionaryRef dict) { + CFIndex i; 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) { - CFIndex i; - 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++) { + pLists[i] = NULL; if (!_SCSerialize((CFPropertyListRef)values[i], (CFDataRef *)&pLists[i], NULL, NULL)) { goto done; } @@ -580,10 +572,8 @@ _SCSerializeMultiple(CFDictionaryRef dict) done : if (nElements > 0) { - CFIndex 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) { @@ -892,6 +882,7 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString { CFDataRef data = NULL; SInt32 errCode = 0; + Boolean ok; CFURLRef resourcesURL; CFStringRef str = NULL; CFURLRef url; @@ -921,12 +912,16 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString CFRelease(fileName); CFRelease(resourcesURL); - if (!CFURLCreateDataAndPropertiesFromResource(NULL, +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" + ok = CFURLCreateDataAndPropertiesFromResource(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 @@ -944,12 +939,16 @@ _SC_CFBundleCopyNonLocalizedString(CFBundleRef bundle, CFStringRef key, CFString 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, - &errCode)) { + &errCode); +#pragma GCC diagnostic pop + if (!ok) { data = NULL; } CFRelease(url); @@ -1018,7 +1017,8 @@ _SC_CFMachPortCreateWithPort(const char *portDescription, portDescription); } crash_info = _SC_cfstring_to_cstring(err, NULL, 0, kCFStringEncodingASCII); - CFRelease(err); + if (err != NULL) CFRelease(err); + 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) { - 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 @@ -1359,11 +1359,11 @@ asm(".desc ___crashreporter_info__, 0x10"); 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; - static void *image = NULL; + static void *image = NULL; 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); } -#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) { - 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, - notifyMessage, + displayMessage, NULL); - CFRelease(notifyMessage); + CFRelease(displayMessage); 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; @@ -1447,3 +1449,41 @@ _SC_crash(const char *crash_info, CFStringRef notifyHeader, CFStringRef notifyMe __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; +} diff --git a/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h b/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h index 7682d42..66148ea 100644 --- a/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h +++ b/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h @@ -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@ * @@ -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). - + 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 diff --git a/SystemConfiguration.fproj/SCDynamicStoreInternal.h b/SystemConfiguration.fproj/SCDynamicStoreInternal.h index a32aa7f..b81fbfc 100644 --- a/SystemConfiguration.fproj/SCDynamicStoreInternal.h +++ b/SystemConfiguration.fproj/SCDynamicStoreInternal.h @@ -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@ * diff --git a/SystemConfiguration.fproj/SCDynamicStorePrivate.h b/SystemConfiguration.fproj/SCDynamicStorePrivate.h index af5a5cc..40acd63 100644 --- a/SystemConfiguration.fproj/SCDynamicStorePrivate.h +++ b/SystemConfiguration.fproj/SCDynamicStorePrivate.h @@ -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@ * @@ -109,6 +109,7 @@ typedef void (*SCDynamicStoreDisconnectCallBack) ( ); + __BEGIN_DECLS /*! diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c index 2342887..b90bb1a 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c @@ -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@ * @@ -72,6 +72,7 @@ __setPrefsConfiguration(SCPreferencesRef prefs, CFDictionaryRef config, Boolean keepInactive) { + CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok; @@ -80,13 +81,13 @@ __setPrefsConfiguration(SCPreferencesRef prefs, return FALSE; } + curConfig = SCPreferencesPathGetValue(prefs, path); + if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } if (keepInactive) { - CFDictionaryRef curConfig; - if (config == NULL) { newConfig = CFDictionaryCreateMutable(NULL, 0, @@ -94,7 +95,6 @@ __setPrefsConfiguration(SCPreferencesRef prefs, &kCFTypeDictionaryValueCallBacks); } - curConfig = SCPreferencesPathGetValue(prefs, path); if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { // if currently disabled CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); @@ -105,7 +105,11 @@ __setPrefsConfiguration(SCPreferencesRef prefs, } // 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); @@ -168,7 +172,11 @@ __setPrefsEnabled(SCPreferencesRef prefs, } // 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); @@ -203,7 +211,10 @@ __copyTemplates() return NULL; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL); +#pragma GCC diagnostic pop CFRelease(url); if (!ok || (xmlTemplates == NULL)) { return NULL; diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h index ba253f0..3075883 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h @@ -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@ * @@ -73,6 +73,9 @@ typedef struct { // name CFStringRef name; + // external identifiers + CFMutableDictionaryRef externalIDs; + } SCNetworkServicePrivate, *SCNetworkServicePrivateRef; @@ -143,6 +146,7 @@ typedef struct { uint64_t entryID; CFMutableDictionaryRef overrides; Boolean modemIsV92; + CFStringRef prefix; CFNumberRef type; CFNumberRef unit; struct { @@ -158,8 +162,8 @@ typedef struct { Boolean supportsBond; struct { CFArrayRef interfaces; - CFDictionaryRef options; CFNumberRef mode; + CFDictionaryRef options; } bond; // for Bridge interfaces @@ -221,13 +225,13 @@ CFArrayRef __SCNetworkInterfaceCopyDeepConfiguration (SCNetworkSetRef set, SCNetworkInterfaceRef interface); -#if !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_IPHONE CFStringRef __SCNetworkInterfaceCopyXLocalizedDisplayName (SCNetworkInterfaceRef interface); CFStringRef __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface); -#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR +#endif // !TARGET_OS_IPHONE int __SCNetworkInterfaceCreateCapabilities (SCNetworkInterfaceRef interface, diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h index fb1987b..ddc8ba7 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h @@ -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@ * @@ -192,6 +192,14 @@ _SCNetworkInterfaceCopyActive (SCDynamicStoreRef store, 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. @@ -311,6 +319,16 @@ _SCNetworkInterfaceGetConfigurationAction (SCNetworkInterfaceRef interface) __ 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. @@ -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; - 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); @@ -415,6 +433,15 @@ _SCNetworkInterfaceIsModemV92 (SCNetworkInterfaceRef interface) __OSX_AVAILA 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. @@ -779,6 +806,30 @@ SCNetworkServiceSetPrimaryRank (SCNetworkServiceRef service, 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) @@ -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 @@ -861,5 +923,85 @@ Boolean 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: +
kSCValNetVPNAppRuleExecutableMatch
+
kSCValNetVPNAppRuleAccountIdentifierMatch
+ The ruleSettings dictionary may also contain the following keys: +
kSCValNetVPNAppRuleDNSDomainMatch
+ 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 */ diff --git a/SystemConfiguration.fproj/SCNetworkConnection.c b/SystemConfiguration.fproj/SCNetworkConnection.c index e54ea07..067c14e 100644 --- a/SystemConfiguration.fproj/SCNetworkConnection.c +++ b/SystemConfiguration.fproj/SCNetworkConnection.c @@ -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@ * @@ -44,6 +44,8 @@ #include #include #include +#include +#include #if !TARGET_OS_IPHONE #include @@ -64,17 +66,25 @@ #include #include #include +#include +#include #include #include "pppcontroller.h" #include +#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 char *scnc_server_name = NULL; typedef struct { @@ -90,9 +100,13 @@ typedef struct { /* 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; + uuid_t client_uuid; + CFStringRef client_bundle_id; /* 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; + 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; @@ -136,7 +158,7 @@ __SCNetworkConnectionCopyDescription(CFTypeRef cf) CFStringAppendFormat(result, NULL, CFSTR(" {"), 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("}")); @@ -159,6 +181,17 @@ __SCNetworkConnectionDeallocate(CFTypeRef cf) -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); @@ -185,7 +218,25 @@ __SCNetworkConnectionDeallocate(CFTypeRef cf) 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; } @@ -212,6 +263,7 @@ childForkHandler() /* the process has forked (and we are the child process) */ scnc_server = MACH_PORT_NULL; + scnc_server_name = NULL; return; } @@ -243,18 +295,84 @@ __SCNetworkConnectionInitialize(void) 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; - + boolean_t exec_async = FALSE; 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; + dispatch_queue_t q = NULL; 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 - goto doit; + pthread_mutex_unlock(&connectionPrivate->lock); + return; } rlsFunction = connectionPrivate->rlsFunction; if (rlsFunction == NULL) { - goto doit; + pthread_mutex_unlock(&connectionPrivate->lock); + return; } if ((connectionPrivate->rlsContext.retain != NULL) && (connectionPrivate->rlsContext.info != NULL)) { @@ -283,18 +403,54 @@ __SCNetworkConnectionCallBack(CFMachPortRef port, void * msg, CFIndex size, void 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); - 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; } - 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; @@ -345,12 +501,17 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef allocator, 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_bootstrap_port = MACH_PORT_NULL; connectionPrivate->client_uid = geteuid(); connectionPrivate->client_gid = getegid(); connectionPrivate->client_pid = getpid(); + connectionPrivate->client_bundle_id = NULL; + uuid_clear(connectionPrivate->client_uuid); connectionPrivate->rlsFunction = callout; @@ -361,6 +522,8 @@ __SCNetworkConnectionCreatePrivate(CFAllocatorRef allocator, } } + connectionPrivate->type = kSCNetworkConnectionTypeUnknown; + /* 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, - PPPCONTROLLER_SERVER, + __SCNetworkConnectionGetControllerPortName(), &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) { @@ -410,11 +573,41 @@ __SCNetworkConnectionServerPort(kern_return_t *status) break; } + scnc_server_name = NULL; /* reset pppcontroller server */ 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 @@ -423,7 +616,6 @@ __SCNetworkConnectionServerPort(kern_return_t *status) #define HAVE_PPPCONTROLLER_ATTACHWITHPROXY #endif - 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 server = scnc_server; + mach_port_t server = __SCNetworkConnectionGetCurrentServerPort(); kern_return_t status = KERN_SUCCESS; #ifdef HAVE_PPPCONTROLLER_ATTACHWITHAUDITSESSION @@ -445,6 +637,11 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate return connectionPrivate->session_port; } + if (connectionPrivate->service == NULL) { + sc_status = kSCStatusConnectionNoService; + 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) && + (connectionPrivate->client_bootstrap_port == MACH_PORT_NULL) && (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; + mach_port_t client_bootstrap_port; 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; } + 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, - bootstrap_port, + client_bootstrap_port, 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) { @@ -665,7 +856,7 @@ __SCNetworkConnectionSessionPort(SCNetworkConnectionPrivateRef connectionPrivate // 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 @@ -731,17 +922,6 @@ __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection) 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) { @@ -758,6 +938,19 @@ __SCNetworkConnectionReconnectNotifications(SCNetworkConnectionRef connection) 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); @@ -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) { @@ -971,6 +1174,11 @@ SCNetworkConnectionCopyServiceID(SCNetworkConnectionRef connection) return NULL; } + if (connectionPrivate->service == NULL) { + _SCErrorSet(kSCStatusConnectionNoService); + return NULL; + } + serviceID = SCNetworkServiceGetServiceID(connectionPrivate->service); return CFRetain(serviceID); } @@ -990,7 +1198,7 @@ SCNetworkConnectionSetClientInfo(SCNetworkConnectionRef connection, 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, @@ -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) { @@ -1095,12 +1369,25 @@ SCNetworkConnectionGetStatus(SCNetworkConnectionRef connection) int sc_status = kSCStatusFailed; mach_port_t session_port; kern_return_t status; + CFStringRef serviceID; 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 : @@ -1152,12 +1439,25 @@ SCNetworkConnectionCopyExtendedStatus(SCNetworkConnectionRef connection) int sc_status = kSCStatusFailed; mach_port_t session_port; kern_return_t status; + CFStringRef serviceID; 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 : @@ -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, @@ -1233,6 +1541,21 @@ SCNetworkConnectionStart(SCNetworkConnectionRef connection, 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; @@ -1293,6 +1616,12 @@ SCNetworkConnectionStart(SCNetworkConnectionRef connection, 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); @@ -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) { @@ -1615,6 +2019,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef connection, } if (queue != NULL) { + dispatch_group_t group = NULL; 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. // - 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); @@ -1674,7 +2080,8 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef connection, CFRetain(connection); notify_port = dispatch_get_context(source); - dispatch_group_async(connectionPrivate->dispatchGroup, connectionPrivate->dispatchQueue, ^{ + + dispatch_group_async(group, queue, ^{ __SCNetworkConnectionCallBack(notify_port, (void *)¬ify_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 -_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; + if (CFEqual(match_domain, WILD_CARD_MATCH_STR)) { + return TRUE; + } + 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 */ -Boolean -__SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef *storeP, - CFStringRef hostName, - Boolean onDemandRetry, - CFStringRef *connectionServiceID, - SCNetworkConnectionStatus *connectionStatus, - CFStringRef *vpnRemoteAddress) /* CFDictionaryRef *info */ +static CFDictionaryRef +__SCNetworkConnectionCopyOnDemandConfiguration(void) { int changed = 1; - CFDictionaryRef configuration; - Boolean ok = FALSE; int status; - SCDynamicStoreRef store = *storeP; - CFArrayRef triggers; uint64_t triggersCount = 0; - int triggersIndex; + CFDictionaryRef configuration; pthread_mutex_lock(&onDemand_notify_lock); if (onDemand_notify_token == -1) { @@ -1989,6 +2793,7 @@ __SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef *storeP, onDemand_notify_token = -1; } } + 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)) { @@ -2021,179 +2826,765 @@ __SCNetworkConnectionCopyOnDemandInfoWithName(SCDynamicStoreRef *storeP, 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); - 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; } } + + onDemand_force_refresh = FALSE; } 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; + 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, ¶ms_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, ¬ify_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; } - 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; } - 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) { - int prefsChanged = 1; - SCDynamicStoreRef session = NULL; - Boolean success = FALSE; - int status; + Boolean success = FALSE; /* initialize runtime */ @@ -2218,14 +3606,14 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef selectionOptions, 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; - success = __SCNetworkConnectionCopyOnDemandInfoWithName(&session, + success = __SCNetworkConnectionCopyOnDemandInfoWithName(NULL, hostName, onDemandRetry, &connectionServiceID, @@ -2240,9 +3628,6 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef selectionOptions, 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) { @@ -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 - // being retried after the VPN has been established) than we're + // being retried after the VPN has been established) then we're // done - if (session != NULL) { - CFRelease(session); - } return FALSE; } } } - if (notify_userprefs_token == -1) { - status = notify_register_check(k_NetworkConnect_Notification, ¬ify_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; isin_addr.s_addr & mask.s_addr) == (routeAddr.s_addr & mask.s_addr)) { + return TRUE; + } + maskDataArray++; } 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; isin6_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; } - 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 { - 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; } - //******************************************************************************************* // SCNetworkConnectionPrivateCopyDefaultServiceIDForDial // ---------------------------------------------------- @@ -2493,7 +4226,7 @@ SCNetworkConnectionCopyUserPreferences(CFDictionaryRef selectionOptions, // with the highest ordering //******************************************************************************************** static Boolean -SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, CFStringRef *serviceID) +SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(CFStringRef *serviceID) { 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 - if (SCNetworkConnectionPrivateIsPPPService(session, lastServiceSelectedInIC, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) { + if (SCNetworkConnectionPrivateIsPPPService(lastServiceSelectedInIC, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) { // make sure the service that we found is valid CFDictionaryRef dict; CFStringRef key; @@ -2512,7 +4245,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, kSCDynamicStoreDomainSetup, lastServiceSelectedInIC, kSCEntNetInterface); - dict = SCDynamicStoreCopyValue(session, key); + dict = SCDynamicStoreCopyValue(NULL, key); CFRelease(key); if (dict != NULL) { CFRelease(dict); @@ -2524,7 +4257,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, } if (!foundService) { - foundService = SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(session, serviceID); + foundService = SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(serviceID); } return foundService; @@ -2536,7 +4269,7 @@ SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, // 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; @@ -2555,7 +4288,7 @@ SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(SCDynamicStoreRef sessio break; } - dict = SCDynamicStoreCopyValue(session, key); + dict = SCDynamicStoreCopyValue(NULL, key); 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); - if (SCNetworkConnectionPrivateIsPPPService(session, service, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) { + if (SCNetworkConnectionPrivateIsPPPService(service, kSCValNetInterfaceSubTypePPPSerial, kSCValNetInterfaceSubTypePPPoE)) { *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 -SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2) +SCNetworkConnectionPrivateIsPPPService(CFStringRef serviceID, CFStringRef subType1, CFStringRef subType2) { CFStringRef entityKey; Boolean isPPPService = FALSE; @@ -2640,7 +4373,7 @@ SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef se return FALSE; } - serviceDict = SCDynamicStoreCopyValue(session, entityKey); + serviceDict = SCDynamicStoreCopyValue(NULL, entityKey); 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 -addPasswordFromKeychain(SCDynamicStoreRef session, CFStringRef serviceID, CFDictionaryRef *userOptions) +addPasswordFromKeychain(CFStringRef serviceID, CFDictionaryRef *userOptions) { 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 */ - if (SCNetworkConnectionPrivateIsPPPService(session, serviceID, kSCValNetInterfaceSubTypeL2TP, 0)) { + if (SCNetworkConnectionPrivateIsPPPService(serviceID, kSCValNetInterfaceSubTypeL2TP, 0)) { CFMutableStringRef uniqueIDSS; uniqueIDSS = CFStringCreateMutableCopy(NULL, 0, uniqueID); @@ -2839,3 +4572,25 @@ copyPasswordFromKeychain(CFStringRef uniqueID) 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/dnsinfo/shared_dns_info_types.h b/SystemConfiguration.fproj/SCNetworkConnectionInternal.h similarity index 55% rename from dnsinfo/shared_dns_info_types.h rename to SystemConfiguration.fproj/SCNetworkConnectionInternal.h index 780cf77..9bef13b 100644 --- a/dnsinfo/shared_dns_info_types.h +++ b/SystemConfiguration.fproj/SCNetworkConnectionInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007 Apple Inc. All rights reserved. + * Copyright (c) 2012, 2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,37 +21,18 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifndef _SHARED_DNS_INFO_TYPES_H -#define _SHARED_DNS_INFO_TYPES_H +#ifndef _SCNETWORKCONNECTIONINTERNAL_H +#define _SCNETWORKCONNECTIONINTERNAL_H -/* - * Keep IPC functions private to the framework - */ -#ifdef mig_external -#undef mig_external -#endif -#define mig_external __private_extern__ +#include -/* 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" +__BEGIN_DECLS -/* - * Input arguments: DNS configuration - * (sent as out-of-line data in a message) - */ -typedef const char * dnsData_t; +void __SCNetworkConnectionForceOnDemandConfigurationRefresh(void); +char * __SCNetworkConnectionGetControllerPortName(void); +CFDictionaryRef __SCNetworkConnectionCopyTokenParameters(SCNetworkConnectionRef connection); -/* Output arguments: DNS configuration - * (sent as out-of-line data in a message) - */ -typedef char * dnsDataOut_t; +__END_DECLS -#endif /* !_SHARED_DNS_INFO_TYPES_H */ +#endif /* _SCNETWORKCONNECTIONINTERNAL_H */ diff --git a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c index 6e98de1..7b58f62 100644 --- a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c +++ b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.c @@ -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@ * @@ -399,6 +399,7 @@ processPreferences(CFStringRef serviceID, CFDictionaryRef dict; dict = CFArrayGetValueAtIndex(prefs, i); + assert(dict != NULL); if (isA_CFDictionary(dict)) { newDict = (*callout)(serviceID, dict, context1, context2, context3); if (newDict == NULL) { @@ -2179,6 +2180,7 @@ SCUserPreferencesSetInterfacePassword(SCUserPreferencesRef userPreferences, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } + assert(newConfig != NULL); CFDictionarySetValue(newConfig, kSCPropNetVPNAuthPassword, unique_id); diff --git a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h index d790dbb..81e6194 100644 --- a/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h +++ b/SystemConfiguration.fproj/SCNetworkConnectionPrivate.h @@ -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@ * @@ -40,7 +40,6 @@ __BEGIN_DECLS #pragma mark - #pragma mark SCNetworkConnection SPIs - 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 +SCNetworkConnectionRefreshOnDemandState (SCNetworkConnectionRef connection) __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + 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); +/*! + @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 @@ -107,6 +383,8 @@ SCNetworkConnectionSetClientInfo (SCNetworkConnectionRef connection, * * external.mycompany.com * + * OnDemandMatchAppEnabled + * 0 * *
* @@ -115,34 +393,88 @@ SCNetworkConnectionSetClientInfo (SCNetworkConnectionRef connection, // 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 -#define kSCNetworkConnectionOnDemandTriggers CFSTR("Triggers") +#define kSCNetworkConnectionOnDemandTriggers CFSTR("Triggers") /* CFArray[CFDictionary] */ // VPN service ID -#define kSCNetworkConnectionOnDemandServiceID CFSTR("ServiceID") +#define kSCNetworkConnectionOnDemandServiceID CFSTR("ServiceID") /* CFString */ // VPN service status (idle, connecting, connected, disconnecting) -#define kSCNetworkConnectionOnDemandStatus CFSTR("Status") +#define kSCNetworkConnectionOnDemandStatus CFSTR("Status") /* CFNumber */ // 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. -#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. -#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. -#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, diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c index bb681bd..b66bcb7 100644 --- a/SystemConfiguration.fproj/SCNetworkInterface.c +++ b/SystemConfiguration.fproj/SCNetworkInterface.c @@ -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@ * @@ -63,7 +63,9 @@ #include // for kIOEthernetInterfaceClass #include #include +#if !TARGET_IPHONE_SIMULATOR #include +#endif // !TARGET_IPHONE_SIMULATOR #include "dy_framework.h" @@ -75,10 +77,6 @@ #define kPCIThunderboltString "PCI-Thunderbolt" #endif -#ifndef kUSBProductString -#define kUSBProductString "USB Product Name" -#endif - #ifndef kIOUserEthernetInterfaceRoleKey #define kIOUserEthernetInterfaceRoleKey "InterfaceRole" #endif @@ -123,6 +121,7 @@ enum { kSortBluetoothPAN_GN, kSortBluetoothPAN_NAP, kSortBluetoothPAN_U, + kSortThunderbolt, kSortBond, kSortBridge, kSortVLAN, @@ -180,12 +179,13 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4 = { 0, // entryID NULL, // overrides FALSE, // modemIsV92 + NULL, // name prefix NULL, // type NULL, // unit { NULL, 0, 0 }, // usb { name, vid, pid } kSortUnknown, // sort_order FALSE, // supportsBond - { NULL, NULL, NULL }, // bond { interfaces, options, mode } + { NULL, NULL, NULL }, // bond { interfaces, mode, options } FALSE, // supportsBridge { NULL, NULL }, // bridge { interfaces, options } FALSE, // supportsVLAN @@ -223,12 +223,13 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback = { 0, // entryID NULL, // overrides FALSE, // modemIsV92 + NULL, // name prefix NULL, // type NULL, // unit { NULL, 0, 0 }, // usb { name, vid, pid } kSortUnknown, // sort_order FALSE, // supportsBond - { NULL, NULL, NULL }, // bond { interfaces, options, mode } + { NULL, NULL, NULL }, // bond { interfaces, mode, options } 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)) { - int pid; - int vid; + int pid = 0; + int vid = 0; 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) || @@ -410,8 +411,8 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf) } 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); @@ -444,7 +445,7 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf) member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i); CFStringAppendFormat(result, NULL, CFSTR("%s%@"), - (i == 0) ? ", interfaces = " : ", ", + (i == 0) ? ", interfaces = " : ",", SCNetworkInterfaceGetBSDName(member)); } } @@ -466,7 +467,7 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf) member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i); CFStringAppendFormat(result, NULL, CFSTR("%s%@"), - (i == 0) ? ", interfaces = " : ", ", + (i == 0) ? ", interfaces = " : ",", SCNetworkInterfaceGetBSDName(member)); } } @@ -556,6 +557,9 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf) if (interfacePrivate->overrides != NULL) CFRelease(interfacePrivate->overrides); + if (interfacePrivate->prefix != NULL) + CFRelease(interfacePrivate->prefix); + 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); - if (kr != KERN_SUCCESS) { + if (kr != kIOReturnSuccess) { 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->prefix = 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) { @@ -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)) { - 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); @@ -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) { - 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) { - 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; - 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; } @@ -1524,6 +1563,7 @@ isBluetoothBuiltin(Boolean *haveController) hciController = IOIteratorNext(iter); IOObjectRelease(iter); if(hciController != MACH_PORT_NULL) { +#if !TARGET_IPHONE_SIMULATOR CFNumberRef idVendor; idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0); @@ -1538,6 +1578,7 @@ isBluetoothBuiltin(Boolean *haveController) CFRelease(idVendor); } +#endif // !TARGET_IPHONE_SIMULATOR IOObjectRelease(hciController); } @@ -1574,6 +1615,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate, io_registry_entry_t bus, CFDictionaryRef bus_dict) { +#if !TARGET_IPHONE_SIMULATOR // capture USB info interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, @@ -1590,6 +1632,7 @@ processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate, CFSTR(kUSBProductID), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); +#endif // !TARGET_IPHONE_SIMULATOR 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, @@ -1717,12 +1762,16 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, 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; + } 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; @@ -1745,7 +1794,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, 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; @@ -1808,6 +1857,11 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, // 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)); @@ -1821,6 +1875,14 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, // 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) { @@ -1890,7 +1952,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, // 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); @@ -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"); - interfacePrivate->localized_arg1 = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey)); + interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict); } } @@ -1956,7 +2018,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, } // Device - interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey)); + interfacePrivate->entity_device = IODictionaryCopyBSDName(interface_dict); // Hardware (MAC) address data = CFDictionaryGetValue(controller_dict, CFSTR(kIOMACAddress)); @@ -1964,6 +2026,12 @@ processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate, 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) && @@ -2448,40 +2516,41 @@ createInterface(io_registry_entry_t interface, processInterface func) /* 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); - 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); - 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); - 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); - 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); + assert(interfacePrivate != NULL); interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane); interfacePrivate->entryID = entryID; @@ -3360,6 +3429,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, if (matching_interfaces != NULL) { CFIndex n; SCPreferencesRef prefs; + Boolean temp_preferences = FALSE; n = CFArrayGetCount(matching_interfaces); switch (n) { @@ -3377,7 +3447,21 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, 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; } @@ -3395,7 +3479,7 @@ _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) { interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice); } - CFRelease(prefs); + if (temp_preferences) CFRelease(prefs); 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; + } 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; @@ -3651,7 +3741,7 @@ __SCNetworkInterfaceCopyAll_IONetworkInterface(void) 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); @@ -3721,9 +3811,9 @@ __SCNetworkInterfaceCopyAll_RS232() 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++) { @@ -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; @@ -3861,7 +3938,7 @@ _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs) 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); @@ -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) @@ -4594,7 +4671,7 @@ __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface localized_name = copy_display_name(interface, FALSE, TRUE); return localized_name; } -#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR +#endif // !TARGET_OS_IPHONE __private_extern__ @@ -6045,6 +6122,10 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface) SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; CFStringRef name; + if (interface == NULL) { + return NULL; + } + info = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, @@ -6058,6 +6139,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface) // 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); } @@ -6067,6 +6149,7 @@ _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface) if (interfacePrivate->usb.pid != NULL) { CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid); } +#endif // !TARGET_IPHONE_SIMULATOR } 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) { @@ -6164,6 +6256,53 @@ _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface) #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) { @@ -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 diff --git a/SystemConfiguration.fproj/SCNetworkReachability.c b/SystemConfiguration.fproj/SCNetworkReachability.c index 73e8ff8..efdae04 100644 --- a/SystemConfiguration.fproj/SCNetworkReachability.c +++ b/SystemConfiguration.fproj/SCNetworkReachability.c @@ -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@ * @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -72,24 +73,18 @@ #define s6_addr16 __u6_addr.__u6_addr16 #endif +#include "SCNetworkConnectionInternal.h" + #include "SCNetworkReachabilityInternal.h" #include +#include -#if !TARGET_IPHONE_SIMULATOR +#if defined(HAVE_IPSEC_STATUS) || defined(HAVE_VPN_STATUS) #include -#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 @@ -103,6 +98,12 @@ #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; @@ -136,25 +137,12 @@ _getaddrinfo_interface_async_call(const char *nodename, 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") -// 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 @@ -211,16 +199,20 @@ static const struct addrinfo HINTS_DEFAULT = { 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 +static Boolean D_nwiBypass = FALSE; + + #if !TARGET_OS_IPHONE /* @@ -234,11 +226,39 @@ static IOPMSystemPowerStateCapabilities power_capabilities = kIOPMSytemPowerStat * host "something has changed" notifications */ +// Note: protected by _hn_target_queue() static SCDynamicStoreRef hn_store = NULL; -static dispatch_queue_t hn_dispatchQueue = 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 */ @@ -249,60 +269,56 @@ typedef struct { } 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; + + typedef enum { dns_query_sync, dns_query_async, - dns_query_llq -} dns_query_type; + dns_query_mdns, +} query_type; 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 -__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; - // report initial or updated query time - firstQuery = !timerisset(dnsQueryEnd); - - (void) gettimeofday(dnsQueryEnd, NULL); + (void) gettimeofday(queryEnd, NULL); if (!_sc_debug) { return; } - if (!timerisset(dnsQueryStart)) { + if (!timerisset(queryStart)) { return; } - timersub(dnsQueryEnd, dnsQueryStart, &dnsQueryElapsed); + timersub(queryEnd, queryStart, &queryElapsed); 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 @@ -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", - 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", - dnsQueryElapsed.tv_sec, - dnsQueryElapsed.tv_usec / QUERY_TIME__DIV); + queryElapsed.tv_sec, + queryElapsed.tv_usec / QUERY_TIME__DIV); break; - case dns_query_llq : + case dns_query_mdns : 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", - 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; } @@ -361,11 +377,27 @@ __reach_changed(ReachabilityInfo *r1, ReachabilityInfo *r2) 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; + 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; } @@ -510,12 +542,20 @@ ReachabilityStoreInfo_save(ReachabilityStoreInfoRef store_info) static Boolean ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info) { + CFStringRef key; + CFMutableArrayRef keys; CFStringRef pattern; CFMutableArrayRef patterns; + keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 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, @@ -530,6 +570,11 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info) CFRelease(pattern); // get info for IPv6 services + key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, + kSCDynamicStoreDomainState, + kSCEntNetIPv6); + CFArrayAppendValue(keys, key); + CFRelease(key); pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, @@ -557,7 +602,6 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info) CFArrayAppendValue(patterns, pattern); CFRelease(pattern); -#if !TARGET_IPHONE_SIMULATOR // get info for VPN services pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, @@ -571,7 +615,6 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_info) kSCEntNetVPN); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); -#endif // !TARGET_IPHONE_SIMULATOR // get info for IPSec services // pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, @@ -597,7 +640,8 @@ ReachabilityStoreInfo_fill(ReachabilityStoreInfoRef store_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; @@ -711,6 +755,12 @@ ReachabilityStoreInfo_update(ReachabilityStoreInfoRef store_info, #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 @@ -983,12 +1033,9 @@ updatePPPAvailable(ReachabilityStoreInfoRef store_info, return sc_status; } - -#pragma mark - #pragma mark VPN info -#if !TARGET_IPHONE_SIMULATOR static int updateVPNStatus(ReachabilityStoreInfoRef store_info, const struct sockaddr *sa, @@ -1216,10 +1263,8 @@ updateVPNAvailable(ReachabilityStoreInfoRef store_info, return sc_status; } -#endif // !TARGET_IPHONE_SIMULATOR -#pragma mark - #pragma mark IPSec info @@ -1398,7 +1443,7 @@ typedef struct { /* * 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 @@ -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)) { @@ -1591,31 +1636,21 @@ route_get(const struct sockaddr *address, 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 ret; - int sc_status = kSCStatusReachabilityUnknown; - CFStringRef server = NULL; + int ret = 0; 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 : @@ -1645,7 +1680,8 @@ checkAddress(ReachabilityStoreInfoRef store_info, SCLog(TRUE, LOG_INFO, CFSTR("checkAddress(): unexpected address family %d"), address->sa_family); - sc_status = kSCStatusInvalidArgument; + *sc_status = kSCStatusInvalidArgument; + ret = EPERM; 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 - goto checkAvailable; + goto done; default : // if error - sc_status = ret; + *sc_status = ret; goto done; } @@ -1680,45 +1716,48 @@ checkAddress(ReachabilityStoreInfoRef store_info, isock = socket(AF_INET, SOCK_DGRAM, 0); if (isock == -1) { + ret = errno; 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; } - if (!(ifr.ifr_flags & IFF_UP)) { - goto checkAvailable; + if (!(ifr->ifr_flags & IFF_UP)) { + ret = EHOSTUNREACH; + goto done; } 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; - } else if (ifr.ifr_flags & IFF_LOOPBACK) { + } else if (ifr->ifr_flags & IFF_LOOPBACK) { 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 *addr2 = (void *)info.rti_info[RTAX_IFA]; + void *addr2 = (void *)info->rti_info[RTAX_IFA]; 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, - 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; } @@ -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; - 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); /* @@ -1739,9 +1778,9 @@ checkAddress(ReachabilityStoreInfoRef store_info, } 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; - 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 : @@ -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; } - bzero(&if_name, sizeof(if_name)); - bcopy(info.sdl->sdl_data, + bzero(if_name, IFNAMSIZ); + bcopy(info->sdl->sdl_data, 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)); - 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); - 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 (isock != -1) (void)close(isock); if (server != NULL) CFRelease(server); + 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 @@ -1883,14 +2082,7 @@ _SCNetworkReachabilityCopyTargetDescription(SCNetworkReachabilityRef target) 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; } } @@ -1908,7 +2100,7 @@ _SCNetworkReachabilityCopyTargetFlags(SCNetworkReachabilityRef target) 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" : ""); @@ -1935,15 +2127,20 @@ __SCNetworkReachabilityCopyDescription(CFTypeRef cf) // add additional "name" info if (targetPrivate->type == reachabilityTypeName) { - if (targetPrivate->dnsMP != MACH_PORT_NULL) { + if (targetPrivate->dnsActive) { 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 n = CFArrayGetCount(targetPrivate->resolvedAddress); + CFIndex n = CFArrayGetCount(targetPrivate->resolvedAddresses); CFStringAppendFormat(result, NULL, CFSTR(" (")); for (i = 0; i < n; i++) { @@ -1951,31 +2148,38 @@ __SCNetworkReachabilityCopyDescription(CFTypeRef cf) 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); } - } 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 { - CFStringAppendFormat(result, NULL, CFSTR(" (no addresses")); + CFStringAppendFormat(result, NULL, CFSTR(" (no addresses)")); } } 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->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); @@ -2081,11 +2282,6 @@ __SCNetworkReachabilityInitialize(void) _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) { @@ -2093,6 +2289,11 @@ __SCNetworkReachabilityInitialize(void) } #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); @@ -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() */ -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); - if (needResolve) { - // allow the DNS query to be [re-]started - targetPrivate->needResolve = TRUE; - } - 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() - * - 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 -__SCNetworkReachabilityPerformNoLock(SCNetworkReachabilityRef target) +__SCNetworkReachabilityPerform(SCNetworkReachabilityRef target) { CFRetain(target); dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{ - __SCNetworkReachabilityPerformInlineNoLock(target, FALSE); + __SCNetworkReachabilityPerformConcurrent(target); 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 -__SCNetworkReachabilityPerform(SCNetworkReachabilityRef target) +__SCNetworkReachabilityPerformLocked(SCNetworkReachabilityRef target) { dispatch_queue_t queue; SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target; @@ -2277,79 +2439,18 @@ __SCNetworkReachabilityCreatePrivate(CFAllocatorRef allocator) return NULL; } + bzero((void *)targetPrivate + sizeof(CFRuntimeBase), size); + 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) { @@ -2412,6 +2513,8 @@ is_valid_address(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); + 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); } + 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) { +#ifdef HAVE_REACHABILITY_SERVER + CFDictionaryRef appLayerVPNProperties; +#endif // HAVE_REACHABILITY_SERVER 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; + + /* 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 %@"), @@ -2558,16 +2674,13 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, const struct sockaddr *addr_l = NULL; const struct sockaddr *addr_r = NULL; CFDataRef data; - struct addrinfo *hints = NULL; CFStringRef interface = NULL; - CFBooleanRef llqBypass; CFStringRef nodename; CFBooleanRef onDemandBypass; CFBooleanRef resolverBypass; #ifdef HAVE_REACHABILITY_SERVER CFBooleanRef serverBypass; #endif // HAVE_REACHABILITY_SERVER - CFStringRef servname; SCNetworkReachabilityRef target; SCNetworkReachabilityPrivateRef targetPrivate; @@ -2582,12 +2695,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, _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))) { @@ -2604,23 +2711,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } 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))) { @@ -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)) { @@ -2653,11 +2737,12 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } #endif // HAVE_REACHABILITY_SERVER - if ((nodename != NULL) || (servname != NULL)) { + + if (nodename != 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; } @@ -2671,7 +2756,7 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } 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; @@ -2682,14 +2767,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } 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, @@ -2704,10 +2781,6 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } - if (llqBypass != NULL) { - targetPrivate->llqBypass = CFBooleanGetValue(llqBypass); - } - if (onDemandBypass != NULL) { targetPrivate->onDemandBypass = CFBooleanGetValue(onDemandBypass); } @@ -2717,11 +2790,13 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef allocator, } #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 + if (_sc_debug && (_sc_log > 0)) { const char *opt; @@ -2775,12 +2850,12 @@ SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef target, } 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); @@ -2794,18 +2869,18 @@ SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef target, 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); - 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)) { @@ -2827,23 +2902,23 @@ __SCNetworkReachabilitySetResolvedAddress(int32_t status, } /* 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 */ - 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) { - __SCNetworkReachabilityPerform(target); + __SCNetworkReachabilityPerformLocked(target); } return; @@ -2851,18 +2926,18 @@ __SCNetworkReachabilitySetResolvedAddress(int32_t status, 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; - __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; } @@ -2896,12 +2971,8 @@ replyMPCopyDescription(const void *info) return CFStringCreateWithFormat(NULL, NULL, - CFSTR(" {%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(" {name = %s, target = %p}"), + targetPrivate->name, target); } @@ -2984,11 +3055,11 @@ enqueueAsyncDNSQuery_dispatch(SCNetworkReachabilityRef target) }); dispatch_source_set_cancel_handler(source, ^{ -#if !TARGET_OS_EMBEDDED +#if !TARGET_OS_IPHONE mach_vm_address_t context; -#else // !TARGET_OS_EMBEDDED +#else // !TARGET_OS_IPHONE mach_port_context_t context; -#endif // !TARGET_OS_EMBEDDED +#endif // !TARGET_OS_IPHONE kern_return_t kr; mach_port_t mp; @@ -3084,7 +3155,7 @@ enqueueAsyncDNSQuery_CF(SCNetworkReachabilityRef target) static Boolean -enqueueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp) +requeueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp) { 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) { @@ -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) && - (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 - ok = enqueueAsyncDNSQuery(target, mp); + ok = requeueAsyncDNSQuery(target, mp); 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 !TARGET_IPHONE_SIMULATOR *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; @@ -3489,7 +3578,6 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef store_info, SCNetworkReachabilityFlags *flags, Boolean *haveDNS, const char *nodename, - const char *servname, 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) { - 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; } @@ -3537,7 +3623,8 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef store_info, 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; @@ -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 */ @@ -3599,7 +3684,8 @@ _SC_R_checkResolverReachability(ReachabilityStoreInfoRef store_info, if (*cp == '.') dots++; } - if (dots > ndots) { + /* Per KB: HT4845 */ + if (dots >= ndots) { 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, - const char *servname, 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, - servname, 0, resolver_if_index, dns_config_index, ""); + 0, resolver_if_index, dns_config_index, ""); - done : + done : ReachabilityStoreInfo_free(&store_info); return ok; @@ -3843,7 +3903,7 @@ _SC_checkResolverReachabilityByAddress(SCDynamicStoreRef *storeP, 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 : @@ -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; } +/* + * dns_refresh_disable + * + * Called to stop monitoring for network/DNS changes + * - caller must be running on the _hn_changes_queue() + */ 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; } +#endif // USE_DNSSERVICEGETADDRINFO + #pragma mark - +#pragma mark [m]DNS Queries + + +static void +dequeueDNSQuery(SCNetworkReachabilityRef target); static dispatch_queue_t -_llq_queue() +_dns_queue() { 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; } +#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 - * - caller must be running on the _llq_queue() + * - caller must be running on the _dns_queue() */ 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); - __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; @@ -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 -_llq_callback(DNSServiceRef sdRef, +_dns_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, @@ -4026,81 +4162,105 @@ _llq_callback(DNSServiceRef sdRef, 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; - 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); } - CFRelease(targetPrivate->resolvedAddress); - targetPrivate->resolvedAddress = NULL; + CFRelease(targetPrivate->dnsAddresses); + targetPrivate->dnsAddresses = NULL; } 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 - CFArrayAppendValue(addresses, llqAddress); + if (i == kCFNotFound) { + CFArrayAppendValue(addresses, dnsAddress); + } +#ifdef HANDLE_RMV_REQUESTS } else { - CFIndex i; - // remove address - i = CFArrayGetFirstIndexOfValue(addresses, - CFRangeMake(0, CFArrayGetCount(addresses)), - llqAddress); if (i != kCFNotFound) { CFArrayRemoveValueAtIndex(addresses, i); } +#endif // HANDLE_RMV_REQUESTS } - CFRelease(llqAddress); + CFRelease(dnsAddress); if (CFArrayGetCount(addresses) > 0) { - targetPrivate->resolvedAddress = addresses; - targetPrivate->resolvedAddressError = NETDB_SUCCESS; + targetPrivate->dnsAddresses = addresses; + targetPrivate->dnsError = NETDB_SUCCESS; } else { // if host not found - targetPrivate->resolvedAddress = CFRetain(kCFNull); - targetPrivate->resolvedAddressError = EAI_NONAME; + targetPrivate->dnsAddresses = CFRetain(kCFNull); + targetPrivate->dnsError = EAI_NONAME; CFRelease(addresses); } - targetPrivate->needResolve = FALSE; } 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 (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 : - 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; + case kDNSServiceErr_ServiceNotRunning : + // mDNSResponder crashed, restart query + DNSServiceRefDeallocate(dnsMain); + dnsMain = NULL; + dnsCount = 0; default : + _dns_mark(target, FALSE, NULL); + SCLog(TRUE, LOG_ERR, - CFSTR("%sSCNetworkReachability _llq_callback w/error=%d"), + CFSTR("%sSCNetworkReachability _dns_callback w/error=%d"), targetPrivate->log_prefix, errorCode); break; @@ -4108,20 +4268,34 @@ _llq_callback(DNSServiceRef sdRef, 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. - 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)) { - CFSetApplyFunction(llqUpdated, _llq_notify, NULL); - CFRelease(llqUpdated); - llqUpdated = NULL; + CFSetApplyFunction(dnsUpdated, _dns_notify, NULL); + CFRelease(dnsUpdated); + dnsUpdated = NULL; } return; @@ -4129,191 +4303,271 @@ _llq_callback(DNSServiceRef sdRef, static Boolean -enqueueLongLivedQuery(SCNetworkReachabilityRef target) +enqueueDNSQuery(SCNetworkReachabilityRef target) { 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 - __dns_query_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd); + __mark_operation_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd); 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 - MUTEX_UNLOCK(&targetPrivate->lock); 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, - CFSTR("DNSServiceCreateConnection(&llqMain) failed, error = %d"), + CFSTR("DNSServiceCreateConnection(&dnsMain) failed, error = %d"), 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); - 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 - | kDNSServiceFlagsShareConnection, + | kDNSServiceFlagsShareConnection + | kDNSServiceFlagsTimeout, targetPrivate->if_index, // interfaceIndex 0, // protocol targetPrivate->name, // hostname - _llq_callback, // callback + _dns_callback, // callback (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 { - 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; } +#endif // USE_DNSSERVICEGETADDRINFO + static void -dequeueLongLivedQuery(SCNetworkReachabilityRef target) +dequeueDNSQuery(SCNetworkReachabilityRef target) { 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); - llqCount--; - if (llqCount == 0) { + dnsCount--; + if (dnsCount == 0) { // 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; } +/* + * 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 @@ -4363,9 +4617,16 @@ __SCNetworkReachabilityOnDemandCheckCallback(SCNetworkReachabilityRef onDemandSe 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); @@ -4379,21 +4640,20 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef store_info, 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; - SCNetworkConnectionStatus onDemandStatus; - SCDynamicStoreRef store; + SCNetworkConnectionStatus onDemandStatus = kSCNetworkConnectionInvalid; + CFMutableDictionaryRef selectOptions = NULL; + Boolean success = FALSE; 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); } @@ -4401,17 +4661,70 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef store_info, /* * 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) { @@ -4420,6 +4733,7 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef store_info, } if (targetPrivate->onDemandServer != NULL) { + SCNetworkReachabilitySetCallback(targetPrivate->onDemandServer, NULL, NULL); if (targetPrivate->dispatchQueue != NULL) { // unschedule __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE); @@ -4446,6 +4760,7 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef store_info, targetPrivate->onDemandServiceID = NULL; } } + 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) { + SCNetworkReachabilityPrivateRef demandPrivate; 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, kSCNetworkReachabilityOptionServerBypass, kCFBooleanTrue); + if (targetPrivate->serverBypass) { + CFDictionarySetValue(options, kSCNetworkReachabilityOptionServerBypass, kCFBooleanTrue); + } #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 }; @@ -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); - if (ok && (*flags & kSCNetworkReachabilityFlagsReachable)) { + + + if ((*flags & kSCNetworkReachabilityFlagsReachable) && !(*flags & kSCNetworkReachabilityFlagsConnectionRequired)) { + // if VPN "server" is [still] reachable + 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; + // 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, @@ -4515,28 +4845,140 @@ __SCNetworkReachabilityOnDemandCheck(ReachabilityStoreInfoRef store_info, targetPrivate->log_prefix); } - onDemand = TRUE; + success = TRUE; } } if (onDemandRemoteAddress != NULL) { if (targetPrivate->onDemandRemoteAddress == NULL) { - targetPrivate->onDemandRemoteAddress = onDemandRemoteAddress; - } else { - CFRelease(onDemandRemoteAddress); + targetPrivate->onDemandRemoteAddress = CFRetain(onDemandRemoteAddress); } } 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, - const char *servname, - const struct addrinfo *hints, 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, - servname, - hints, + NULL, + &HINTS_DEFAULT, interface, reply_callback, (void *)&reply); @@ -4621,7 +5061,7 @@ getaddrinfo_interface_sync(const char *nodename, *res = reply.res; return reply.status; } -#endif /* HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL */ +#endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL static Boolean @@ -4637,7 +5077,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, 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); @@ -4647,6 +5087,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, #ifdef HAVE_REACHABILITY_SERVER if (!targetPrivate->serverBypass) { if (!targetPrivate->serverActive) { + ok = __SCNetworkReachabilityServer_targetAdd(target); if (!ok) { targetPrivate->serverBypass = TRUE; @@ -4663,7 +5104,11 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, } 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; } } @@ -4724,8 +5169,9 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, 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); @@ -4733,186 +5179,100 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, /* 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) { - 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 ((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) { - 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. */ - onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, FALSE, &my_info.flags); + onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, FALSE, &onDemandFlags); if (onDemand) { /* if OnDemand connection is needed */ + my_info.flags = onDemandFlags; goto done; } } + targetPrivate->dnsBlocked = FALSE; + /* 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, - 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->resolverFlags = kSCNetworkReachabilityFlagsReachable; 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); - __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) { @@ -4927,118 +5287,95 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_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 */ - goto checkResolvedAddress; + goto checkResolvedAddresses; } 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, - 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 */ - goto checkResolvedAddress; + goto checkResolvedAddresses; } 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, - CFSTR("%sstart DNS query for %s%s%s%s%s"), + CFSTR("%sstart DNS query for name = %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 : ""); + 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 */ - goto checkResolvedAddress; + goto checkResolvedAddresses; } SCLog(_sc_debug, LOG_INFO, - CFSTR("%scheck DNS for %s%s%s%s%s"), + CFSTR("%scheck DNS for name = %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 : ""); + targetPrivate->name); /* * 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, - targetPrivate->serv, - &targetPrivate->hints, + NULL, + &HINTS_DEFAULT, &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 - __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); - checkResolvedAddress : + checkResolvedAddresses : /* * 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) { - 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. */ - onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, TRUE, &my_info.flags); + onDemand = __SCNetworkReachabilityOnDemandCheck(store_info, target, TRUE, &onDemandFlags); if (onDemand) { /* if OnDemand connection is needed */ + my_info.flags = onDemandFlags; goto done; } } + if (!targetPrivate->haveDNS) { /* * No DNS servers are defined. Set flags based on @@ -5134,7 +5474,8 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, done: - _reach_set(reach_info, &my_info, targetPrivate->cycle); + + _reach_set(reach_info, &my_info, targetPrivate->cycle, targetPrivate->if_index, targetPrivate->if_name); error : @@ -5143,9 +5484,8 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info, } int -SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target) +SCNetworkReachabilityGetInterfaceIndex(SCNetworkReachabilityRef target) { - SCNetworkReachabilityFlags flags; 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 - flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending; 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 ... */ - if (ok && rankReachability(flags) == 2) { + if (ok && rankReachability(targetPrivate->info.flags) == 2) { 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 - *flags = targetPrivate->info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending; + *flags = targetPrivate->info.flags & kSCNetworkReachabilityFlagsMask; 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 : @@ -5224,7 +5566,7 @@ SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, static void -__SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef store) +__SCNetworkReachabilitySetNotifications(SCDynamicStoreRef store) { CFStringRef key; CFMutableArrayRef keys; @@ -5234,113 +5576,117 @@ __SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef store) 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 @@ -5351,7 +5697,6 @@ __SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef store) CFRelease(key); #endif // TARGET_OS_IPHONE - // 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) { -#if !TARGET_OS_IPHONE - Boolean cpuStatusChanged = FALSE; -#endif // !TARGET_OS_IPHONE Boolean dnsConfigChanged = FALSE; CFIndex i; Boolean forcedChange = FALSE; @@ -5394,6 +5722,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, CFIndex nTargets; Boolean networkConfigChanged = FALSE; struct timeval now; + Boolean onDemandConfigChanged = FALSE; #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); - dispatch_sync(_hn_queue(), ^{ + dispatch_sync(_hn_target_queue(), ^{ /* 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) { - 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 { + // data not available, use default power_capabilities = kIOPMSytemPowerStateCapabilitiesMask; } @@ -5479,6 +5793,19 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, } 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 */ @@ -5496,31 +5823,39 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, "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 ", - - // 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 - #define PWR 4 + #define PWR 8 if (powerStatusChanged) { changes |= PWR; - if (cpuStatusChanged) { - changes += PWR; - } } #endif // !TARGET_OS_IPHONE + #define VOD 4 + if (onDemandConfigChanged) { + changes |= VOD; + } + #define DNS 2 if (dnsConfigChanged) { changes |= DNS; @@ -5532,7 +5867,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, } SCLog(TRUE, LOG_INFO, - CFSTR("process %s%sconfiguration change"), + CFSTR("process %s%s%sconfiguration change"), 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++) { + Boolean dnsNeedsUpdate = FALSE; SCNetworkReachabilityRef target = targets[i]; SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target; MUTEX_LOCK(&targetPrivate->lock); + if (dnsConfigChanged) { targetPrivate->last_dns = now; - targetPrivate->dnsRetryCount = 0; } if (networkConfigChanged) { @@ -5564,14 +5900,19 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, #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. */ - 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 */ @@ -5581,10 +5922,9 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, &ns_flags, &targetPrivate->haveDNS, targetPrivate->name, - targetPrivate->serv, targetPrivate->if_index, - NULL, - NULL, + &ns_if_index, + &ns_dns_config, 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); + ns_flags = kSCNetworkReachabilityFlagsReachable; 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) { - 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, - CFSTR("%scancel DNS query for %s%s%s%s%s"), + CFSTR("%scancel [m]DNS query for name = %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 : ""); - 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 */ @@ -5634,7 +5986,7 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef store, } if (targetPrivate->scheduled) { - __SCNetworkReachabilityPerform(target); + __SCNetworkReachabilityPerformLocked(target); } MUTEX_UNLOCK(&targetPrivate->lock); @@ -5710,11 +6062,6 @@ reachPerform(void *info) MUTEX_LOCK(&targetPrivate->lock); - if (targetPrivate->dnsRetry != NULL) { - // cancel DNS retry - dequeueAsyncDNSRetry(target); - } - if (!targetPrivate->scheduled) { // if not currently scheduled MUTEX_UNLOCK(&targetPrivate->lock); @@ -5799,7 +6146,10 @@ reachPerform(void *info) 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) { @@ -5807,9 +6157,6 @@ reachPerform(void *info) return; } - /* save last notification info */ - _reach_set(&targetPrivate->last_notify, &reach_info, cycle); - /* save last notification time */ (void)gettimeofday(&targetPrivate->last_push, NULL); @@ -5827,7 +6174,7 @@ reachPerform(void *info) if (rlsFunction != NULL) { (*rlsFunction)(target, - reach_info.flags & ~kSCNetworkReachabilityFlagsFirstResolvePending, + reach_info.flags & kSCNetworkReachabilityFlagsMask, context_info); } @@ -5905,6 +6252,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, #ifdef HAVE_REACHABILITY_SERVER if (!targetPrivate->serverBypass) { if (!targetPrivate->serverActive) { + ok = __SCNetworkReachabilityServer_targetAdd(target); if (!ok) { targetPrivate->serverBypass = TRUE; @@ -5925,6 +6273,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, goto done; } + goto watch; } } @@ -5932,51 +6281,86 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, /* schedule the SCNetworkReachability did-something-change handler */ - dispatch_sync(_hn_queue(), ^{ + dispatch_sync(_hn_target_queue(), ^{ 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")); - dns_configuration_unwatch(); 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; - dns_configuration_unwatch(); - _SCErrorSet(kSCStatusFailed); 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; + _SCErrorSet(kSCStatusFailed); + return; + } + +#ifdef USE_DNSSERVICEGETADDRINFO + if (!dns_refresh_enable(_hn_changes_queue(), + hn_store, + __SCNetworkReachabilityHandleChanges)) { + // if error dns_configuration_unwatch(); + SCDynamicStoreSetDispatchQueue(hn_store, NULL); + CFRelease(hn_store); + hn_store = NULL; + _SCErrorSet(kSCStatusFailed); 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); @@ -6019,20 +6403,29 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, * 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; - _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 - _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->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 - _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 */ - _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 - _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); @@ -6155,6 +6560,7 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, // unschedule the target specific sources if (targetPrivate->dispatchQueue != NULL) { if (targetPrivate->onDemandServer != NULL) { + SCNetworkReachabilitySetCallback(targetPrivate->onDemandServer, NULL, NULL); __SCNetworkReachabilityUnscheduleFromRunLoop(targetPrivate->onDemandServer, NULL, NULL, TRUE); } @@ -6186,6 +6592,9 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, 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); @@ -6201,6 +6610,7 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, // Cancel our request for server monitoring // if (targetPrivate->serverActive) { + ok = __SCNetworkReachabilityServer_targetUnschedule(target); if (!ok) { SCLog(TRUE, LOG_DEBUG, @@ -6221,22 +6631,17 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, #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) { @@ -6249,8 +6654,6 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, // 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); @@ -6259,6 +6662,32 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target, 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 diff --git a/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h b/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h index f0caeaa..69ad3af 100644 --- a/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h +++ b/SystemConfiguration.fproj/SCNetworkReachabilityInternal.h @@ -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@ * @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -37,10 +38,25 @@ #include #include -#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 -#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 - @@ -50,7 +66,15 @@ #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 { @@ -82,11 +106,10 @@ typedef struct { /* target host name */ const char *name; - const char *serv; - struct addrinfo hints; Boolean needResolve; - CFArrayRef resolvedAddress; /* CFArray[CFData] */ - int resolvedAddressError; + CFArrayRef resolvedAddresses; /* CFArray[CFData] */ + int resolvedError; + SCNetworkReachabilityFlags resolverFlags; /* [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 dnsRetry; // != NULL if DNS retry request queued - int dnsRetryCount; // number of retry attempts /* [async] processing info */ struct timeval last_dns; @@ -138,10 +159,22 @@ typedef struct { 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 */ @@ -154,13 +187,17 @@ typedef struct { 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 + + Boolean useVPNAppLayer; // if App-Layer VPN, only use client mode #endif // HAVE_REACHABILITY_SERVER Boolean resolverBypass; // set this flag to bypass resolving the name + + /* logging */ char log_prefix[32]; @@ -176,7 +213,12 @@ typedef struct { #define REACH_SERVER_VERSION 20110323 + +#if !TARGET_IPHONE_SIMULATOR #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_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_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 @@ -233,13 +273,13 @@ enum { 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); +void +__SCNetworkReachabilityPerform (SCNetworkReachabilityRef target); + +void +__SCNetworkReachabilityPerformConcurrent (SCNetworkReachabilityRef target); + #ifdef HAVE_REACHABILITY_SERVER dispatch_queue_t __SCNetworkReachability_concurrent_queue (void); -void -__SCNetworkReachabilityPerformNoLock (SCNetworkReachabilityRef target); - #pragma mark - #pragma mark [XPC] Reachability Server (client APIs) @@ -284,17 +327,79 @@ __SCNetworkReachabilityServer_targetStatus (SCNetworkReachabilityRef target); Boolean __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef target); + 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 +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 diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c index 1d85e43..5a19657 100644 --- a/SystemConfiguration.fproj/SCNetworkService.c +++ b/SystemConfiguration.fproj/SCNetworkService.c @@ -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@ * @@ -38,6 +38,7 @@ #include +#define EXTERNAL_ID_DOMAIN_PREFIX "_" 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->externalIDs != NULL) CFRelease(servicePrivate->externalIDs); 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); @@ -452,6 +454,8 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco } protocol = SCNetworkServiceCopyProtocol(service, protocolType); + assert(protocol != NULL); + newEntity = _protocolTemplate(service, protocolType); ok = SCNetworkProtocolSetConfiguration(protocol, newEntity); CFRelease(newEntity); @@ -519,6 +523,7 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs) } servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, keys[i], NULL); + assert(servicePrivate != NULL); CFArrayAppendValue(array, (SCNetworkServiceRef)servicePrivate); CFRelease(servicePrivate); } @@ -620,6 +625,7 @@ _SCNetworkServiceCopyActive(SCDynamicStoreRef store, CFStringRef serviceID) } servicePrivate = __SCNetworkServiceCreatePrivate(NULL, NULL, serviceID, NULL); + assert(servicePrivate != NULL); if (store != NULL) { servicePrivate->store = CFRetain(store); } @@ -1130,7 +1136,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service) 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); @@ -1139,7 +1145,7 @@ SCNetworkServiceGetName(SCNetworkServiceRef service) // 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; } @@ -1709,3 +1715,130 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service) 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; +} diff --git a/SystemConfiguration.fproj/SCNetworkSet.c b/SystemConfiguration.fproj/SCNetworkSet.c index 126300f..41dd8d2 100644 --- a/SystemConfiguration.fproj/SCNetworkSet.c +++ b/SystemConfiguration.fproj/SCNetworkSet.c @@ -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@ * @@ -201,6 +201,7 @@ _serviceOrder_add(SCNetworkSetRef set, SCNetworkServiceRef service) } else { newOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } + assert(newOrder != NULL); n = CFArrayGetCount(newOrder); serviceID = SCNetworkServiceGetServiceID(service); @@ -450,6 +451,7 @@ SCNetworkSetCopy(SCPreferencesRef prefs, CFStringRef setID) } setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, setID); + assert(setPrivate != NULL); // mark set as "old" (already established) setPrivate->established = TRUE; @@ -517,6 +519,7 @@ SCNetworkSetCopyAll(SCPreferencesRef prefs) } setPrivate = __SCNetworkSetCreatePrivate(NULL, prefs, keys[i]); + assert(setPrivate != NULL); // 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) { @@ -555,6 +632,7 @@ SCNetworkSetCopyCurrent(SCPreferencesRef prefs) 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; @@ -674,6 +752,7 @@ SCNetworkSetCreate(SCPreferencesRef prefs) 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) @@ -1130,6 +1209,7 @@ add_supported_interfaces(CFMutableArrayRef interface_list, SCNetworkInterfaceRef return; } + 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) { @@ -1168,6 +1379,7 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF CFArrayRef services; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; Boolean updated = FALSE; + Boolean updatedIFs = FALSE; #if TARGET_OS_IPHONE CFArrayRef orphans = NULL; @@ -1193,20 +1405,103 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF } #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); +#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; @@ -1318,6 +1613,7 @@ __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set, CF } CFRelease(interface_list); } + if (updatedIFs) CFRelease(interfaces); 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); + assert(interfaces != NULL); updated = __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set, interfaces); CFRelease(interfaces); diff --git a/SystemConfiguration.fproj/SCNetworkSignature.c b/SystemConfiguration.fproj/SCNetworkSignature.c index 2be8e9b..0a86bc4 100644 --- a/SystemConfiguration.fproj/SCNetworkSignature.c +++ b/SystemConfiguration.fproj/SCNetworkSignature.c @@ -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@ * @@ -46,18 +46,20 @@ #include "SCNetworkSignature.h" #include "SCNetworkSignaturePrivate.h" #include - -const char * kSCNetworkSignatureActiveChangedNotifyName = NETWORK_ID_KEY ".active"; +#include +#include +#include +#include #pragma mark SCNetworkSignature Supporting APIs static CFStringRef create_global_state_v4_key(void) { - return SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, + return SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4); - + } static CFStringRef @@ -88,26 +90,26 @@ create_ipv6_services_pattern(void) 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]; - + 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; - in_addr_t s_addr; + in_addr_t s_addr; 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 - || addr->sa_len != sizeof(struct sockaddr_in)){ + || addr->sa_len != sizeof(struct sockaddr_in)) { _SCErrorSet(kSCStatusInvalidArgument); goto done; } @@ -160,18 +162,18 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc, _SCErrorSet(kSCStatusInvalidArgument); goto done; } - + 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); - + 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; } @@ -181,22 +183,22 @@ SCNetworkSignatureCopyActiveIdentifierForAddress(CFAllocatorRef alloc, 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 = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, service_id, kSCEntNetIPv4); - + service_dict = CFDictionaryGetValue(info, service); - - if (isA_CFDictionary(service_dict) == NULL + + if (isA_CFDictionary(service_dict) == NULL || 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); - + v4_service_pattern = create_ipv4_services_pattern(); CFArrayAppendValue(patterns, v4_service_pattern); - + v6_service_pattern = create_ipv6_services_pattern(); CFArrayAppendValue(patterns, v6_service_pattern); - + info = SCDynamicStoreCopyMultiple(NULL, keys, patterns); - - if (info == NULL + + if (info == NULL || 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 - * 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) { - service_order = CFDictionaryGetValue(global_v4_dict, + service_order = CFDictionaryGetValue(global_v4_dict, kSCPropNetServiceOrder); if (isA_CFArray(service_order) != NULL) { count = CFArrayGetCount(service_order); } } - + active = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - + 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}; - + 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_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); } - + 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? */ - 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; } - } + } done: if (info != NULL) { CFRelease(info); @@ -400,41 +402,44 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc, 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; - 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; } - 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; - 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; - 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; } - /* 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; @@ -443,6 +448,12 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc, 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); @@ -467,6 +478,17 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc, /* 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; @@ -480,6 +502,12 @@ SCNetworkSignatureCopyIdentifierForConnectedSocket(CFAllocatorRef alloc, } done: + if (info != NULL) { + freeconninfo(info); + } + if (if_name_cf != NULL) { + CFRelease(if_name_cf); + } if (local_ip_str != NULL) { CFRelease(local_ip_str); } diff --git a/SystemConfiguration.fproj/SCNetworkSignature.h b/SystemConfiguration.fproj/SCNetworkSignature.h index 10926a6..675ae3f 100644 --- a/SystemConfiguration.fproj/SCNetworkSignature.h +++ b/SystemConfiguration.fproj/SCNetworkSignature.h @@ -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@ * @@ -42,13 +42,6 @@ __BEGIN_DECLS 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 diff --git a/SystemConfiguration.fproj/SCNetworkSignaturePrivate.h b/SystemConfiguration.fproj/SCNetworkSignaturePrivate.h index 55219f0..1486b5c 100644 --- a/SystemConfiguration.fproj/SCNetworkSignaturePrivate.h +++ b/SystemConfiguration.fproj/SCNetworkSignaturePrivate.h @@ -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@ * @@ -24,14 +24,6 @@ #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 */ diff --git a/SystemConfiguration.fproj/SCPCommit.c b/SystemConfiguration.fproj/SCPCommit.c index 6f193c1..6418cfc 100644 --- a/SystemConfiguration.fproj/SCPCommit.c +++ b/SystemConfiguration.fproj/SCPCommit.c @@ -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@ * @@ -60,6 +60,13 @@ __SCPreferencesCommitChanges_helper(SCPreferencesRef prefs) 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; } } diff --git a/SystemConfiguration.fproj/SCPOpen.c b/SystemConfiguration.fproj/SCPOpen.c index 7558a9e..125ba24 100644 --- a/SystemConfiguration.fproj/SCPOpen.c +++ b/SystemConfiguration.fproj/SCPOpen.c @@ -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@ * @@ -48,6 +48,7 @@ #include #include +#include #include #include @@ -84,7 +85,7 @@ __SCPreferencesCopyDescription(CFTypeRef cf) { 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("}")); @@ -209,6 +210,7 @@ __SCPreferencesCreatePrivate(CFAllocatorRef allocator) prefsPrivate->changed = FALSE; prefsPrivate->isRoot = (geteuid() == 0); prefsPrivate->authorizationData = NULL; + prefsPrivate->authorizationRequired = FALSE; prefsPrivate->helper_port = MACH_PORT_NULL; return prefsPrivate; @@ -355,7 +357,7 @@ __SCPreferencesAccess_helper(SCPreferencesRef prefs) } if ((serverPrefs == NULL) || (serverSignature == NULL)) { - CFRelease(serverDict); + if (serverDict != NULL) CFRelease(serverDict); goto fail; } @@ -390,7 +392,6 @@ __SCPreferencesCreate(CFAllocatorRef allocator, CFDataRef authorizationData, CFDictionaryRef options) { - int fd = -1; SCPreferencesPrivateRef prefsPrivate; int sc_status = kSCStatusOK; @@ -426,87 +427,90 @@ __SCPreferencesCreate(CFAllocatorRef allocator, 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; - 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); - return prefsPrivate; + return NULL; - error : + done : - if (fd != -1) (void) close(fd); - CFRelease(prefsPrivate); + /* all OK */ _SCErrorSet(sc_status); - return NULL; + return prefsPrivate; } __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; } - 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) { @@ -518,6 +522,7 @@ __SCPreferencesAccess(SCPreferencesRef prefs) case ENOENT : /* no preference data, start fresh */ break; + case EPERM : 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) { - CFDataRef authorizationRefData; + CFDataRef data; AuthorizationExternalForm extForm; OSStatus os_status; @@ -684,11 +689,11 @@ SCPreferencesCreateWithOptions(CFAllocatorRef allocator, 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, - authorizationRefData); - CFRelease(authorizationRefData); + data); + CFRelease(data); } #endif @@ -860,7 +865,7 @@ SCPreferencesSetCallback(SCPreferencesRef prefs, (*prefsPrivate->rlsContext.release)(prefsPrivate->rlsContext.info); } - prefsPrivate->rlsFunction = callout; + prefsPrivate->rlsFunction = callout; prefsPrivate->rlsContext.info = NULL; prefsPrivate->rlsContext.retain = NULL; prefsPrivate->rlsContext.release = NULL; diff --git a/SystemConfiguration.fproj/SCPPath.c b/SystemConfiguration.fproj/SCPPath.c index bd94742..a9489ff 100644 --- a/SystemConfiguration.fproj/SCPPath.c +++ b/SystemConfiguration.fproj/SCPPath.c @@ -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@ * @@ -379,6 +379,8 @@ SCPreferencesPathCreateUniqueChild(SCPreferencesRef prefs, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + assert(newDict != NULL); + if (!setPath(prefs, newPath, newDict)) { CFRelease(newPath); newPath = NULL; diff --git a/SystemConfiguration.fproj/SCPreferencesInternal.h b/SystemConfiguration.fproj/SCPreferencesInternal.h index aca0a16..f4ab7da 100644 --- a/SystemConfiguration.fproj/SCPreferencesInternal.h +++ b/SystemConfiguration.fproj/SCPreferencesInternal.h @@ -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@ * @@ -100,6 +100,7 @@ typedef struct { /* authorization, helper */ CFDataRef authorizationData; + Boolean authorizationRequired; mach_port_t helper_port; } SCPreferencesPrivate, *SCPreferencesPrivateRef; diff --git a/SystemConfiguration.fproj/SCPreferencesPrivate.h b/SystemConfiguration.fproj/SCPreferencesPrivate.h index 2690e17..303ffdd 100644 --- a/SystemConfiguration.fproj/SCPreferencesPrivate.h +++ b/SystemConfiguration.fproj/SCPreferencesPrivate.h @@ -35,9 +35,33 @@ @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 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 diff --git a/SystemConfiguration.fproj/SCPrivate.h b/SystemConfiguration.fproj/SCPrivate.h index 509c59e..6846033 100644 --- a/SystemConfiguration.fproj/SCPrivate.h +++ b/SystemConfiguration.fproj/SCPrivate.h @@ -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@ * @@ -61,6 +61,14 @@ */ +/* "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++); @@ -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 */ +/* 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 @@ -104,23 +126,6 @@ extern int _sc_log; /* 0 if SC messages should be written to stdout/stderr, */ #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 @@ -128,6 +133,7 @@ extern int _sc_log; /* 0 if SC messages should be written to stdout/stderr, */ #define kSCNetworkReachabilityOptionInterface CFSTR("interface") + /*! @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") -/*! - @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 @@ -158,6 +156,9 @@ extern int _sc_log; /* 0 if SC messages should be written to stdout/stderr, */ #define kSCNetworkReachabilityOptionServerBypass CFSTR("ServerBypass") + + + /*! @group */ @@ -404,7 +405,57 @@ void SCLog (Boolean condition, 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. @@ -426,6 +477,8 @@ void SCLOG (aslclient asl, ...); +#endif + /*! @function SCPrint @discussion Conditionally issue a debug message. @@ -440,6 +493,8 @@ void SCPrint (Boolean condition, CFStringRef formatString, ...); + + /*! @function SCTrace @discussion Conditionally issue a debug message with a time stamp. @@ -454,6 +509,35 @@ void SCTrace (Boolean condition, 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 @@ -479,6 +563,29 @@ SCNetworkProxiesCopyMatching (CFDictionaryRef globalConfiguration, 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 @@ -546,9 +653,9 @@ _SC_checkResolverReachabilityByAddress (SCDynamicStoreRef *storeP, int SCNetworkReachabilityGetInterfaceIndex (SCNetworkReachabilityRef target); + #pragma mark - #pragma mark Domain - /*! @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); +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 */ diff --git a/SystemConfiguration.fproj/SCProxies.c b/SystemConfiguration.fproj/SCProxies.c index b041e3c..9fe060d 100644 --- a/SystemConfiguration.fproj/SCProxies.c +++ b/SystemConfiguration.fproj/SCProxies.c @@ -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@ * @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -62,8 +63,7 @@ validate_proxy_content(CFMutableDictionaryRef proxies, 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); - 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; + int s_port = 0; 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; - int s_port; 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); +static void +normalize_services_proxy(const void *key, 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; + CFDictionaryRef services; CFArrayRef supplemental; if (!isA_CFDictionary(proxy)) { @@ -213,6 +230,13 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy) NULL, 0); + validate_proxy_content(newProxy, + kSCPropNetProxiesFallBackAllowed, + NULL, + NULL, + NULL, + 0); + // validate FTP passive setting num = CFDictionaryGetValue(newProxy, kSCPropNetProxiesFTPPassive); if (num != NULL) { @@ -286,6 +310,22 @@ __SCNetworkProxiesCopyNormalized(CFDictionaryRef proxy) 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)) { @@ -323,6 +363,19 @@ normalize_scoped_proxy(const void *key, const void *value, void *context) 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) @@ -337,13 +390,35 @@ normalize_supplemental_proxy(const void *value, void *context) return; } - 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; + 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 */ @@ -376,11 +451,14 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef globalConfiguration, 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 @@ -428,6 +506,49 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef globalConfiguration, 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; @@ -523,6 +644,7 @@ SCNetworkProxiesCopyMatching(CFDictionaryRef globalConfiguration, newProxy = CFDictionaryCreateMutableCopy(NULL, 0, globalConfiguration); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesScoped); + CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesServices); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplemental); proxies = CFArrayCreate(NULL, (const void **)&newProxy, 1, &kCFTypeArrayCallBacks); CFRelease(newProxy); diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.c b/SystemConfiguration.fproj/SCSchemaDefinitions.c index 583307d..4df5ad6 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitions.c +++ b/SystemConfiguration.fproj/SCSchemaDefinitions.c @@ -61,7 +61,9 @@ const CFStringRef kSCEntNetSMB = CFSTR("SMB" const CFStringRef kSCEntNet6to4 = CFSTR("6to4"); +const CFStringRef kSCEntNetAppLayer = CFSTR("AppLayer"); 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"); @@ -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 kSCPropNetDNSServiceIdentifier = CFSTR("ServiceIdentifier"); +const CFStringRef kSCPropNetDNSSupplementalMatchDomainsNoSearch = CFSTR("SupplementalMatchDomainsNoSearch"); 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 kSCPropNetIPSecDisconnectOnWake = CFSTR("DisconnectOnWake"); +const CFStringRef kSCPropNetIPSecDisconnectOnWakeTimer = CFSTR("DisconnectOnWakeTimer"); 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 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"); @@ -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 kSCPropNetPPPDisconnectOnWake = CFSTR("DisconnectOnWake"); +const CFStringRef kSCPropNetPPPDisconnectOnWakeTimer = CFSTR("DisconnectOnWakeTimer"); 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 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 kSCPropNetProxiesServices = CFSTR("__SERVICES__"); 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 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 kSCPropNetVPNAuthPasswordPluginType = CFSTR("AuthPasswordPluginType"); 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 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 kSCPropNetVPNOnDemandMatchAppEnabled = CFSTR("OnDemandMatchAppEnabled"); 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 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 kSCValNetVPNAuthPasswordEncryptionExternal = CFSTR("External"); 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"); diff --git a/SystemConfiguration.fproj/SCSchemaDefinitions.h b/SystemConfiguration.fproj/SCSchemaDefinitions.h index 22e2b0b..af6f711 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitions.h +++ b/SystemConfiguration.fproj/SCSchemaDefinitions.h @@ -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@ * @@ -95,26 +95,6 @@ * * 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 @@ -806,79 +786,79 @@ extern const CFStringRef kSCPropNetLocalHostName; /*! @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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 - @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; @@ -2375,6 +2355,7 @@ extern const CFStringRef kSCPropUsersConsoleUserGID; /* -------------------- 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 \ @@ -2652,79 +2633,79 @@ extern const CFStringRef kSCPropUsersConsoleUserGID; ,"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) ) - 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 ) - 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 ) - 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 ) - 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) ) - 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 ) - 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) ) - 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" \ , ) - 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" \ , ) - 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" \ , ) - 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" \ , ) - 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" \ , ) - 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" \ diff --git a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h index ee3ca28..509be00 100644 --- a/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h +++ b/SystemConfiguration.fproj/SCSchemaDefinitionsPrivate.h @@ -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@ * @@ -34,7 +34,9 @@ * Network Entity Keys * * kSCEntNetCommCenter "com.apple.CommCenter" CFDictionary + * kSCEntNetAppLayer "AppLayer" CFDictionary * kSCEntNetEAPOL "EAPOL" CFDictionary + * kSCEntNetLinkIssues "LinkIssues" CFDictionary * kSCEntNetLinkQuality "LinkQuality" CFDictionary * kSCEntNetLoopback "Loopback" CFDictionary * kSCEntNetOnDemand "OnDemand" CFDictionary @@ -50,6 +52,11 @@ * 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) @@ -69,6 +76,8 @@ * kSCValNetInterfaceTypeLoopback "Loopback" * kSCValNetInterfaceTypeVPN "VPN" * + * kSCPropNetIPSecDisconnectOnWake "DisconnectOnWake" CFNumber (0 or 1) + * kSCPropNetIPSecDisconnectOnWakeTimer "DisconnectOnWakeTimer" CFNumber * kSCEntNetIPSec Entity Keys * * kSCPropNetIPSecLastCause "LastCause" CFNumber @@ -105,10 +114,18 @@ * kSCPropNetIPv6RoutePrefixLength "PrefixLength" CFNumber * kSCPropNetIPv6RouteGatewayAddress "GatewayAddress" CFString * + * kSCEntNetLinkIssues Entity Keys + * + * kSCPropNetLinkIssuesModuleID "ModuleID" CFData + * kSCPropNetLinkIssuesInfo "Info" CFData + * kSCPropNetLinkIssuesTimeStamp "TimeStamp" CFDATE + * * kSCEntNetLinkQuality Entity Keys * * kSCPropNetLinkQuality "LinkQuality" CFNumber * + * kSCPropNetPPPDisconnectOnWake "DisconnectOnWake" CFNumber (0 or 1) + * kSCPropNetPPPDisconnectOnWakeTimer "DisconnectOnWakeTimer" CFNumber * kSCEntNetPPP Entity Keys * * --- OnDemand: --- @@ -133,10 +150,13 @@ * * 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 + * kSCPropNetProxiesServices "__SERVICES__" CFDictionary * kSCPropNetProxiesSupplemental "__SUPPLEMENTAL__" CFArray[CFDictionary] * kSCPropNetProxiesSupplementalMatchDomain "__MATCH_DOMAIN__" CFString * @@ -152,9 +172,12 @@ * * kSCEntNetVPN Entity Keys * + * kSCPropNetVPNAppRules "AppRules" CFArray[CFDictionary] + * kSCPropNetVPNAuthCredentialPassword "AuthCredentialPassword" 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) @@ -162,25 +185,77 @@ * 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) + * kSCPropNetVPNOnDemandMatchAppEnabled "OnDemandMatchAppEnabled" CFBoolean * 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) * + * --- 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 --- + * kSCValNetVPNAuthPasswordEncryptionExternal "External" * 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 @@ -236,12 +311,24 @@ extern const CFStringRef kSCPrefVirtualNetworkInterfaces; */ 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 kSCEntNetLinkIssues + @availability Introduced in Mac OS X 10.9. + */ +extern const CFStringRef kSCEntNetLinkIssues; + /*! @const kSCEntNetLinkQuality @availability Introduced in Mac OS X 10.7. @@ -298,6 +385,22 @@ extern const CFStringRef kSCPropNetCommCenterAllowNetworkAccess; */ 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 */ @@ -378,6 +481,18 @@ extern const CFStringRef kSCValNetInterfaceTypeLoopback; */ 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 */ @@ -498,6 +613,28 @@ extern const CFStringRef kSCPropNetIPv6RoutePrefixLength; */ 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 */ @@ -508,6 +645,18 @@ extern const CFStringRef kSCPropNetIPv6RouteGatewayAddress; */ 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 */ @@ -600,6 +749,18 @@ extern const CFStringRef kSCValNetPPPOnDemandPriorityLow; @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. @@ -618,6 +779,12 @@ extern const CFStringRef kSCPropNetProxiesSupplementalMatchOrders; */ 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. @@ -668,6 +835,18 @@ extern const CFStringRef kSCValNetServicePrimaryRankNever; @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. @@ -686,6 +865,12 @@ extern const CFStringRef kSCPropNetVPNAuthPassword; */ 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. @@ -728,6 +913,18 @@ extern const CFStringRef kSCPropNetVPNDisconnectOnLogout; */ 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. @@ -752,6 +949,12 @@ extern const CFStringRef kSCPropNetVPNMTU; */ 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. @@ -770,6 +973,24 @@ extern const CFStringRef kSCPropNetVPNOnDemandMatchDomainsOnRetry; */ 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. @@ -788,6 +1009,42 @@ extern const CFStringRef kSCPropNetVPNStatus; */ 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. @@ -800,6 +1057,12 @@ extern const CFStringRef kSCValNetVPNAuthenticationMethodPassword; */ 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. @@ -812,6 +1075,144 @@ extern const CFStringRef kSCValNetVPNAuthPasswordEncryptionKeychain; */ 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 */ @@ -893,12 +1294,24 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,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(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 \ @@ -936,6 +1349,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,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 \ @@ -1008,6 +1433,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1116,12 +1553,42 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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(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 \ @@ -1206,6 +1673,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1224,6 +1703,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"__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 \ @@ -1266,6 +1751,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1284,6 +1781,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1326,6 +1829,18 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1350,6 +1865,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1368,6 +1889,24 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1386,6 +1925,42 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1398,6 +1973,12 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ @@ -1410,6 +1991,139 @@ extern const CFStringRef kSCPropVirtualNetworkInterfacesVLANOptions; ,"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 \ diff --git a/SystemConfiguration.fproj/SNHelper.c b/SystemConfiguration.fproj/SNHelper.c new file mode 100644 index 0000000..4ae0fd9 --- /dev/null +++ b/SystemConfiguration.fproj/SNHelper.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013 Apple Inc. + * All rights reserved. + */ +#include +#include +#include + +#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 index 0000000..4d2aefb --- /dev/null +++ b/SystemConfiguration.fproj/SNHelperPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013 Apple Inc. + * All rights reserved. + */ + +#ifndef __SYSTEMCONFIGURATION_SNHELPER_PRIVATE_H__ +#define __SYSTEMCONFIGURATION_SNHELPER_PRIVATE_H__ + +#include + +#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__ */ diff --git a/SystemConfiguration.fproj/SystemConfiguration.h b/SystemConfiguration.fproj/SystemConfiguration.h index a1337bd..9cb4bc2 100644 --- a/SystemConfiguration.fproj/SystemConfiguration.h +++ b/SystemConfiguration.fproj/SystemConfiguration.h @@ -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@ * @@ -109,6 +109,9 @@ enum { 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) + */ }; diff --git a/SystemConfiguration.fproj/VLANConfiguration.c b/SystemConfiguration.fproj/VLANConfiguration.c index a73c910..dc07360 100644 --- a/SystemConfiguration.fproj/VLANConfiguration.c +++ b/SystemConfiguration.fproj/VLANConfiguration.c @@ -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@ * @@ -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); + assert(vlan != NULL); // 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); @@ -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) { @@ -299,6 +190,22 @@ findVLANInterfaceAndTag(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, #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) { @@ -315,20 +222,10 @@ SCVLANInterfaceCopyAll(SCPreferencesRef prefs) kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN); dict = SCPreferencesPathGetValue(prefs, path); + CFRelease(path); 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; } @@ -481,6 +378,7 @@ _SCVLANInterfaceCopyActive(void) // 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 @@ -488,10 +386,12 @@ _SCVLANInterfaceCopyActive(void) 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); + assert(vlan_tag != NULL); SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan, vlan_physical, vlan_tag); CFRelease(vlan_physical); @@ -504,7 +404,9 @@ _SCVLANInterfaceCopyActive(void) done : - (void) close(s); + if (s != -1) { + (void) close(s); + } freeifaddrs(ifap); return vlans; } @@ -564,7 +466,7 @@ SCVLANInterfaceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef physical, CF 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("/%@/%@/%@"), @@ -757,7 +659,9 @@ SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan, SCNetworkInte 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); } @@ -827,7 +731,9 @@ SCVLANInterfaceSetLocalizedDisplayName(SCVLANInterfaceRef vlan, CFStringRef newN } else { CFDictionaryRemoveValue(newDict, kSCPropUserDefinedName); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } @@ -889,7 +795,9 @@ SCVLANInterfaceSetOptions(SCVLANInterfaceRef vlan, CFDictionaryRef newOptions) } else { CFDictionaryRemoveValue(newDict, kSCPropVirtualNetworkInterfacesVLANOptions); } - ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + if (!CFEqual(dict, newDict)) { + ok = SCPreferencesPathSetValue(interfacePrivate->prefs, path, newDict); + } CFRelease(newDict); CFRelease(path); } diff --git a/SystemConfiguration.fproj/VPNAppLayer.c b/SystemConfiguration.fproj/VPNAppLayer.c new file mode 100644 index 0000000..01901ca --- /dev/null +++ b/SystemConfiguration.fproj/VPNAppLayer.c @@ -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 index 0000000..01901ca --- /dev/null +++ b/SystemConfiguration.fproj/VPNAppLayerPrivate.h @@ -0,0 +1,5 @@ +/* + * Copyright (c) 2012, 2013 Apple Inc. + * All rights reserved. + */ + diff --git a/SystemConfiguration.fproj/VPNConfiguration.c b/SystemConfiguration.fproj/VPNConfiguration.c index 4e587a2..58acb55 100644 --- a/SystemConfiguration.fproj/VPNConfiguration.c +++ b/SystemConfiguration.fproj/VPNConfiguration.c @@ -1,4 +1,4 @@ /* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. */ diff --git a/SystemConfiguration.fproj/VPNConfiguration.h b/SystemConfiguration.fproj/VPNConfiguration.h index 4e587a2..d7d8fa0 100644 --- a/SystemConfiguration.fproj/VPNConfiguration.h +++ b/SystemConfiguration.fproj/VPNConfiguration.h @@ -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 index 0000000..d286c3d --- /dev/null +++ b/SystemConfiguration.fproj/VPNFlow.c @@ -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 index 0000000..d286c3d --- /dev/null +++ b/SystemConfiguration.fproj/VPNFlow.h @@ -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 index 0000000..a24886f --- /dev/null +++ b/SystemConfiguration.fproj/VPNFlowPrivate.h @@ -0,0 +1,4 @@ +/* + * Copyright (c) 2012, 2013 Apple Inc. All rights reserved. + */ + diff --git a/SystemConfiguration.fproj/VPNPrivate.c b/SystemConfiguration.fproj/VPNPrivate.c index 2dfbed3..b4b9a4b 100644 --- a/SystemConfiguration.fproj/VPNPrivate.c +++ b/SystemConfiguration.fproj/VPNPrivate.c @@ -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 index 0000000..8be02b4 --- /dev/null +++ b/SystemConfiguration.fproj/VPNService.c @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2012, 2013 Apple Inc. All rights reserved. + */ + +#include +#include + +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; +} + diff --git a/SystemConfiguration.fproj/VPNTunnel.c b/SystemConfiguration.fproj/VPNTunnel.c index 4e587a2..58acb55 100644 --- a/SystemConfiguration.fproj/VPNTunnel.c +++ b/SystemConfiguration.fproj/VPNTunnel.c @@ -1,4 +1,4 @@ /* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. */ diff --git a/SystemConfiguration.fproj/VPNTunnel.h b/SystemConfiguration.fproj/VPNTunnel.h index 4e587a2..58acb55 100644 --- a/SystemConfiguration.fproj/VPNTunnel.h +++ b/SystemConfiguration.fproj/VPNTunnel.h @@ -1,4 +1,4 @@ /* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. */ diff --git a/SystemConfiguration.fproj/VPNTunnelPrivate.h b/SystemConfiguration.fproj/VPNTunnelPrivate.h index 4e587a2..58acb55 100644 --- a/SystemConfiguration.fproj/VPNTunnelPrivate.h +++ b/SystemConfiguration.fproj/VPNTunnelPrivate.h @@ -1,4 +1,4 @@ /* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. + * Copyright (c) 2009-2013 Apple Inc. All rights reserved. */ diff --git a/SystemConfiguration.fproj/config_types.h b/SystemConfiguration.fproj/config_types.h index a3a63ca..fb93019 100644 --- a/SystemConfiguration.fproj/config_types.h +++ b/SystemConfiguration.fproj/config_types.h @@ -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@ * @@ -41,7 +41,12 @@ /* * Mach server port name */ +#if !TARGET_IPHONE_SIMULATOR #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, ... diff --git a/SystemConfiguration.fproj/dy_framework.c b/SystemConfiguration.fproj/dy_framework.c index 9366fe4..e2c1089 100644 --- a/SystemConfiguration.fproj/dy_framework.c +++ b/SystemConfiguration.fproj/dy_framework.c @@ -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@ * @@ -37,7 +37,6 @@ #include "dy_framework.h" - #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, kSecGuestAttributePid) +SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecCodeInfoIdentifier) +SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecCodeInfoUnique) __private_extern__ OSStatus _AuthorizationMakeExternalForm(AuthorizationRef authorization, AuthorizationExternalForm *extForm) @@ -565,3 +567,4 @@ _SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data) return dyfunc ? dyfunc(allocator, data) : NULL; } + diff --git a/SystemConfiguration.fproj/dy_framework.h b/SystemConfiguration.fproj/dy_framework.h index 3cd5bd8..0faee13 100644 --- a/SystemConfiguration.fproj/dy_framework.h +++ b/SystemConfiguration.fproj/dy_framework.h @@ -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@ * @@ -204,6 +204,15 @@ CFTypeRef _kSecMatchSearchList(); CFTypeRef _kSecReturnRef(); #define kSecReturnRef _kSecReturnRef() +CFTypeRef _kSecGuestAttributePid(); +#define kSecGuestAttributePid _kSecGuestAttributePid() + +CFTypeRef _kSecCodeInfoIdentifier(); +#define kSecCodeInfoIdentifier _kSecCodeInfoIdentifier() + +CFTypeRef _kSecCodeInfoUnique(); +#define kSecCodeInfoUnique _kSecCodeInfoUnique() + OSStatus _AuthorizationMakeExternalForm ( AuthorizationRef authorization, @@ -355,6 +364,8 @@ _SecCertificateCreateWithData ( ); #define SecCertificateCreateWithData _SecCertificateCreateWithData + + __END_DECLS #endif // _DY_FRAMEWORK_H diff --git a/SystemConfiguration.fproj/genSCPreferences.c b/SystemConfiguration.fproj/genSCPreferences.c index 5cff797..69114d5 100644 --- a/SystemConfiguration.fproj/genSCPreferences.c +++ b/SystemConfiguration.fproj/genSCPreferences.c @@ -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@ * @@ -59,7 +59,7 @@ 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" @@ -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_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, @@ -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_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, @@ -141,14 +148,18 @@ typedef enum { #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 APP "App" #define ARP "ARP" #define ACCESSPOINTNAME "AccessPointName" +#define ACCOUNT "Account" #define ACSP "ACSP" // Apple Client Server Protocol +#define ACTION "Action" #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 ALLOW "Allow" +#define ALLOWED "Allowed" #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 BYPASS "Bypass" #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" @@ -187,6 +202,7 @@ typedef enum { #define COMPRESSIONVJ "CompressionVJ" #define COMPUTERNAME "ComputerName" #define CONFIGMETHOD "ConfigMethod" +#define CONNECT "Connect" #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 CREDENTIAL "Credential" #define CURRENTSET "CurrentSet" #define DATACOMPRESSION "DataCompression" #define DEFAULT "Default" #define DEFAULTZONE "DefaultZone" +#define DESIGNATED "Designated" #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 DISCONNECT "Disconnect" #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" @@ -229,10 +250,14 @@ typedef enum { #define ENCRYPTION "Encryption" #define ERRORCORRECTION "ErrorCorrection" #define ETHERNET "Ethernet" +#define EVALUATE "Evaluate" #define EXCEPTIONSLIST "ExceptionsList" #define EXCLUDED "Excluded" #define EXCLUDESIMPLEHOSTNAMES "ExcludeSimpleHostnames" +#define EXECUTABLE "Executable" +#define EXTERNAL "External" #define FAILOVER "Failover" +#define FALLBACK "FallBack" #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 IDENTIFIER "Identifier" #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 INFO "Info" #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 LAYER "Layer" #define LCP "LCP" #define LINK "Link" +#define LINKISSUES "LinkIssues" #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 MODULEID "ModuleID" #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 NO "No" #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 PARAMETERS "Parameters" #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 PROBE "Probe" #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 REQUIRED "Required" +#define REQUIREMENT "Requirement" #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 RULE "Rule" +#define RULES "Rules" #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 SERVERS "Servers" #define SERVICE "Service" +#define SERVICES "Services" #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 SSID "SSID" #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 SUSPENDED "Suspended" #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" @@ -415,6 +460,7 @@ typedef enum { #define VLAN_MTU "VLAN_MTU" #define VPN "VPN" #define WAITFORDIALTONE "WaitForDialTone" +#define WIFI "WiFi" #define WINS "WINS" #define WORKGROUP "Workgroup" #define XAUTH "XAuth" @@ -505,7 +551,9 @@ static schemaDefinition names[] = { { 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_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 }, @@ -525,36 +573,36 @@ static schemaDefinition names[] = { { 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 }, - { 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 }, - { 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 }, @@ -591,6 +639,12 @@ static schemaDefinition names[] = { { 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 }, @@ -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_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 }, @@ -765,6 +821,13 @@ static schemaDefinition names[] = { { 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}, @@ -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_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 }, @@ -982,10 +1047,13 @@ static schemaDefinition names[] = { { 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_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 }, @@ -1020,9 +1088,12 @@ static schemaDefinition names[] = { { 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_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 }, @@ -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_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_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_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 }, + { 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 }, + { 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 }, + { 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 }, @@ -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_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"); @@ -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_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; @@ -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_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); @@ -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_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; @@ -1350,11 +1512,12 @@ dump_names(int type) 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"); + } break; default: break; @@ -1365,11 +1528,12 @@ dump_names(int type) 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"); + } 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_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: @@ -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_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; @@ -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_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: @@ -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_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; @@ -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_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; @@ -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_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; @@ -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_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 @@ -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_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; @@ -1707,6 +1897,8 @@ main(int argc, char * argv[]) printf("#endif\t/* 0 */\n\n\n"); printf("/* -------------------- Schema declarations -------------------- */\n\n"); + + dump_names(gen_hfile_e); printf("\n"); diff --git a/SystemConfiguration.fproj/helper/SCHelper_server.c b/SystemConfiguration.fproj/helper/SCHelper_server.c index ad83e9c..01fd485 100644 --- a/SystemConfiguration.fproj/helper/SCHelper_server.c +++ b/SystemConfiguration.fproj/helper/SCHelper_server.c @@ -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@ * @@ -45,6 +45,8 @@ #include "SCHelper_client.h" #include "helper_types.h" +#include + #pragma mark - #pragma mark SCHelper session managment @@ -53,6 +55,7 @@ // // 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") // @@ -84,10 +87,13 @@ typedef struct { audit_token_t auditToken; // write access entitlement associated with this session + lazyBoolean callerReadAccess; 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; @@ -119,7 +125,7 @@ static pthread_mutex_t sessions_lock = PTHREAD_MUTEX_INITIALIZER; #pragma mark Helper session management -#if !TARGET_OS_IPHONE +#if !TARGET_OS_IPHONE static Boolean __SCHelperSessionUseEntitlement(SCHelperSessionRef session) { @@ -127,7 +133,7 @@ static Boolean return sessionPrivate->use_entitlement; } -#endif //!TARGET_OS_IPHONE +#endif //!TARGET_OS_IPHONE static AuthorizationRef @@ -145,25 +151,31 @@ __SCHelperSessionSetAuthorization(SCHelperSessionRef session, CFTypeRef authoriz 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) { -#if !TARGET_OS_IPHONE +#if !TARGET_OS_IPHONE if (!__SCHelperSessionUseEntitlement(session)) { AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDefaults); // AuthorizationFree(sessionPrivate->authorization, kAuthorizationFlagDestroyRights); - sessionPrivate->authorization = NULL; } else { -#endif //!TARGET_OS_IPHONE 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; } -#if !TARGET_OS_IPHONE +#if !TARGET_OS_IPHONE if (isA_CFData(authorizationData)) { AuthorizationExternalForm extForm; @@ -181,13 +193,16 @@ __SCHelperSessionSetAuthorization(SCHelperSessionRef session, CFTypeRef authoriz 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; } +#endif //!TARGET_OS_IPHONE 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; - return sessionPrivate->vpnFilter; + pthread_mutex_lock(&sessionPrivate->lock); + + sessionPrivate->isSetChange = setChange ? YES : NO; + + pthread_mutex_unlock(&sessionPrivate->lock); + + return; } 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); - 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); @@ -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) { @@ -387,7 +429,7 @@ __SCHelperSessionCopyDescription(CFTypeRef cf) 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)); } @@ -413,8 +455,9 @@ __SCHelperSessionDeallocate(CFTypeRef cf) // 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); @@ -469,8 +512,11 @@ __SCHelperSessionCreate(CFAllocatorRef allocator) sessionPrivate->use_entitlement = FALSE; sessionPrivate->port = MACH_PORT_NULL; sessionPrivate->mp = NULL; + sessionPrivate->callerReadAccess = UNKNOWN; sessionPrivate->callerWriteAccess = UNKNOWN; - sessionPrivate->vpnFilter = NULL; + sessionPrivate->isSetChange = UNKNOWN; + sessionPrivate->isVPNChange = UNKNOWN; + sessionPrivate->vpnTypes = 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; -#if !TARGET_OS_IPHONE +#if !TARGET_OS_IPHONE CFDataRef authorizationData = NULL; #endif Boolean ok = FALSE; @@ -644,19 +690,23 @@ do_Auth(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t *status return FALSE; } - if (isA_CFDictionary(authorizationDict) == FALSE) { + if (authorizationDict == NULL) { + return FALSE; + } + + if (!isA_CFDictionary(authorizationDict)) { 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 { - CFStringRef authorizationInfo; + CFStringRef 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; - CFArrayRef vpnFilter; + Boolean useSetFilter; + Boolean useVPNFilter; + CFArrayRef vpnTypes = NULL; 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; + 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; - CFRange range = CFRangeMake(0, CFArrayGetCount(vpnFilter)); for (c = 0; c < 2; c++) { - CFArrayRef services; switch (c) { case 0 : @@ -1165,41 +1219,49 @@ do_prefs_Commit(SCHelperSessionRef session, void *info, CFDataRef data, uint32_t 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) { @@ -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) { @@ -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) { @@ -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 -hasAuthorization(SCHelperSessionRef session) +isVPNChange(SCHelperSessionRef session) { - AuthorizationRef authorization = __SCHelperSessionGetAuthorization(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 !TARGET_OS_IPHONE +#if !TARGET_OS_IPHONE 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; - flags |= kAuthorizationFlagExtendRights; flags |= kAuthorizationFlagInteractionAllowed; + flags |= kAuthorizationFlagExtendRights; // flags |= kAuthorizationFlagPartialRights; // flags |= kAuthorizationFlagPreAuthorize; @@ -1447,81 +1666,48 @@ hasAuthorization(SCHelperSessionRef session) 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)); + 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; + Boolean needsWrite; 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 - { 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 - { SCHELPER_MSG_EXIT, "EXIT", FALSE, do_Exit , NULL } + { SCHELPER_MSG_EXIT, "EXIT", FALSE, FALSE, do_Exit , NULL } }; #define nHELPERS (sizeof(helpers)/sizeof(struct helper)) @@ -1587,6 +1774,9 @@ newHelper(void *arg) SCHelperSessionRef session = (SCHelperSessionRef)arg; SCHelperSessionPrivateRef sessionPrivate = (SCHelperSessionPrivateRef)session; + assert(session != NULL); + assert(sessionPrivate->mp != NULL); + __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; + 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 @@ -1800,7 +1994,11 @@ helperCallback(CFMachPortRef port, void *msg, CFIndex size, void *info) 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); @@ -1845,6 +2043,7 @@ _helperinit(mach_port_t server, } session = __SCHelperSessionCreate(NULL); + assert(session != NULL); sessionPrivate = (SCHelperSessionPrivateRef)session; // create per-session port @@ -1853,6 +2052,12 @@ _helperinit(mach_port_t server, &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 @@ -1978,7 +2183,8 @@ _helperexec(mach_port_t server, 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, diff --git a/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist b/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist index abf8095..bafb82f 100644 --- a/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist +++ b/SystemConfiguration.fproj/helper/com.apple.SCHelper-embedded.plist @@ -11,5 +11,7 @@ com.apple.SystemConfiguration.helper + POSIXSpawnType + Adaptive diff --git a/SystemConfiguration.fproj/helper/com.apple.SCHelper.plist b/SystemConfiguration.fproj/helper/com.apple.SCHelper.plist index ee55286..b6612a4 100644 --- a/SystemConfiguration.fproj/helper/com.apple.SCHelper.plist +++ b/SystemConfiguration.fproj/helper/com.apple.SCHelper.plist @@ -5,11 +5,13 @@ Label com.apple.SCHelper Program - /System/Library/Frameworks/SystemConfiguration.framework/Resources/SCHelper + /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/Helpers/SCHelper MachServices com.apple.SystemConfiguration.helper + POSIXSpawnType + Adaptive diff --git a/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_client.c b/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_client.c index 09c0ea6..13196ea 100644 --- a/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_client.c +++ b/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_client.c @@ -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@ * @@ -30,23 +30,13 @@ #include #include - -#include "rb.h" +#include #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; @@ -70,50 +60,48 @@ log_xpc_object(const char *msg, xpc_object_t obj) typedef struct { - struct rb_node rbn; + rb_node_t rbn; SCNetworkReachabilityRef target; } reach_request_t; -#define RBNODE_TO_REACH_REQUEST(node) \ - ((reach_request_t *)((uintptr_t)node - offsetof(reach_request_t, rbn))) - - 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 -_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); } -static struct rb_tree * +static rb_tree_t * _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_node_offset = offsetof(reach_request_t, rbn), + .rbto_context = NULL }; - static struct rb_tree rbtree; + static rb_tree_t rbt; 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, ^{ - q = dispatch_queue_create(REACH_SERVICE_NAME ".rbt", NULL); + q = dispatch_queue_create(REACH_SERVICE_NAME ".requests.rbt", NULL); }); return q; @@ -161,14 +149,13 @@ _reach_request_add(SCNetworkReachabilityRef target) 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); - if (request == NULL || !rb_tree_insert_node(_reach_requests_rbt(), &request->rbn)) { + if (request == NULL || !rb_tree_insert_node(rbt, request)) { __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? - 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); } }); + + return; } @@ -204,12 +191,12 @@ _reach_request_copy_target(uint64_t target_id) __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); } }); @@ -233,7 +220,7 @@ handle_reachability_status(SCNetworkReachabilityRef target, xpc_object_t dict) // log_xpc_object(" status", dict); } - __SCNetworkReachabilityPerformNoLock(target); + __SCNetworkReachabilityPerformConcurrent(target); return; } @@ -284,6 +271,11 @@ static xpc_connection_t _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(); @@ -293,9 +285,7 @@ _reach_connection_create() 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; @@ -316,14 +306,18 @@ _reach_connection_create() 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; } - 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) { @@ -403,7 +397,7 @@ add_proc_name(xpc_object_t reqdict) 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 @@ -427,11 +421,6 @@ _reach_server_target_add(xpc_connection_t connection, SCNetworkReachabilityRef t 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, @@ -444,12 +433,6 @@ _reach_server_target_add(xpc_connection_t connection, SCNetworkReachabilityRef t 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, @@ -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); @@ -549,9 +533,9 @@ _reach_server_target_remove(xpc_connection_t connection, SCNetworkReachabilityRe 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 : { @@ -619,9 +603,9 @@ _reach_server_target_schedule(xpc_connection_t connection, SCNetworkReachability 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 : { @@ -655,7 +639,7 @@ _reach_server_target_schedule(xpc_connection_t connection, SCNetworkReachability if (retry) { // reconnect - _reach_server_target_reconnect(connection, target); + _reach_server_target_reconnect(connection, target, FALSE); // and retry retry = FALSE; @@ -671,8 +655,9 @@ static void _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, @@ -702,20 +687,20 @@ _reach_reply_set_reachability(SCNetworkReachabilityRef target, 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 ((targetPrivate->resolvedAddressError == 0) && (addresses != NULL)) { + if ((targetPrivate->resolvedError == NETDB_SUCCESS) && (addresses != NULL)) { int i; int n; CFMutableArrayRef newAddresses; @@ -734,10 +719,10 @@ _reach_reply_set_reachability(SCNetworkReachabilityRef target, CFRelease(newAddress); } - targetPrivate->resolvedAddress = newAddresses; + targetPrivate->resolvedAddresses = newAddresses; } else { /* save the error associated with the attempt to resolve the name */ - targetPrivate->resolvedAddress = CFRetain(kCFNull); + targetPrivate->resolvedAddresses = CFRetain(kCFNull); } 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; @@ -791,9 +775,9 @@ _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRe 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 : @@ -844,7 +828,7 @@ _reach_server_target_status(xpc_connection_t connection, SCNetworkReachabilityRe if (retry) { // reconnect - _reach_server_target_reconnect(connection, target); + _reach_server_target_reconnect(connection, target, 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 retry = FALSE; 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 : - 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); } - - if (ok) { - CFRelease(target); - } } 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, - 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); - ok = TRUE; + retry = TRUE; } 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); } + if (retry) { + // reconnect + targetPrivate->serverScheduled = FALSE; + _reach_server_target_reconnect(connection, target, FALSE); + ok = TRUE; + } + + if (ok) { + CFRelease(target); + } + xpc_release(reqdict); return ok; } @@ -930,7 +923,7 @@ _reach_server_target_unschedule(xpc_connection_t connection, SCNetworkReachabili 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; @@ -940,8 +933,17 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit 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); @@ -962,8 +964,11 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit 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; } @@ -972,26 +977,20 @@ _reach_server_target_reconnect(xpc_connection_t connection, SCNetworkReachabilit 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; - rbt_request = RBNODE_TO_REACH_REQUEST(rbn); - - target = rbt_request->target; + xpc_retain(connection); + target = request->target; CFRetain(target); dispatch_async(__SCNetworkReachability_concurrent_queue(), ^{ - _reach_server_target_reconnect(connection, target); + _reach_server_target_reconnect(connection, target, FALSE); CFRelease(target); + xpc_release(connection); }); } }); @@ -1183,4 +1182,6 @@ __SCNetworkReachabilityServer_targetUnschedule(SCNetworkReachabilityRef target) return ok; } + + #endif // HAVE_REACHABILITY_SERVER diff --git a/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_server.c b/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_server.c index d9dfe2c..8527f32 100644 --- a/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_server.c +++ b/SystemConfiguration.fproj/reachability/SCNetworkReachabilityServer_server.c @@ -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@ * @@ -35,8 +35,7 @@ #include #include #include - -#include "rb.h" +#include #pragma mark - @@ -264,18 +263,18 @@ _target_reply_add_reachability(SCNetworkReachabilityRef target, 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); - n = CFArrayGetCount(targetPrivate->resolvedAddress); + n = CFArrayGetCount(targetPrivate->resolvedAddresses); 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), @@ -283,13 +282,13 @@ _target_reply_add_reachability(SCNetworkReachabilityRef target, } xpc_dictionary_set_value(reply, - REACH_STATUS_RESOLVED_ADDRESS, + REACH_STATUS_RESOLVED_ADDRESSES, 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); @@ -458,6 +457,7 @@ _target_watcher_remove(SCNetworkReachabilityRef target, connection, target, target_id); + ok = FALSE; return; } @@ -469,11 +469,11 @@ _target_watcher_remove(SCNetworkReachabilityRef target, target, target_id); CFRelease(key); + ok = FALSE; return; } CFDictionaryRemoveValue(targetPrivate->serverWatchers, key); - xpc_release(connection); CFRelease(key); n = CFDictionaryGetCount(targetPrivate->serverWatchers); @@ -502,8 +502,15 @@ _target_watcher_remove(SCNetworkReachabilityRef target, } // 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; @@ -515,7 +522,7 @@ _target_watcher_remove(SCNetworkReachabilityRef target, typedef struct { - struct rb_node rbn; + rb_node_t rbn; xpc_connection_t connection; pid_t pid; const char *proc_name; @@ -523,56 +530,54 @@ typedef struct { } reach_client_t; -#define RBNODE_TO_REACH_CLIENT(node) \ - ((reach_client_t *)((uintptr_t)node - offsetof(reach_client_t, rbn))) - - 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 -_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); } -static struct rb_tree * +static rb_tree_t * _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_node_offset = offsetof(reach_client_t, rbn), + .rbto_context = NULL }; - static struct rb_tree rbtree; + static rb_tree_t rbt; dispatch_once(&once, ^{ - rb_tree_init(&rbtree, &ops); + rb_tree_init(&rbt, &ops); }); - return &rbtree; + return &rbt; } static dispatch_queue_t -_reach_connection_queue() +_reach_clients_rbt_queue() { 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; @@ -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; + CFDictionaryRef serverWatchers; 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); } - CFDictionaryGetKeysAndValues(targetPrivate->serverWatchers, watchers, NULL); + CFDictionaryGetKeysAndValues(serverWatchers, watchers, NULL); 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); } + + 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) { - 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; + 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; } @@ -751,6 +761,21 @@ _client_target_remove(reach_client_t *client, uint64_t target_id) #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 * @@ -791,7 +816,8 @@ _reach_changed(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags */ 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; - dispatch_async(_reach_connection_queue(), ^{ + dispatch_async(_reach_server_queue(), ^{ 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; - const char *serv; 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; @@ -962,12 +986,6 @@ target_add(reach_client_t *client, xpc_object_t request) 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))) { @@ -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); @@ -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)); @@ -1057,11 +1063,6 @@ target_add(reach_client_t *client, xpc_object_t request) 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); @@ -1072,11 +1073,6 @@ target_add(reach_client_t *client, xpc_object_t request) 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, @@ -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); - 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); @@ -1353,19 +1354,33 @@ target_status(reach_client_t *client, xpc_object_t request) 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); + /* + * ... 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, - CFSTR("<%p> reply [scheduled], %@"), + CFSTR("<%p> reply [scheduled%s], %@"), client->connection, + targetPrivate->serverInfoValid ? "/valid" : "", 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 - * must return "current" flags. + * we must return "current" flags. */ if (targetPrivate->scheduled && targetPrivate->serverInfoValid) { /* @@ -1397,7 +1412,7 @@ target_status(reach_client_t *client, xpc_object_t request) 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 @@ -1407,7 +1422,7 @@ target_status(reach_client_t *client, xpc_object_t request) 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; @@ -1426,8 +1441,24 @@ target_status(reach_client_t *client, xpc_object_t request) 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"), @@ -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) { - Boolean ok; 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 - 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 : @@ -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) { - 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 = "?", }; - 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); - 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, - rbt_client->proc_name, - rbt_client->pid, + client->proc_name, + client->pid, 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, ^{ + 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(" 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->serverQueryActive, + nWatchers, + targetPrivate->serverSyncQueryActive, 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")); - if (targetPrivate->serverWatchers != NULL) { + if (nWatchers > 0) { 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; - struct rb_node *rbn; - struct rb_tree *rbt; 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 - 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 @@ -1850,53 +1887,58 @@ process_request(reach_client_t *client, xpc_object_t request) 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)); } - 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) { - 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; @@ -1911,11 +1953,7 @@ process_new_connection(xpc_connection_t connection) 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, @@ -1958,7 +1996,6 @@ load_SCNetworkReachability(CFBundleRef bundle, Boolean bundleVerbose) { xpc_connection_t connection; const char *name; - dispatch_queue_t reach_server_q; S_debug = bundleVerbose; @@ -1971,19 +2008,13 @@ load_SCNetworkReachability(CFBundleRef bundle, Boolean bundleVerbose) &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, - reach_server_q, + _reach_server_queue(), 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 index 21205db..0000000 --- a/SystemConfiguration.fproj/reachability/rb.c +++ /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 . - * - * 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 -#include -#include -#include -#ifdef RBDEBUG -#define KASSERT(s) assert(s) -#else -#define KASSERT(s) do { } while (/*CONSTCOND*/ 0) -#endif -#else -#include -#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 -#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; -} - -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; -} - -/* - * 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)); -} - -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); -} - -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)); -} - -/* - * 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 index 56f910d..0000000 --- a/SystemConfiguration.fproj/reachability/rb.h +++ /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 . - * - * 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 -#else -#include -#include -#endif -#include -#ifndef __APPLE__ -#include -#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 index 0000000..6d9a074 --- /dev/null +++ b/SystemConfiguration.fproj/scprefs_observer.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..a80ef47 --- /dev/null +++ b/SystemConfiguration.fproj/scprefs_observer.h @@ -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 */ diff --git a/SystemConfiguration.fproj/update-headers b/SystemConfiguration.fproj/update-headers index 862125b..c1c1104 100755 --- a/SystemConfiguration.fproj/update-headers +++ b/SystemConfiguration.fproj/update-headers @@ -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 =~ s/#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*\/\*SPI\*\/\n//; $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 =~ s/(#define\t__AVAILABILITY_INTERNAL__.*FUTURE.*)\/\*SPI\*\//\1/; $spi_new =~ s/(__IPHONE_\w+)\/\*SPI\*\//\1/g; return $spi_new; diff --git a/configd.tproj/_SCD.c b/configd.tproj/_SCD.c index bb64497..c54f4ba 100644 --- a/configd.tproj/_SCD.c +++ b/configd.tproj/_SCD.c @@ -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@ * @@ -232,21 +232,26 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey) } +#define N_QUICK 64 + + __private_extern__ void pushNotifications(FILE *_configd_trace) { - const void **sessionsToNotify; CFIndex notifyCnt; int server; - serverSessionRef theSession; + const void * sessionsToNotify_q[N_QUICK]; + const void ** sessionsToNotify = sessionsToNotify_q; SCDynamicStorePrivateRef storePrivate; + serverSessionRef theSession; 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], @@ -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. diff --git a/configd.tproj/_configadd.c b/configd.tproj/_configadd.c index f532b47..8f01964 100644 --- a/configd.tproj/_configadd.c +++ b/configd.tproj/_configadd.c @@ -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@ * @@ -134,7 +134,7 @@ _configadd(mach_port_t server, } } - if (!hasWriteAccess(mySession)) { + if (!hasWriteAccess(mySession, key)) { *sc_status = kSCStatusAccessError; goto done; } diff --git a/configd.tproj/_configclose.c b/configd.tproj/_configclose.c index 34e46b3..61729e4 100644 --- a/configd.tproj/_configclose.c +++ b/configd.tproj/_configclose.c @@ -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@ * @@ -36,8 +36,6 @@ #include "configd.h" #include "session.h" -#define N_QUICK 16 - static Boolean isMySessionKey(CFStringRef sessionKey, CFStringRef key) { diff --git a/configd.tproj/_confignotify.c b/configd.tproj/_confignotify.c index 52db0f8..ee85c5c 100644 --- a/configd.tproj/_confignotify.c +++ b/configd.tproj/_confignotify.c @@ -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@ * @@ -109,7 +109,7 @@ _confignotify(mach_port_t server, } } - if (!hasWriteAccess(mySession)) { + if (!hasWriteAccess(mySession, key)) { *sc_status = kSCStatusAccessError; goto done; } diff --git a/configd.tproj/_configremove.c b/configd.tproj/_configremove.c index 2d43008..eb27106 100644 --- a/configd.tproj/_configremove.c +++ b/configd.tproj/_configremove.c @@ -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@ * @@ -149,7 +149,7 @@ _configremove(mach_port_t server, } } - if (!hasWriteAccess(mySession)) { + if (!hasWriteAccess(mySession, key)) { *sc_status = kSCStatusAccessError; goto done; } diff --git a/configd.tproj/_configset.c b/configd.tproj/_configset.c index ee05645..0dd2b41 100644 --- a/configd.tproj/_configset.c +++ b/configd.tproj/_configset.c @@ -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@ * @@ -255,7 +255,7 @@ _configset(mach_port_t server, } } - if (!hasWriteAccess(mySession)) { + if (!hasWriteAccess(mySession, key)) { *sc_status = kSCStatusAccessError; goto done; } @@ -371,6 +371,8 @@ __SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet, return sc_status; } +#define N_QUICK 32 + __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); diff --git a/configd.tproj/_notifyremove.c b/configd.tproj/_notifyremove.c index bd4a261..9c894a5 100644 --- a/configd.tproj/_notifyremove.c +++ b/configd.tproj/_notifyremove.c @@ -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@ * @@ -100,7 +100,7 @@ __SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boole /* * 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); diff --git a/configd.tproj/com.apple.configd.plist b/configd.tproj/com.apple.configd.plist index 33473f1..e9c87cf 100644 --- a/configd.tproj/com.apple.configd.plist +++ b/configd.tproj/com.apple.configd.plist @@ -14,6 +14,10 @@ com.apple.SystemConfiguration.SCNetworkReachability + com.apple.SystemConfiguration.DNSConfiguration + + com.apple.SystemConfiguration.NetworkInformation + POSIXSpawnType Interactive diff --git a/configd.tproj/com.apple.configd_sim.plist b/configd.tproj/com.apple.configd_sim.plist new file mode 100644 index 0000000..39b9c8e --- /dev/null +++ b/configd.tproj/com.apple.configd_sim.plist @@ -0,0 +1,32 @@ + + + + + EnableTransactions + + KeepAlive + + Label + com.apple.configd_sim + MachServices + + com.apple.SystemConfiguration.configd_sim + + com.apple.SystemConfiguration.SCNetworkReachability_sim + + com.apple.SystemConfiguration.DNSConfiguration_sim + + com.apple.SystemConfiguration.NetworkInformation_sim + + + POSIXSpawnType + Interactive + ProgramArguments + + /usr/libexec/configd_sim + -d + + Umask + 18 + + diff --git a/configd.tproj/configd.8 b/configd.tproj/configd.8 index f697803..9006d7b 100644 --- a/configd.tproj/configd.8 +++ b/configd.tproj/configd.8 @@ -51,10 +51,10 @@ in the foreground without forking. This is useful for debugging. .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 -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 diff --git a/configd.tproj/configd.m b/configd.tproj/configd.m index 0a52729..852c41a 100644 --- a/configd.tproj/configd.m +++ b/configd.tproj/configd.m @@ -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@ * @@ -55,9 +55,9 @@ #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 -#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 */ @@ -346,15 +346,17 @@ main(int argc, char * const argv[]) // argv += optind; /* check credentials */ +#if !TARGET_IPHONE_SIMULATOR 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); -#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; @@ -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)) { diff --git a/configd.tproj/configd_server.c b/configd.tproj/configd_server.c index 99240d5..bbbb9c1 100644 --- a/configd.tproj/configd_server.c +++ b/configd.tproj/configd_server.c @@ -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@ * @@ -34,6 +34,7 @@ * - initial revision */ +#include #include #include #include @@ -48,13 +49,6 @@ 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; @@ -72,14 +66,6 @@ config_demux(mach_msg_header_t *request, mach_msg_header_t *reply) 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. */ @@ -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 (_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)) { @@ -240,7 +223,8 @@ server_init() 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); } @@ -268,7 +252,6 @@ server_shutdown() 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; diff --git a/configd.tproj/entitlements.plist b/configd.tproj/entitlements.plist index 5b7d736..f3624c6 100644 --- a/configd.tproj/entitlements.plist +++ b/configd.tproj/entitlements.plist @@ -8,11 +8,20 @@ com.apple.certificates com.apple.identities
+ com.apple.private.mobileinstall.allowedSPI + + Uninstall + Lookup + com.apple.springboard.launchapplications com.apple.multitasking.unlimitedassertions com.apple.wifi.manager-access + com.apple.coretelephony.Identity.get + + com.apple.private.SCNetworkConnection-proxy-user + diff --git a/configd.tproj/pattern.c b/configd.tproj/pattern.c index f307903..87bcbb1 100644 --- a/configd.tproj/pattern.c +++ b/configd.tproj/pattern.c @@ -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@ * @@ -47,7 +47,7 @@ typedef struct { CFMutableArrayRef pInfo; - regex_t *preg; + CFDataRef pRegex; } 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; + Boolean match = FALSE; + regex_t *preg; 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 */ - len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(storeKey), kCFStringEncodingASCII) + 1; + len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), kCFStringEncodingASCII) + 1; 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; } - /* 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 : - /* we've got a match */ - CFArrayAppendValue(pInfo, storeKey); + match = TRUE; 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)); - SCLog(TRUE, LOG_DEBUG, CFSTR("identifyKeyForPattern regexec(): %s"), reErrBuf); + SCLog(TRUE, LOG_DEBUG, CFSTR("keyMatchesPattern regexec(): %s"), reErrBuf); break; } } @@ -116,12 +110,34 @@ identifyKeyForPattern(const void *key, void *val, void *context) 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 -patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error) +patternCompile(CFStringRef pattern, CFDataRef pRegex, CFStringRef *error) { Boolean append = FALSE; Boolean insert = FALSE; @@ -174,8 +190,12 @@ patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error) CFRelease(pattern); } if (ok) { + regex_t *preg; 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]; @@ -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); - 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)); - /* 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); @@ -241,9 +273,8 @@ patternNew(CFStringRef 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); @@ -277,8 +308,7 @@ patternCopyMatches(CFStringRef pattern) 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); @@ -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) @@ -344,6 +420,7 @@ patternRemoveSession(CFStringRef pattern, CFNumberRef sessionNum) /* find instance of this pattern */ pInfo = patternCopy(pattern); + assert(pInfo != NULL); /* 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); - /* ALIGN: CF aligns to >8 byte boundries */ - regfree((regex_t *)(void *)CFDataGetBytePtr(pRegex)); + patternRelease(pRegex); CFDictionaryRemoveValue(patternData, pattern); } diff --git a/configd.tproj/pattern.h b/configd.tproj/pattern.h index 417fedc..4798b8a 100644 --- a/configd.tproj/pattern.h +++ b/configd.tproj/pattern.h @@ -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@ * @@ -38,6 +38,9 @@ __BEGIN_DECLS CFArrayRef patternCopyMatches (CFStringRef pattern); +Boolean patternKeyMatches (CFStringRef pattern, + CFStringRef key); + Boolean patternAddSession (CFStringRef pattern, CFNumberRef sessionNum); diff --git a/configd.tproj/plugin_support.c b/configd.tproj/plugin_support.c index 309631d..90a85cc 100644 --- a/configd.tproj/plugin_support.c +++ b/configd.tproj/plugin_support.c @@ -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@ * @@ -61,19 +61,17 @@ void _SCDPluginExecInit(); #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 -#else // !TARGET_OS_EMBEDDED +#else // !TARGET_OS_IPHONE #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[] = { - PLUGIN_MACOSX("com.apple.SystemConfiguration.Apple80211"), 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"), @@ -86,7 +84,6 @@ static const CFStringRef pluginWhitelist[] = { #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])) @@ -119,12 +116,14 @@ CFRunLoopRef plugin_runLoop = NULL; 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; +#endif // !TARGET_IPHONE_SIMULATOR #ifdef HAVE_REACHABILITY_SERVER extern SCDynamicStoreBundleLoadFunction load_SCNetworkReachability; #endif // HAVE_REACHABILITY_SERVER @@ -147,6 +146,7 @@ static const builtin builtin_plugins[] = { &prime_IPMonitor, NULL }, +#if !TARGET_IPHONE_SIMULATOR { CFSTR("com.apple.SystemConfiguration.InterfaceNamer"), &load_InterfaceNamer, @@ -175,6 +175,7 @@ static const builtin builtin_plugins[] = { &prime_PreferencesMonitor, NULL }, +#endif // !TARGET_IPHONE_SIMULATOR #ifdef HAVE_REACHABILITY_SERVER { CFSTR("com.apple.SystemConfiguration.SCNetworkReachability"), @@ -853,15 +854,28 @@ timerCallback(CFRunLoopTimerRef timer, void *info) static void sortBundles(CFMutableArrayRef orig) { + CFIndex i; + CFIndex n; 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); - while (CFArrayGetCount(orig) > 0) { - int i; + while (n > 0) { 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; @@ -887,6 +901,12 @@ sortBundles(CFMutableArrayRef orig) 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); @@ -910,6 +930,8 @@ sortBundles(CFMutableArrayRef orig) 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 */ @@ -922,6 +944,7 @@ sortBundles(CFMutableArrayRef orig) CFArrayRemoveAllValues(orig); CFArrayAppendArray(orig, new, CFRangeMake(0, CFArrayGetCount(new))); CFRelease(new); + CFRelease(orig_bundleIDs); return; } @@ -972,9 +995,24 @@ plugin_exec(void *arg) 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)); - 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), @@ -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. */ - 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, - CFSTR("com.apple.SystemConfiguration.InterfaceNamer"))) + CFSTR("com.apple.SystemConfiguration.InterfaceNamer"))) { CFArrayRemoveValueAtIndex(allBundles, i); CFArrayInsertValueAtIndex(allBundles, 0, bi); diff --git a/configd.tproj/session.c b/configd.tproj/session.c index cbb5b96..f6c8821 100644 --- a/configd.tproj/session.c +++ b/configd.tproj/session.c @@ -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@ * @@ -31,8 +31,10 @@ * - initial revision */ +#include #include "configd.h" #include "configd_server.h" +#include "pattern.h" #include "session.h" #include @@ -52,20 +54,6 @@ static CFRunLoopRef sessionRunLoop = 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) @@ -120,11 +108,17 @@ tempSession(mach_port_t server, CFStringRef name, audit_token_t auditToken) (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; @@ -221,13 +215,6 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) 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(), @@ -236,12 +223,14 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) 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]; } @@ -284,6 +273,16 @@ cleanupSession(mach_port_t server) */ (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. @@ -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 #include @@ -397,66 +396,81 @@ sessionName(serverSessionRef session) return (name != NULL) ? name : CFSTR("???"); } - -static Boolean -hasEntitlement(serverSessionRef session, CFStringRef entitlement) +static CFTypeRef +copyEntitlement(serverSessionRef session, CFStringRef entitlement) { - Boolean hasEntitlement = FALSE; 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; - CFTypeRef value; - /* Get the value for the entitlement. */ + // Get the value for the entitlement 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, - CFSTR("hasEntitlement: entitlement not valid: %@"), + CFSTR("SecTaskCopyValueForEntitlement(,\"%@\",) failed, error = %@ : %@"), + entitlement, + error, 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, - CFSTR("hasEntitlement SecTaskCreateWithAuditToken() failed: %@"), + CFSTR("SecTaskCreateWithAuditToken() failed: %@"), 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) { +#if !TARGET_IPHONE_SIMULATOR + 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 @@ -466,35 +480,127 @@ hasRootAccess(serverSessionRef session) 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; + +#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 -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; } +#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 @@ -519,8 +628,11 @@ hasPathAccess(serverSessionRef session, const char *path) &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; } diff --git a/configd.tproj/session.h b/configd.tproj/session.h index 68d8f91..ab4c4d6 100644 --- a/configd.tproj/session.h +++ b/configd.tproj/session.h @@ -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@ * @@ -40,6 +40,22 @@ #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 : of CFString with write access allowed for + * each SCDynamicStore key matching the string(s) + * + * Key : "patterns" + * Value : 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) @@ -69,8 +85,18 @@ typedef struct { /* 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; @@ -91,7 +117,8 @@ void listSessions (FILE *f); Boolean hasRootAccess (serverSessionRef session); -Boolean hasWriteAccess (serverSessionRef session); +Boolean hasWriteAccess (serverSessionRef session, + CFStringRef key); Boolean hasPathAccess (serverSessionRef session, const char *path); diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj index ebce9e4..2fced37 100644 --- a/configd.xcodeproj/project.pbxproj +++ b/configd.xcodeproj/project.pbxproj @@ -28,6 +28,14 @@ ); 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; @@ -58,6 +66,17 @@ 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" */; @@ -106,79 +125,6 @@ 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" */; @@ -238,12 +184,26 @@ 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 = ( + 157FDE44164A079B0040D6A8 /* PBXTargetDependency */, 151FE37A0D5B713C000D6DB1 /* PBXTargetDependency */, ); name = "All-EmbeddedSimulator"; @@ -254,9 +214,9 @@ /* 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 */; }; - 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 */; }; @@ -265,24 +225,26 @@ 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 */; }; - 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 */; }; - 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 */; }; - 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, ); }; }; - 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 */; }; - 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 */; }; + 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 */; }; @@ -340,18 +302,18 @@ 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, ); }; }; - 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, ); }; }; - 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, ); }; }; - 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, ); }; }; @@ -359,7 +321,7 @@ 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 */; }; @@ -431,7 +393,6 @@ 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 */; }; @@ -441,7 +402,88 @@ 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 */; }; + 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 */; }; @@ -478,14 +520,10 @@ 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 */; }; - 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 */; }; - 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 */; }; @@ -536,9 +574,7 @@ 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 */; }; - 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 */; }; @@ -553,230 +589,14 @@ 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 */; }; - 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 */; }; + 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 */; }; @@ -837,9 +657,7 @@ 159D54C407529FFF004F8947 /* _notifycancel.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1405C0722B0099E85F /* _notifycancel.c */; settings = {ATTRIBUTES = (); }; }; 159D54C507529FFF004F8947 /* _snapshot.c in Sources */ = {isa = PBXBuildFile; fileRef = 15CB6A1605C0722B0099E85F /* _snapshot.c */; settings = {ATTRIBUTES = (); }; }; 159D54C607529FFF004F8947 /* config.defs in Sources */ = {isa = PBXBuildFile; fileRef = 15CB69BE05C0722B0099E85F /* config.defs */; settings = {ATTRIBUTES = (Server, ); }; }; - 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 */; }; - 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 */; }; @@ -855,18 +673,18 @@ 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, ); }; }; - 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, ); }; }; - 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, ); }; }; - 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, ); }; }; @@ -874,7 +692,7 @@ 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 */; }; @@ -947,9 +765,6 @@ 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 */; }; @@ -966,56 +781,49 @@ 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 */; }; - 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 */; }; - 15C330D4134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */; }; 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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, ); }; }; - 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, ); }; }; - 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, ); }; }; - 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, ); }; }; - 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, ); }; }; @@ -1023,13 +831,12 @@ 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, ); }; }; - 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 */; }; @@ -1086,7 +893,6 @@ 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"; }; }; @@ -1096,8 +902,23 @@ 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 */; }; - 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 */; }; @@ -1110,6 +931,38 @@ 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, ); }; }; @@ -1118,12 +971,14 @@ 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, ); }; }; + 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 */ @@ -1176,20 +1031,6 @@ 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 */; @@ -1225,6 +1066,13 @@ 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 */; @@ -1295,6 +1143,13 @@ 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 */; @@ -1449,180 +1304,131 @@ 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; - remoteGlobalIDString = 1583EB92108395BE00A3BC0C; - remoteInfo = "scutil-EmbeddedOther"; + remoteGlobalIDString = 15AB751216EBFF3400FAA8CE; + remoteInfo = "SCNetworkReachability-EmbeddedSimulator"; }; - 15AC516B108396B7004A9ED5 /* PBXContainerItemProxy */ = { + 15AB752316EC005A00FAA8CE /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EB4B108395BD00A3BC0C; - remoteInfo = "configd-EmbeddedOther"; + remoteGlobalIDString = 15E1B04116EBAE3C00E5F06F; + remoteInfo = "IPMonitor-EmbeddedSimulator"; }; - 15AC5170108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15AB752B16EC254D00FAA8CE /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EB32108395BD00A3BC0C; - remoteInfo = "PreferencesMonitor-EmbeddedOther"; + remoteGlobalIDString = 15DAD5DF075913CE0084A6ED; + remoteInfo = DNSConfiguration; }; - 15AC5178108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15C64A230F684C5700D78394 /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EB0F108395BC00A3BC0C; - remoteInfo = "LinkConfiguration.bundle-EmbeddedOther"; + remoteGlobalIDString = 15C64A280F684C6B00D78394; + remoteInfo = "configd_libSystem-Embedded"; }; - 15AC517C108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EB00108395BC00A3BC0C; - remoteInfo = "KernelEventMonitor.bundle-EmbeddedOther"; + remoteGlobalIDString = 15D3080F16F3E4DA00014F82; + remoteInfo = "SimulatorSupport-EmbeddedSimulator"; }; - 15AC5180108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15D3083116F3EAD000014F82 /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EAE8108395BC00A3BC0C; - remoteInfo = "InterfaceNamer.bundle-EmbeddedOther"; + remoteGlobalIDString = 15D3080F16F3E4DA00014F82; + remoteInfo = "SimulatorSupport-EmbeddedSimulator"; }; - 15AC5184108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 1583EAD9108395BB00A3BC0C; - remoteInfo = "IPMonitor.bundle-EmbeddedOther"; + remoteGlobalIDString = 15732AAD16EA511900F3AC4C; + remoteInfo = "scutil-EmbeddedSimulator"; }; - 15AC5188108396D2004A9ED5 /* PBXContainerItemProxy */ = { + 15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 15DAD5DF075913CE0084A6ED; - remoteInfo = DNSConfiguration; + remoteGlobalIDString = 15E1B05A16EBAE7800E5F06F; + remoteInfo = "IPMonitor.bundle-EmbeddedSimulator"; }; - 15C64A230F684C5700D78394 /* PBXContainerItemProxy */ = { + 15E83108167F9B0600FD51EC /* PBXContainerItemProxy */ = { 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; - remoteGlobalIDString = 15C64A280F684C6B00D78394; - remoteInfo = "configd_libSystem-Embedded"; + remoteGlobalIDString = 151C1CC60CFB487000C5AFD6; + remoteInfo = "All-Embedded"; }; - 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */ = { + 15E8310C167F9B1200FD51EC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 15CB6A7705C0722B0099E85F /* Project object */; proxyType = 1; - remoteGlobalIDString = 157A84D80D56C63900B6F1A0; - remoteInfo = "DNSConfiguration-Embedded"; + remoteGlobalIDString = 15FD13BF0D59485000F9409C; + remoteInfo = "All-EmbeddedSimulator"; }; D6DDAC3C147A24BC00A2E902 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -1654,6 +1460,16 @@ ); 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; @@ -1674,54 +1490,57 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - 1583EAA5108395BB00A3BC0C /* CopyFiles */ = { + 159D54D507529FFF004F8947 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; - dstPath = /System/Library/LaunchDaemons; + dstPath = /usr/share/man/man8; dstSubfolderSpec = 0; files = ( - 1583EAA6108395BB00A3BC0C /* com.apple.SCHelper-embedded.plist in CopyFiles */, + 159D54D607529FFF004F8947 /* configd.8 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; - 1583EB7F108395BD00A3BC0C /* CopyFiles */ = { + 159D54D707529FFF004F8947 /* CopyFiles */ = { 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; }; - 159D54D507529FFF004F8947 /* CopyFiles */ = { + 15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; - dstPath = /usr/share/man/man8; + dstPath = /private/etc/asl; 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; }; - 159D54D707529FFF004F8947 /* CopyFiles */ = { + 15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; - dstPath = /System/Library/LaunchDaemons; + dstPath = /private/etc/asl; 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; }; - 15D9DCF910DD909F004E545D /* CopyFiles */ = { + 15D9DCF910DD909F004E545D /* AppWorkaround.plist */ = { 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 */ = { @@ -1754,8 +1573,6 @@ 1528BFE91357312E00691881 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/SCNetworkReachability/Info.plist; sourceTree = ""; }; 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 = ""; }; 152E0E7E10FE820E00E402F2 /* helper.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; name = helper.defs; path = SystemConfiguration.fproj/helper/helper.defs; sourceTree = ""; }; 152E0E8810FE824000E402F2 /* helper_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = helper_types.h; path = SystemConfiguration.fproj/helper/helper_types.h; sourceTree = ""; }; @@ -1764,7 +1581,11 @@ 1531D3DA0E93E6DA00248432 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Plugins/Logger/Info.plist; sourceTree = ""; }; 1531D3DB0E93E6DA00248432 /* logger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = logger.c; path = Plugins/Logger/logger.c; sourceTree = ""; }; 1532629006281C9D00B1C10C /* dnsinfo_create.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_create.h; path = dnsinfo/dnsinfo_create.h; sourceTree = ""; }; + 153338BA14BE7978004FCE22 /* libSystemConfiguration_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libSystemConfiguration_client.c; path = libSystemConfiguration/libSystemConfiguration_client.c; sourceTree = ""; }; + 153338BB14BE7978004FCE22 /* libSystemConfiguration_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libSystemConfiguration_client.h; path = libSystemConfiguration/libSystemConfiguration_client.h; sourceTree = ""; }; 153393E20D34994100FE74E7 /* update-headers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "update-headers"; sourceTree = ""; }; + 153ACCA614E322D5005029A5 /* network_information_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = network_information_server.c; path = nwi/network_information_server.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; + 153ACCA714E322D5005029A5 /* network_information_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = network_information_server.h; path = nwi/network_information_server.h; sourceTree = ""; }; 1540E3600987DA9500157C07 /* com.apple.configd.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 30; path = com.apple.configd.plist; sourceTree = ""; }; 1543636A0752D03C00A8EC6C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 1547001D08455B98006787CE /* SCHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SCHelper; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1789,13 +1610,17 @@ 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = ""; }; 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 = ""; }; + 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 = ""; }; + 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 = ""; }; 1575FD2612CD15C60003D86E /* proxy-configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "proxy-configuration.h"; sourceTree = ""; }; 1577252F06EFB96700D7B52B /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/NetworkInterface.strings; sourceTree = ""; }; - 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; }; @@ -1803,31 +1628,16 @@ 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 = ""; }; 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 = ""; }; 158AD8C00754E3EF00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 158AD9100754E40E00124717 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 158AD9F80754EA2F00124717 /* AppleTalk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleTalk.framework; path = /System/Library/Frameworks/AppleTalk.framework; sourceTree = ""; }; + 1596A7AF14EDB73D00798C39 /* libSystemConfiguration_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = libSystemConfiguration_server.c; path = libSystemConfiguration/libSystemConfiguration_server.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; + 1596A7B014EDB73D00798C39 /* libSystemConfiguration_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = libSystemConfiguration_server.h; path = libSystemConfiguration/libSystemConfiguration_server.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 159A7513107FEAA400A57EAB /* VPNPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNPrivate.h; sourceTree = ""; }; 159A7515107FEAA400A57EAB /* VPNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNConfiguration.h; sourceTree = ""; }; 159A7517107FEAA400A57EAB /* VPNPrivate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNPrivate.c; sourceTree = ""; }; 159A7519107FEAA400A57EAB /* VPNConfiguration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNConfiguration.c; sourceTree = ""; }; + 159C9A8D17399609003DDA1D /* dnsinfo_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dnsinfo_internal.h; path = dnsinfo/dnsinfo_internal.h; sourceTree = ""; }; 159D53A707528B36004F8947 /* ip_plugin.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = ip_plugin.c; sourceTree = ""; }; 159D53AA07528B36004F8947 /* dns-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "dns-configuration.c"; sourceTree = ""; }; 159D53AB07528B36004F8947 /* set-hostname.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "set-hostname.c"; sourceTree = ""; }; @@ -1861,6 +1671,9 @@ 15AAA7F1108E310700C2A607 /* VPNTunnelPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnelPrivate.h; sourceTree = ""; }; 15AAA7F2108E310700C2A607 /* VPNTunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VPNTunnel.h; sourceTree = ""; }; 15AAA7F3108E310700C2A607 /* VPNTunnel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNTunnel.c; sourceTree = ""; }; + 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 = ""; }; 15AD7A390670A85900BFE03C /* SCNetworkConfigurationInternal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkConfigurationInternal.c; sourceTree = ""; }; 15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkConfigurationInternal.h; sourceTree = ""; }; @@ -1868,20 +1681,17 @@ 15AD7A3C0670A85900BFE03C /* SCNetworkProtocol.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkProtocol.c; sourceTree = ""; }; 15AD7A3D0670A85900BFE03C /* SCNetworkService.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkService.c; sourceTree = ""; }; 15AD7A3E0670A85900BFE03C /* SCNetworkSet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSet.c; sourceTree = ""; }; - 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 = ""; }; 15B73F0805FD1B670096477F /* dnsinfo_copy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_copy.c; path = dnsinfo/dnsinfo_copy.c; sourceTree = ""; }; 15B73F0905FD1B670096477F /* dnsinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo.h; path = dnsinfo/dnsinfo.h; sourceTree = ""; }; - 15B73F0B05FD1B670096477F /* dnsinfo_private.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_private.c; path = dnsinfo/dnsinfo_private.c; sourceTree = ""; }; 15B73F0C05FD1B670096477F /* dnsinfo_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_private.h; path = dnsinfo/dnsinfo_private.h; sourceTree = ""; }; 15B73F0D05FD1B670096477F /* dnsinfo_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dnsinfo_server.c; path = dnsinfo/dnsinfo_server.c; sourceTree = ""; }; 15B73F0E05FD1B670096477F /* dnsinfo_server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dnsinfo_server.h; path = dnsinfo/dnsinfo_server.h; sourceTree = ""; }; 15BAA32207F0699A00D9EC95 /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = /usr/lib/libbsm.dylib; sourceTree = ""; }; 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_client.c; path = reachability/SCNetworkReachabilityServer_client.c; sourceTree = ""; }; - 15C330B8134B92780028E36B /* rb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rb.c; path = reachability/rb.c; sourceTree = ""; }; - 15C330B9134B92780028E36B /* rb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rb.h; path = reachability/rb.h; sourceTree = ""; }; 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SCNetworkReachabilityServer_server.c; path = reachability/SCNetworkReachabilityServer_server.c; sourceTree = ""; }; 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkReachabilityInternal.h; sourceTree = ""; }; + 15CAEF381712690500367CE1 /* libcupolicy.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcupolicy.dylib; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/usr/local/lib/libcupolicy.dylib; sourceTree = DEVELOPER_DIR; }; 15CB691305C0722B0099E85F /* SystemConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemConfiguration.h; sourceTree = ""; }; 15CB691505C0722B0099E85F /* SCPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCPrivate.h; sourceTree = ""; }; 15CB691705C0722B0099E85F /* SCDPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCDPlugin.h; sourceTree = ""; }; @@ -1906,7 +1716,6 @@ 15CB694105C0722B0099E85F /* moh_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh_msg.h; sourceTree = ""; }; 15CB694305C0722B0099E85F /* moh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moh.h; sourceTree = ""; }; 15CB694505C0722B0099E85F /* DeviceOnHold.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceOnHold.h; sourceTree = ""; }; - 15CB694705C0722B0099E85F /* LinkConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LinkConfiguration.h; sourceTree = ""; }; 15CB694905C0722B0099E85F /* dy_framework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dy_framework.h; sourceTree = ""; }; 15CB695005C0722B0099E85F /* SCD.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCD.c; sourceTree = ""; }; 15CB695205C0722B0099E85F /* SCDKeys.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCDKeys.c; sourceTree = ""; }; @@ -1946,7 +1755,7 @@ 15CB69A005C0722B0099E85F /* SCLocation.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCLocation.c; sourceTree = ""; }; 15CB69A205C0722B0099E85F /* SCNetwork.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetwork.c; sourceTree = ""; }; 15CB69A405C0722B0099E85F /* SCNetworkConnection.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkConnection.c; sourceTree = ""; }; - 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCNetworkReachability.c; sourceTree = ""; }; + 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */ = {isa = PBXFileReference; indentWidth = 8; lastKnownFileType = sourcecode.c.c; path = SCNetworkReachability.c; sourceTree = ""; }; 15CB69A805C0722B0099E85F /* SCProxies.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SCProxies.c; sourceTree = ""; }; 15CB69AC05C0722B0099E85F /* DHCP.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = DHCP.c; sourceTree = ""; }; 15CB69AE05C0722B0099E85F /* moh.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = moh.c; sourceTree = ""; }; @@ -2009,9 +1818,14 @@ 15CB6A6A05C0722B0099E85F /* scutil.8 */ = {isa = PBXFileReference; explicitFileType = text.man; path = scutil.8; sourceTree = ""; }; 15CB6A6F05C0722B0099E85F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 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 = ""; }; + 15D3083816F3EB8600014F82 /* simulator_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulator_support.c; path = Plugins/SimulatorSupport/simulator_support.c; sourceTree = ""; }; + 15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.configd_sim.plist; sourceTree = ""; }; 15D8B2291450D8450090CECF /* SCD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCD.h; sourceTree = ""; }; 15D9DCFA10DD90A1004E545D /* AppWorkaround.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppWorkaround.plist; sourceTree = ""; }; - 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 = ""; }; 15DAF2D908466D4900D1B2BD /* SCHelper_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = SCHelper_server.c; path = helper/SCHelper_server.c; sourceTree = ""; }; 15DC34670711D49400A3311C /* net_interface.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_interface.c; sourceTree = ""; }; @@ -2022,10 +1836,10 @@ 15DC346C0711D49400A3311C /* net_service.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_service.h; sourceTree = ""; }; 15DC346D0711D49400A3311C /* net_set.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = net_set.c; sourceTree = ""; }; 15DC346E0711D49400A3311C /* net_set.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net_set.h; sourceTree = ""; }; + 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 = ""; }; 15FC130A0CCEA59E0013872C /* monitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor.c; path = SCMonitor/monitor.c; sourceTree = ""; }; - 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 = ""; }; 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = IndigoSDK.xcconfig; path = /AppleInternal/Indigo/IndigoSDK.xcconfig; sourceTree = ""; }; 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; }; @@ -2042,14 +1856,31 @@ 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 = ""; }; 72B43727113C7BFC00EBF1B6 /* nc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nc.c; sourceTree = ""; }; + 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 = ""; }; + B03FEFB516376D2800A1B88F /* VPNAppLayer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNAppLayer.c; sourceTree = ""; }; + B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCNetworkConnectionInternal.h; sourceTree = ""; }; + B0A88CA616397A1200A60B3A /* VPNAppLayerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VPNAppLayerPrivate.h; sourceTree = ""; tabWidth = 4; }; + B0BF3440174594C400961734 /* entitlements-osx.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "entitlements-osx.plist"; sourceTree = ""; }; + B0C967F717441F0E00889853 /* SNHelperPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNHelperPrivate.h; sourceTree = ""; }; + B0C9689B174426C200889853 /* SNHelper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SNHelper.c; sourceTree = ""; }; + C4CDB8111631933400819B44 /* VPNFlow.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VPNFlow.h; sourceTree = ""; tabWidth = 4; }; + C4CDB8121631933400819B44 /* VPNFlowPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VPNFlowPrivate.h; sourceTree = ""; }; + C4CDB8141631935700819B44 /* VPNFlow.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = VPNFlow.c; sourceTree = ""; tabWidth = 4; }; + C4F1847F16237AFC00D97043 /* VPNService.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VPNService.c; sourceTree = ""; }; + D61AAEAD1522C99C0066B003 /* scprefs_observer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scprefs_observer.c; sourceTree = ""; }; + D61AAEB41522C9BD0066B003 /* scprefs_observer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scprefs_observer.h; sourceTree = ""; }; + D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.networking.IPMonitor; sourceTree = ""; }; D6986A75136891120091C931 /* network_information_priv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information_priv.c; path = nwi/network_information_priv.c; sourceTree = ""; }; D6986A761368911E0091C931 /* network_information_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information_priv.h; path = nwi/network_information_priv.h; sourceTree = ""; }; D6986A77136891300091C931 /* network_information.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = network_information.c; path = nwi/network_information.c; sourceTree = ""; }; D6986A781368913C0091C931 /* network_information.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = network_information.h; path = nwi/network_information.h; sourceTree = ""; }; + D6AEB89815AE4446009F2FAF /* ip_plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ip_plugin.h; sourceTree = ""; }; F95B8A420B03E07A00993BA3 /* SCNetworkSignature.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SCNetworkSignature.c; sourceTree = ""; }; F95B8A440B03E09300993BA3 /* SCNetworkSignature.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignature.h; sourceTree = ""; }; F95B8A450B03E09300993BA3 /* SCNetworkSignaturePrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCNetworkSignaturePrivate.h; sourceTree = ""; }; + F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = IPMonitorControlPrefs.c; sourceTree = ""; }; + F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPMonitorControlPrefs.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2101,6 +1932,7 @@ files = ( 1558481907550EC10046C2E9 /* CoreFoundation.framework in Frameworks */, 1559C44E0D349A4E0098FD59 /* SystemConfiguration.framework in Frameworks */, + 15D2E437167643460078F547 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2119,6 +1951,39 @@ 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; }; @@ -2138,6 +2003,7 @@ 1574340E0D4A8137002ACA73 /* CoreFoundation.framework in Frameworks */, 1574340F0D4A8137002ACA73 /* SystemConfiguration.framework in Frameworks */, 157434110D4A8137002ACA73 /* libedit.dylib in Frameworks */, + 72C3E82715003E78000D68CB /* MobileInstallation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2177,79 +2043,6 @@ ); 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; @@ -2273,6 +2066,7 @@ buildActionMask = 2147483647; files = ( 15A5A2630D5B94190087BDA0 /* CoreFoundation.framework in Frameworks */, + B0FEF41A164406F400174B99 /* libbsm.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2288,54 +2082,13 @@ buildActionMask = 2147483647; files = ( 15DAD6AE07591A1A0084A6ED /* CoreFoundation.framework in Frameworks */, + B03FEFBA16382C0700A1B88F /* libbsm.dylib in Frameworks */, ); 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 = ""; - }; - 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 = ""; - }; - 1513E3A11084216500088779 /* configd, scutil, scselect */ = { - isa = PBXGroup; - children = ( - 1583EB84108395BD00A3BC0C /* configd */, - 1583EB90108395BE00A3BC0C /* scselect */, - 1583EBB6108395BE00A3BC0C /* scutil */, - ); - name = "configd, scutil, scselect"; - sourceTree = ""; - }; 151F5DA80CCE995D0093AC3B /* SCMonitor */ = { isa = PBXGroup; children = ( @@ -2367,7 +2120,7 @@ 154083530D5B824400E07907 /* MacOSX */ = { isa = PBXGroup; children = ( - 15DAD5EE075913CE0084A6ED /* libdnsinfo.dylib */, + 15DAD5EE075913CE0084A6ED /* libsystem_configuration.dylib */, 1547072E0D1F70C80075C28D /* SystemConfiguration.framework */, 1547001D08455B98006787CE /* SCHelper */, 151F5D9A0CCE98E50093AC3B /* SCMonitor.plugin */, @@ -2380,7 +2133,7 @@ 1540835A0D5B825200E07907 /* Embedded */ = { isa = PBXGroup; children = ( - 157A84E80D56C63900B6F1A0 /* libdnsinfo.dylib */, + 157A84E80D56C63900B6F1A0 /* libsystem_configuration.dylib */, 1559C4440D349A4E0098FD59 /* SystemConfiguration.framework */, 154083C50D5B832F00E07907 /* Plugins */, 1559C4470D349A4E0098FD59 /* SCHelper */, @@ -2393,6 +2146,8 @@ isa = PBXGroup; children = ( 15A5A26A0D5B94190087BDA0 /* SystemConfiguration.framework */, + 1541472016EBF5C500B197B9 /* Plugins */, + 1541471F16EBF32B00B197B9 /* configd, scutil */, ); name = EmbeddedSimulator; sourceTree = ""; @@ -2427,6 +2182,20 @@ name = "configd, scutil, scselect"; sourceTree = ""; }; + 1541471F16EBF32B00B197B9 /* configd, scutil */ = { + isa = PBXGroup; + children = ( + ); + name = "configd, scutil"; + sourceTree = ""; + }; + 1541472016EBF5C500B197B9 /* Plugins */ = { + isa = PBXGroup; + children = ( + ); + name = Plugins; + sourceTree = ""; + }; 1547002E084561B4006787CE /* SCHelper */ = { isa = PBXGroup; children = ( @@ -2468,6 +2237,7 @@ children = ( 15B73F0905FD1B670096477F /* dnsinfo.h */, 1532629006281C9D00B1C10C /* dnsinfo_create.h */, + 159C9A8D17399609003DDA1D /* dnsinfo_internal.h */, 15B73F0C05FD1B670096477F /* dnsinfo_private.h */, 15B73F0E05FD1B670096477F /* dnsinfo_server.h */, ); @@ -2477,7 +2247,6 @@ 1582B37905FD1A66009C2750 /* Sources */ = { isa = PBXGroup; children = ( - 15B73F0B05FD1B670096477F /* dnsinfo_private.c */, 15B73F0805FD1B670096477F /* dnsinfo_copy.c */, 1521FC5C060F296A003B28F5 /* dnsinfo_create.c */, 1522FCE50FA7FD7000B24128 /* dnsinfo_flatfile.c */, @@ -2527,6 +2296,7 @@ 1531D3D90E93E6AA00248432 /* Logger */, 159D53C207528B36004F8947 /* PreferencesMonitor */, 1528BFDA13572FC200691881 /* SCNetworkReachability */, + 15D3080E16F3E49F00014F82 /* SimulatorSupport */, ); name = Plugins; sourceTree = ""; @@ -2534,6 +2304,7 @@ 159D53A607528B36004F8947 /* IPMonitor */ = { isa = PBXGroup; children = ( + D6AEB89815AE4446009F2FAF /* ip_plugin.h */, 159D53A707528B36004F8947 /* ip_plugin.c */, 155D22380AF13A7300D52ED0 /* dns-configuration.h */, 159D53AA07528B36004F8947 /* dns-configuration.c */, @@ -2544,6 +2315,7 @@ 155D223A0AF13A7300D52ED0 /* smb-configuration.h */, 1572EB7A0A506D3B00D02459 /* smb-configuration.c */, 15FD743E0754DE7A001CC321 /* Info.plist */, + D68AD25F159BCD5900D4F1BE /* com.apple.networking.IPMonitor */, ); name = IPMonitor; path = Plugins/IPMonitor; @@ -2599,6 +2371,8 @@ 159D53C907528B36004F8947 /* common */ = { isa = PBXGroup; children = ( + F9A3780E16A4846E00C57CDC /* IPMonitorControlPrefs.c */, + F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */, 159D53CA07528B36004F8947 /* cache.c */, 159D53CB07528B36004F8947 /* cache.h */, ); @@ -2606,6 +2380,19 @@ path = Plugins/common; sourceTree = ""; }; + 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 = ""; + }; 15B6861D0678B61900FF4023 /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -2633,7 +2420,6 @@ children = ( 15CB693705C0722B0099E85F /* SCNetworkReachability.h */, 15C330D0134B95AA0028E36B /* SCNetworkReachabilityInternal.h */, - 15C330B9134B92780028E36B /* rb.h */, ); name = Headers; sourceTree = ""; @@ -2645,7 +2431,6 @@ 15CB69A605C0722B0099E85F /* SCNetworkReachability.c */, 15C330B7134B92780028E36B /* SCNetworkReachabilityServer_client.c */, 15C330BB134B92780028E36B /* SCNetworkReachabilityServer_server.c */, - 15C330B8134B92780028E36B /* rb.c */, ); name = Sources; sourceTree = ""; @@ -2760,7 +2545,6 @@ 15AD7A380670A85900BFE03C /* SCNetworkConfiguration.h */, 155A1E6B081079CC00F70D98 /* SCNetworkConfigurationPrivate.h */, 15AD7A3A0670A85900BFE03C /* SCNetworkConfigurationInternal.h */, - 15CB694705C0722B0099E85F /* LinkConfiguration.h */, ); name = Headers; sourceTree = ""; @@ -2777,6 +2561,7 @@ 9EE943F306AF409B00772EB5 /* BondConfiguration.c */, 15FD7B3B101E439200C56621 /* BridgeConfiguration.c */, 15CB69B605C0722B0099E85F /* VLANConfiguration.c */, + C4F1847F16237AFC00D97043 /* VPNService.c */, ); name = Sources; sourceTree = ""; @@ -2802,6 +2587,7 @@ 15C330E0134B9C4C0028E36B /* Headers */ = { isa = PBXGroup; children = ( + B084710E16385121006C92A3 /* SCNetworkConnectionInternal.h */, 15CB693505C0722B0099E85F /* SCNetworkConnection.h */, 15A2972E0A13C08C009879B3 /* SCNetworkConnectionPrivate.h */, 23C1E2BE062DD5DB00835B54 /* pppcontroller.h */, @@ -2821,6 +2607,9 @@ 15C330E2134B9C9B0028E36B /* Sources */ = { isa = PBXGroup; children = ( + B0C9689B174426C200889853 /* SNHelper.c */, + B03FEFB516376D2800A1B88F /* VPNAppLayer.c */, + C4CDB8141631935700819B44 /* VPNFlow.c */, 159A7517107FEAA400A57EAB /* VPNPrivate.c */, 159A7519107FEAA400A57EAB /* VPNConfiguration.c */, 15AAA7F3108E310700C2A607 /* VPNTunnel.c */, @@ -2831,6 +2620,10 @@ 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 */, @@ -2844,8 +2637,7 @@ children = ( 15CB6A8605C072500099E85F /* MiG */, 15CB6A8305C072410099E85F /* Schema */, - D6986A70136890B60091C931 /* NetworkInformation */, - 1582B36B05FD1A4D009C2750 /* DNSConfiguration */, + 15B534AD14BE778800EA6522 /* libsystem_configuration */, 15CB690705C0722A0099E85F /* SystemConfiguration */, 151F5DA80CCE995D0093AC3B /* SCMonitor */, 15CB69C205C0722B0099E85F /* configd */, @@ -2854,7 +2646,6 @@ 159D53A207528B06004F8947 /* Plugins */, 15CB6A6E05C0722B0099E85F /* External Frameworks and Libraries */, 15CB690F05C0722B0099E85F /* Products */, - 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */, 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */, ); indentWidth = 8; @@ -2888,7 +2679,15 @@ 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 = ""; @@ -2910,6 +2709,7 @@ 15CB694505C0722B0099E85F /* DeviceOnHold.h */, 15CB693D05C0722B0099E85F /* DHCPClientPreferences.h */, 15CB694905C0722B0099E85F /* dy_framework.h */, + D61AAEB41522C9BD0066B003 /* scprefs_observer.h */, 15CB694305C0722B0099E85F /* moh.h */, 15CB694105C0722B0099E85F /* moh_msg.h */, ); @@ -2921,6 +2721,7 @@ children = ( 150607BD075A00A200B147BA /* SCSchemaDefinitions.c */, 15CB695005C0722B0099E85F /* SCD.c */, + D61AAEAD1522C99C0066B003 /* scprefs_observer.c */, 15CB695405C0722B0099E85F /* SCDPrivate.c */, 15CB695605C0722B0099E85F /* SCDPlugin.c */, 15CB699C05C0722B0099E85F /* SCDConsoleUser.c */, @@ -2996,7 +2797,9 @@ 15CB6A1805C0722B0099E85F /* Supporting Files */ = { isa = PBXGroup; children = ( + B0BF3440174594C400961734 /* entitlements-osx.plist */, 1540E3600987DA9500157C07 /* com.apple.configd.plist */, + 15D3083A16F4E6D900014F82 /* com.apple.configd_sim.plist */, 15CB6A2005C0722B0099E85F /* configd.8 */, 1567333E0DD1FD6500145179 /* entitlements.plist */, ); @@ -3093,13 +2896,15 @@ 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 */, + 15AC2D8816C574FE00340E28 /* libcupolicy.dylib */, 152CEED0070CF6640050F23C /* libedit.dylib */, + 72C3E82615003E78000D68CB /* MobileInstallation.framework */, + 15CAEF381712690500367CE1 /* libcupolicy.dylib */, ); name = "External Frameworks and Libraries"; sourceTree = ""; @@ -3119,14 +2924,22 @@ 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 */, + 1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */, ); name = MiG; sourceTree = ""; }; + 15D3080E16F3E49F00014F82 /* SimulatorSupport */ = { + isa = PBXGroup; + children = ( + 15D3083816F3EB8600014F82 /* simulator_support.c */, + 15D3083616F3EB7200014F82 /* Info.plist */, + ); + name = SimulatorSupport; + sourceTree = ""; + }; 15FF5C390CDF9C4000EEC8AA /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -3150,6 +2963,7 @@ children = ( D6986A781368913C0091C931 /* network_information.h */, D6986A761368911E0091C931 /* network_information_priv.h */, + 153ACCA714E322D5005029A5 /* network_information_server.h */, ); name = Headers; sourceTree = ""; @@ -3159,6 +2973,7 @@ children = ( D6986A77136891300091C931 /* network_information.c */, D6986A75136891120091C931 /* network_information_priv.c */, + 153ACCA614E322D5005029A5 /* network_information_server.c */, ); name = Sources; sourceTree = ""; @@ -3180,13 +2995,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1528C0001357401900691881 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1547001908455B98006787CE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3246,6 +3054,7 @@ 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 */, @@ -3254,52 +3063,103 @@ 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 */, - 1572C4CB0CFB55B400E2776E /* pppcontroller.h in Headers */, + 1572C581171CD00E00870549 /* pppcontroller_mach_defines.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 */, + 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 */, + 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 */, - 15C330C5134B92780028E36B /* rb.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; }; - 157433DE0D4A8122002ACA73 /* Headers */ = { + 15732A7716EA503200F3AC4C /* Headers */ = { 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; }; - 157433F10D4A8137002ACA73 /* Headers */ = { + 15732AAE16EA511900F3AC4C /* 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 */, + 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 */, @@ -3314,6 +3174,7 @@ 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; }; @@ -3326,6 +3187,8 @@ 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; }; @@ -3385,163 +3248,6 @@ ); 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; @@ -3571,6 +3277,8 @@ 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; }; @@ -3629,6 +3337,7 @@ 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 */, @@ -3638,7 +3347,7 @@ 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 */, @@ -3651,9 +3360,24 @@ 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 */, + 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; }; @@ -3664,6 +3388,7 @@ 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; }; @@ -3689,6 +3414,7 @@ 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 */, @@ -3699,18 +3425,21 @@ 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 */, - 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 */, + 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 */, + B0C967F817441F0E00889853 /* SNHelperPrivate.h in Headers */, 157A88890A470D0F003A4256 /* SCSchemaDefinitionsPrivate.h in Headers */, F95B8A460B03E09300993BA3 /* SCNetworkSignature.h in Headers */, F95B8A470B03E09300993BA3 /* SCNetworkSignaturePrivate.h in Headers */, @@ -3718,8 +3447,22 @@ 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 */, + 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; }; @@ -3840,38 +3583,6 @@ 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" */; @@ -3967,6 +3678,64 @@ 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" */; @@ -4003,9 +3772,9 @@ productReference = 1574341A0D4A8137002ACA73 /* scutil */; productType = "com.apple.product-type.tool"; }; - 157A84D80D56C63900B6F1A0 /* DNSConfiguration-Embedded */ = { + 157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */ = { 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 */, @@ -4015,10 +3784,10 @@ ); dependencies = ( ); - name = "DNSConfiguration-Embedded"; + name = "libsystem_configuration-Embedded"; 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 */ = { @@ -4140,6 +3909,7 @@ buildConfigurationList = 158317800CFB85C8006F62B9 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-Embedded" */; buildPhases = ( 1583177E0CFB85C8006F62B9 /* Resources */, + 15D54E2515B4FA1900F5229A /* com.apple.networking.IPMonitor */, ); buildRules = ( ); @@ -4233,418 +4003,193 @@ productReference = 1559C4470D349A4E0098FD59 /* SCHelper */; productType = "com.apple.product-type.tool"; }; - 1583EA04108395BB00A3BC0C /* DNSConfiguration-EmbeddedOther */ = { + 159D53D307528BDA004F8947 /* KernelEventMonitor */ = { isa = PBXNativeTarget; - buildConfigurationList = 1583EA0D108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "DNSConfiguration-EmbeddedOther" */; + buildConfigurationList = 156EB6020905594A00EEF749 /* Build configuration list for PBXNativeTarget "KernelEventMonitor" */; buildPhases = ( - 1583EA05108395BB00A3BC0C /* Headers */, - 1583EA08108395BB00A3BC0C /* Sources */, - 1583EA0C108395BB00A3BC0C /* Frameworks */, + 159D53D007528BDA004F8947 /* Headers */, + 159D53D107528BDA004F8947 /* Sources */, ); 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; - buildConfigurationList = 1583EA96108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedOther" */; + buildConfigurationList = 156EB5F60905594A00EEF749 /* Build configuration list for PBXNativeTarget "InterfaceNamer" */; buildPhases = ( - 1583EA1A108395BB00A3BC0C /* Headers */, - 1583EA49108395BB00A3BC0C /* Update Headers */, - 1583EA4A108395BB00A3BC0C /* Resources */, - 1583EA4F108395BB00A3BC0C /* Sources */, - 1583EA93108395BB00A3BC0C /* Frameworks */, - 1583EA95108395BB00A3BC0C /* get-mobility-info */, + 159D53E107528C4A004F8947 /* Headers */, + 159D53E207528C4A004F8947 /* Sources */, ); 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; - buildConfigurationList = 1583EAA7108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "SCHelper-EmbeddedOther" */; + buildConfigurationList = 156EB5EE0905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor" */; buildPhases = ( - 1583EA9C108395BB00A3BC0C /* Headers */, - 1583EA9F108395BB00A3BC0C /* Sources */, - 1583EAA1108395BB00A3BC0C /* Frameworks */, - 1583EAA5108395BB00A3BC0C /* CopyFiles */, + 159D53E807528C61004F8947 /* Headers */, + 159D53E907528C61004F8947 /* Sources */, ); 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; - buildConfigurationList = 1583EAD5108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor-EmbeddedOther" */; + buildConfigurationList = 156EB60E0905594A00EEF749 /* Build configuration list for PBXNativeTarget "LinkConfiguration" */; buildPhases = ( - 1583EACB108395BB00A3BC0C /* Headers */, - 1583EACF108395BB00A3BC0C /* Sources */, + 159D53EF07528C79004F8947 /* Headers */, + 159D53F007528C79004F8947 /* Sources */, ); 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"; }; - 1583EAD9108395BB00A3BC0C /* IPMonitor.bundle-EmbeddedOther */ = { + 159D53F907528C95004F8947 /* PreferencesMonitor */ = { isa = PBXNativeTarget; - buildConfigurationList = 1583EADB108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "IPMonitor.bundle-EmbeddedOther" */; + buildConfigurationList = 156EB6160905594A00EEF749 /* Build configuration list for PBXNativeTarget "PreferencesMonitor" */; buildPhases = ( - 1583EADA108395BB00A3BC0C /* Resources */, + 159D53F607528C95004F8947 /* Headers */, + 159D53F707528C95004F8947 /* Sources */, ); 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; - buildConfigurationList = 1583EAE4108395BB00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer-EmbeddedOther" */; + buildConfigurationList = 156EB6220905594A00EEF749 /* Build configuration list for PBXNativeTarget "configd" */; buildPhases = ( - 1583EAE1108395BB00A3BC0C /* Headers */, - 1583EAE2108395BB00A3BC0C /* Sources */, + 159D54A307529FFF004F8947 /* Headers */, + 159D54AB07529FFF004F8947 /* Sources */, + 159D54CA07529FFF004F8947 /* Frameworks */, + 159D54D507529FFF004F8947 /* CopyFiles */, + 159D54D707529FFF004F8947 /* CopyFiles */, ); 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; - buildConfigurationList = 1583EAEA108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "InterfaceNamer.bundle-EmbeddedOther" */; + buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */; buildPhases = ( - 1583EAE9108395BC00A3BC0C /* Resources */, + 15A5A1E60D5B94190087BDA0 /* Headers */, + 15A5A2170D5B94190087BDA0 /* Update Headers */, + 15A5A2180D5B94190087BDA0 /* Resources */, + 15A5A21D0D5B94190087BDA0 /* Sources */, + 15A5A2620D5B94190087BDA0 /* Frameworks */, ); 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; - buildConfigurationList = 1583EAFC108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor-EmbeddedOther" */; + buildConfigurationList = 15AB751616EBFF3400FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedSimulator" */; buildPhases = ( - 1583EAF0108395BC00A3BC0C /* Headers */, - 1583EAF6108395BC00A3BC0C /* Sources */, + 15AB751316EBFF3400FAA8CE /* Headers */, + 15AB751416EBFF3400FAA8CE /* Sources */, ); 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"; }; - 1583EB00108395BC00A3BC0C /* KernelEventMonitor.bundle-EmbeddedOther */ = { + 15AB751A16EBFF8A00FAA8CE /* SCNetworkReachability.bundle-EmbeddedSimulator */ = { isa = PBXNativeTarget; - buildConfigurationList = 1583EB02108395BC00A3BC0C /* Build configuration list for PBXNativeTarget "KernelEventMonitor.bundle-EmbeddedOther" */; + buildConfigurationList = 15AB751C16EBFF8A00FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability.bundle-EmbeddedSimulator" */; buildPhases = ( - 1583EB01108395BC00A3BC0C /* Resources */, + 15AB751B16EBFF8A00FAA8CE /* Resources */, ); 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; - productReference = 1583EB3F108395BD00A3BC0C /* PreferencesMonitor.bundle */; + productReference = 15AB751F16EBFF8A00FAA8CE /* SCNetworkReachability.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; - buildConfigurationList = 156EB5EE0905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor" */; + buildConfigurationList = 15D3082416F3E4DA00014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport-EmbeddedSimulator" */; buildPhases = ( - 159D53E807528C61004F8947 /* Headers */, - 159D53E907528C61004F8947 /* Sources */, + 15D3081016F3E4DA00014F82 /* Headers */, + 15D3081816F3E4DA00014F82 /* Sources */, ); buildRules = ( ); dependencies = ( ); - name = IPMonitor; + name = "SimulatorSupport-EmbeddedSimulator"; 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"; }; - 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; - buildConfigurationList = 15A5A2660D5B94190087BDA0 /* Build configuration list for PBXNativeTarget "SystemConfiguration.framework-EmbeddedSimulator" */; + buildConfigurationList = 15D3082A16F3E4E100014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport.bundle-EmbeddedSimulator" */; buildPhases = ( - 15A5A1E60D5B94190087BDA0 /* Headers */, - 15A5A2170D5B94190087BDA0 /* Update Headers */, - 15A5A2180D5B94190087BDA0 /* Resources */, - 15A5A21D0D5B94190087BDA0 /* Sources */, - 15A5A2620D5B94190087BDA0 /* Frameworks */, + 15D3082916F3E4E100014F82 /* Resources */, ); 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; - buildConfigurationList = 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "DNSConfiguration" */; + buildConfigurationList = 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "libsystem_configuration" */; buildPhases = ( 15DAD5E0075913CE0084A6ED /* Headers */, 15DAD5E4075913CE0084A6ED /* Sources */, @@ -4654,10 +4199,10 @@ ); dependencies = ( ); - name = DNSConfiguration; + name = libsystem_configuration; 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 */ = { @@ -4671,7 +4216,7 @@ 15DAD66C07591A1A0084A6ED /* Sources */, 15DAD6AD07591A1A0084A6ED /* Frameworks */, 15DAD6B007591A1A0084A6ED /* get-mobility-info */, - 15D9DCF910DD909F004E545D /* CopyFiles */, + 15D9DCF910DD909F004E545D /* AppWorkaround.plist */, ); buildRules = ( ); @@ -4683,6 +4228,38 @@ 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" */; @@ -4704,6 +4281,7 @@ buildConfigurationList = 156EB5F20905594A00EEF749 /* Build configuration list for PBXNativeTarget "IPMonitor.bundle" */; buildPhases = ( 15FD72A20754DA4C001CC321 /* Resources */, + 15D54E2A15B4FAF100F5229A /* com.apple.networking.IPMonitor */, ); buildRules = ( ); @@ -4753,7 +4331,7 @@ 15CB6A7705C0722B0099E85F /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 0500; }; buildConfigurationList = 156EB63E0905594A00EEF749 /* Build configuration list for PBXProject "configd" */; compatibilityVersion = "Xcode 3.2"; @@ -4772,7 +4350,7 @@ targets = ( 15CB690005C0722A0099E85F /* All */, 15C64A1E0F684C3300D78394 /* configd_libSystem */, - 15DAD5DF075913CE0084A6ED /* DNSConfiguration */, + 15DAD5DF075913CE0084A6ED /* libsystem_configuration */, 157BB8AE075924360025DA7A /* configd_base */, 15DAD63F07591A1A0084A6ED /* SystemConfiguration.framework */, 1547001808455B98006787CE /* SCHelper */, @@ -4797,7 +4375,7 @@ 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 */, @@ -4820,33 +4398,20 @@ 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 */, + 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 */, - 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 */ @@ -4881,13 +4446,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1528C0081357401D00691881 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 156CA4810EF853BB00C59A18 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4948,127 +4506,95 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1583EA4A108395BB00A3BC0C /* Resources */ = { + 15A5A2180D5B94190087BDA0 /* Resources */ = { 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; }; - 1583EADA108395BB00A3BC0C /* Resources */ = { + 15AB751B16EBFF8A00FAA8CE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1583EAE9108395BC00A3BC0C /* Resources */ = { + 15D3082916F3E4E100014F82 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1583EB01108395BC00A3BC0C /* Resources */ = { + 15DAD66807591A1A0084A6ED /* Resources */ = { 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; }; - 1583EB10108395BC00A3BC0C /* Resources */ = { + 15E1B05B16EBAE7800E5F06F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1583EB1D108395BC00A3BC0C /* Resources */ = { + 15FD72940754DA2B001CC321 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1583EB3B108395BD00A3BC0C /* Resources */ = { + 15FD72A20754DA4C001CC321 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 15A5A2180D5B94190087BDA0 /* Resources */ = { + 15FD72B20754DA69001CC321 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 15A5A2190D5B94190087BDA0 /* Localizable.strings in Resources */, - 15A5A21A0D5B94190087BDA0 /* NetworkInterface.strings in Resources */, - 15A5A21B0D5B94190087BDA0 /* NetworkConfiguration.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 15DAD66807591A1A0084A6ED /* Resources */ = { + 15FD72C60754DA7E001CC321 /* Resources */ = { 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; }; - 15FD72940754DA2B001CC321 /* Resources */ = { - isa = PBXResourcesBuildPhase; +/* 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; - }; - 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; @@ -5083,7 +4609,7 @@ ); 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; @@ -5100,36 +4626,6 @@ 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; @@ -5143,7 +4639,7 @@ ); 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 */ = { @@ -5229,14 +4725,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 1528C0011357401900691881 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1528C0021357401900691881 /* SCNetworkReachabilityServer_server.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1547001A08455B98006787CE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -5264,6 +4752,7 @@ 155847600754FDCD0046C2E9 /* net_service.c in Sources */, 155847610754FDCD0046C2E9 /* net_set.c in Sources */, 72B43729113C7BFC00EBF1B6 /* nc.c in Sources */, + F9B50FF316A4CBB200CA274E /* IPMonitorControlPrefs.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5287,6 +4776,7 @@ 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 */, @@ -5312,6 +4802,7 @@ 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 */, @@ -5319,8 +4810,8 @@ 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 */, + 1572C5030CFB55B400E2776E /* SCPApply.c in Sources */, 1572C5060CFB55B400E2776E /* SCDHostName.c in Sources */, 1572C5070CFB55B400E2776E /* SCLocation.c in Sources */, 1572C5080CFB55B400E2776E /* SCNetwork.c in Sources */, @@ -5334,9 +4825,7 @@ 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 */, - 1572C5180CFB55B400E2776E /* shared_dns_info.defs in Sources */, 1572C5190CFB55B400E2776E /* SCNetworkConfigurationInternal.c in Sources */, 1572C51A0CFB55B400E2776E /* SCNetworkInterface.c in Sources */, 1572C51B0CFB55B400E2776E /* SCNetworkProtocol.c in Sources */, @@ -5353,7 +4842,76 @@ 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; }; @@ -5383,6 +4941,7 @@ 1574340B0D4A8137002ACA73 /* net_service.c in Sources */, 1574340C0D4A8137002ACA73 /* net_set.c in Sources */, 72B4372B113C7BFC00EBF1B6 /* nc.c in Sources */, + F9B50FF416A4CBB800CA274E /* IPMonitorControlPrefs.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5390,10 +4949,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 157A84DE0D56C63900B6F1A0 /* shared_dns_info.defs in Sources */, 157A84DF0D56C63900B6F1A0 /* dnsinfo_copy.c in Sources */, - 157A84E00D56C63900B6F1A0 /* dnsinfo_private.c in Sources */, D661C2F11368BB600030B977 /* network_information.c in Sources */, + 153338BD14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5403,11 +4961,15 @@ 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 */, + 153ACCA914E322D5005029A5 /* network_information_server.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; }; @@ -5476,9 +5038,7 @@ 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 */, - 1583174A0CFB80A1006F62B9 /* shared_dns_info.defs in Sources */, 15C330E5134BD2AC0028E36B /* SCNetworkReachabilityServer_server.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -5492,220 +5052,6 @@ ); 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; @@ -5733,12 +5079,16 @@ 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 */, + 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 */, - 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; }; @@ -5787,9 +5137,7 @@ 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 */, - 159D54C907529FFF004F8947 /* shared_dns_info.defs in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5846,9 +5194,6 @@ 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 */, @@ -5864,7 +5209,26 @@ 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; }; @@ -5872,10 +5236,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 15DAD5E5075913CE0084A6ED /* shared_dns_info.defs in Sources */, 15DAD5E6075913CE0084A6ED /* dnsinfo_copy.c in Sources */, - 15DAD5E7075913CE0084A6ED /* dnsinfo_private.c in Sources */, D6986A79136891650091C931 /* network_information.c in Sources */, + 153338BC14BE7978004FCE22 /* libSystemConfiguration_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5911,6 +5274,7 @@ 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 */, @@ -5935,7 +5299,6 @@ 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 */, @@ -5951,7 +5314,27 @@ 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; }; @@ -5993,16 +5376,6 @@ 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 */; @@ -6028,6 +5401,11 @@ 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 */; @@ -6078,6 +5456,11 @@ 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 */; @@ -6188,130 +5571,95 @@ 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; - target = 1583EA11108395BB00A3BC0C /* configd_base-EmbeddedOther */; - targetProxy = 15AC515A1083960E004A9ED5 /* PBXContainerItemProxy */; + target = 15AB751216EBFF3400FAA8CE /* SCNetworkReachability-EmbeddedSimulator */; + targetProxy = 15AB752116EC005A00FAA8CE /* PBXContainerItemProxy */; }; - 15AC515D10839613004A9ED5 /* PBXTargetDependency */ = { + 15AB752416EC005A00FAA8CE /* 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; - target = 1583EB41108395BD00A3BC0C /* configd_executables-EmbeddedOther */; - targetProxy = 15AC515E1083961E004A9ED5 /* PBXContainerItemProxy */; + target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */; + targetProxy = 15AB752916EC254D00FAA8CE /* PBXContainerItemProxy */; }; - 15AC516110839649004A9ED5 /* PBXTargetDependency */ = { + 15AB752C16EC254D00FAA8CE /* 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; - target = 1583EB32108395BD00A3BC0C /* PreferencesMonitor-EmbeddedOther */; - targetProxy = 15AC5172108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15DAD5DF075913CE0084A6ED /* libsystem_configuration */; + targetProxy = 15C64A210F684C4900D78394 /* PBXContainerItemProxy */; }; - 15AC5179108396D2004A9ED5 /* PBXTargetDependency */ = { + 15C64A240F684C5700D78394 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EB16108395BC00A3BC0C /* Logger.bundle-EmbeddedOther */; - targetProxy = 15AC5178108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15C64A1E0F684C3300D78394 /* configd_libSystem */; + targetProxy = 15C64A230F684C5700D78394 /* PBXContainerItemProxy */; }; - 15AC517B108396D2004A9ED5 /* PBXTargetDependency */ = { + 15C64A2F0F684C8300D78394 /* 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; - target = 1583EB07108395BC00A3BC0C /* LinkConfiguration-EmbeddedOther */; - targetProxy = 15AC517C108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 157A84D80D56C63900B6F1A0 /* libsystem_configuration-Embedded */; + targetProxy = 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */; }; - 15AC517F108396D2004A9ED5 /* PBXTargetDependency */ = { + 15D3083016F3EAD000014F82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EB00108395BC00A3BC0C /* KernelEventMonitor.bundle-EmbeddedOther */; - targetProxy = 15AC517E108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */; + targetProxy = 15D3082F16F3EAD000014F82 /* PBXContainerItemProxy */; }; - 15AC5181108396D2004A9ED5 /* PBXTargetDependency */ = { + 15D3083216F3EAD000014F82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EAEF108395BC00A3BC0C /* KernelEventMonitor-EmbeddedOther */; - targetProxy = 15AC5180108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15D3082816F3E4E100014F82 /* SimulatorSupport.bundle-EmbeddedSimulator */; + targetProxy = 15D3083116F3EAD000014F82 /* PBXContainerItemProxy */; }; - 15AC5183108396D2004A9ED5 /* PBXTargetDependency */ = { + 15D3083516F3EB2500014F82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EAE8108395BC00A3BC0C /* InterfaceNamer.bundle-EmbeddedOther */; - targetProxy = 15AC5182108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15D3080F16F3E4DA00014F82 /* SimulatorSupport-EmbeddedSimulator */; + targetProxy = 15D3083416F3EB2500014F82 /* PBXContainerItemProxy */; }; - 15AC5185108396D2004A9ED5 /* PBXTargetDependency */ = { + 15E1B03E16EBAB8A00E5F06F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EAE0108395BB00A3BC0C /* InterfaceNamer-EmbeddedOther */; - targetProxy = 15AC5184108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15732A7616EA503200F3AC4C /* configd-EmbeddedSimulator */; + targetProxy = 15E1B03D16EBAB8A00E5F06F /* PBXContainerItemProxy */; }; - 15AC5187108396D2004A9ED5 /* PBXTargetDependency */ = { + 15E1B04016EBAB9400E5F06F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EAD9108395BB00A3BC0C /* IPMonitor.bundle-EmbeddedOther */; - targetProxy = 15AC5186108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15732AAD16EA511900F3AC4C /* scutil-EmbeddedSimulator */; + targetProxy = 15E1B03F16EBAB9400E5F06F /* PBXContainerItemProxy */; }; - 15AC5189108396D2004A9ED5 /* PBXTargetDependency */ = { + 15E1B06416EBAF2A00E5F06F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 1583EACA108395BB00A3BC0C /* IPMonitor-EmbeddedOther */; - targetProxy = 15AC5188108396D2004A9ED5 /* PBXContainerItemProxy */; + target = 15E1B04116EBAE3C00E5F06F /* IPMonitor-EmbeddedSimulator */; + targetProxy = 15E1B06316EBAF2A00E5F06F /* PBXContainerItemProxy */; }; - 15C64A220F684C4900D78394 /* PBXTargetDependency */ = { + 15E1B06616EBAF2A00E5F06F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 15DAD5DF075913CE0084A6ED /* DNSConfiguration */; - targetProxy = 15C64A210F684C4900D78394 /* PBXContainerItemProxy */; + target = 15E1B05A16EBAE7800E5F06F /* IPMonitor.bundle-EmbeddedSimulator */; + targetProxy = 15E1B06516EBAF2A00E5F06F /* PBXContainerItemProxy */; }; - 15C64A240F684C5700D78394 /* PBXTargetDependency */ = { + 15E83109167F9B0600FD51EC /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 15C64A1E0F684C3300D78394 /* configd_libSystem */; - targetProxy = 15C64A230F684C5700D78394 /* PBXContainerItemProxy */; + target = 15CB690005C0722A0099E85F /* All */; + targetProxy = 15E83108167F9B0600FD51EC /* PBXContainerItemProxy */; }; - 15C64A2F0F684C8300D78394 /* PBXTargetDependency */ = { + 15E8310B167F9B0C00FD51EC /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 15C64A280F684C6B00D78394 /* configd_libSystem-Embedded */; - targetProxy = 15C64A2E0F684C8300D78394 /* PBXContainerItemProxy */; + target = 151C1CC60CFB487000C5AFD6 /* All-Embedded */; + targetProxy = 15E8310A167F9B0C00FD51EC /* PBXContainerItemProxy */; }; - 15C64A310F684C8F00D78394 /* PBXTargetDependency */ = { + 15E8310D167F9B1200FD51EC /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 157A84D80D56C63900B6F1A0 /* DNSConfiguration-Embedded */; - targetProxy = 15C64A300F684C8F00D78394 /* PBXContainerItemProxy */; + target = 15FD13BF0D59485000F9409C /* All-EmbeddedSimulator */; + targetProxy = 15E8310C167F9B1200FD51EC /* PBXContainerItemProxy */; }; D6DDAC3D147A24BC00A2E902 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -6350,7 +5698,6 @@ /* Begin XCBuildConfiguration section */ 151C1CC70CFB487000C5AFD6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd (Aggregate/Embedded)"; }; @@ -6358,7 +5705,6 @@ }; 151C1CC80CFB487000C5AFD6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd (Aggregate/Embedded)"; }; @@ -6367,6 +5713,7 @@ 151F5D9C0CCE98E60093AC3B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "-"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; @@ -6374,6 +5721,7 @@ INSTALL_MODE_FLAG = "a-w,a+rX"; INSTALL_PATH = /System/Library/UserEventPlugins; PRODUCT_NAME = SCMonitor; + PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = plugin; }; name = Debug; @@ -6381,6 +5729,7 @@ 151F5D9D0CCE98E60093AC3B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "-"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; @@ -6388,6 +5737,7 @@ INSTALL_MODE_FLAG = "a-w,a+rX"; INSTALL_PATH = /System/Library/UserEventPlugins; PRODUCT_NAME = SCMonitor; + PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = plugin; }; name = Release; @@ -6502,143 +5852,112 @@ }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Release; }; - 1528C0041357401900691881 /* Debug */ = { + 156CA4830EF853BB00C59A18 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist"; 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; }; - 1528C0051357401900691881 /* Release */ = { + 156CA4840EF853BB00C59A18 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = "Plugins/Logger/Info-Embedded.plist"; 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; }; - 1528C00B1357401D00691881 /* Debug */ = { + 156EB5DB0905594A00EEF749 /* 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; - }; - 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; - 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 = ( - "-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; @@ -6657,17 +5976,28 @@ 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 = ( - "-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; @@ -6681,7 +6011,10 @@ "$(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"; @@ -6699,7 +6032,10 @@ "$(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"; @@ -6723,7 +6059,7 @@ 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; @@ -6735,7 +6071,7 @@ 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; @@ -6995,7 +6331,6 @@ 156EB6230905594A00EEF749 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -7011,7 +6346,6 @@ 156EB6240905594A00EEF749 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -7027,10 +6361,9 @@ 156EB6270905594A00EEF749 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; 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; }; @@ -7039,10 +6372,9 @@ 156EB6280905594A00EEF749 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; 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; }; @@ -7051,7 +6383,6 @@ 156EB62B0905594A00EEF749 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -7067,7 +6398,6 @@ 156EB62C0905594A00EEF749 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "-"; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -7121,12 +6451,11 @@ 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", - "-fstack-protector", + "-fstack-protector-all", "-D_FORTIFY_SOURCE=2", ); RUN_CLANG_STATIC_ANALYZER = YES; @@ -7150,12 +6479,11 @@ 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", - "-fstack-protector", + "-fstack-protector-all", "-D_FORTIFY_SOURCE=2", ); VERSIONING_SYSTEM = "apple-generic"; @@ -7171,61 +6499,221 @@ }; 1572C52A0CFB55B400E2776E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; WRAPPER_EXTENSION = framework; }; name = Debug; }; 1572C52B0CFB55B400E2776E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; 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; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; - INSTALL_MODE_FLAG = "a-w,a+rX,u+s"; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = scselect; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Debug; }; 157433EA0D4A8122002ACA73 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; - INSTALL_MODE_FLAG = "a-w,a+rX,u+s"; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = scselect; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Release; }; 157434170D4A8137002ACA73 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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 = ( @@ -7233,14 +6721,18 @@ "$(SDKROOT)/usr/local/lib/SystemConfiguration", ); PRODUCT_NAME = scutil; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Debug; }; 157434180D4A8137002ACA73 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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 = ( @@ -7248,12 +6740,13 @@ "$(SDKROOT)/usr/local/lib/SystemConfiguration", ); PRODUCT_NAME = scutil; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Release; }; 157A84E50D56C63900B6F1A0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { BUILD_VARIANTS = ( normal, @@ -7264,26 +6757,39 @@ 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 = ( - "-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; + SUPPORTED_PLATFORMS = iphoneos; }; name = Debug; }; 157A84E60D56C63900B6F1A0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { BUILD_VARIANTS = ( normal, @@ -7294,26 +6800,39 @@ 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 = ( - "-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; + SUPPORTED_PLATFORMS = iphoneos; }; 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"; @@ -7321,13 +6840,14 @@ INSTALL_PATH = /usr/local/lib/SystemConfiguration; LIBRARY_STYLE = STATIC; PRODUCT_NAME = IPMonitor; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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"; @@ -7335,39 +6855,42 @@ INSTALL_PATH = /usr/local/lib/SystemConfiguration; LIBRARY_STYLE = STATIC; PRODUCT_NAME = IPMonitor; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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"; @@ -7375,13 +6898,14 @@ INSTALL_PATH = /usr/local/lib/SystemConfiguration; LIBRARY_STYLE = STATIC; PRODUCT_NAME = KernelEventMonitor; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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"; @@ -7389,65 +6913,88 @@ INSTALL_PATH = /usr/local/lib/SystemConfiguration; LIBRARY_STYLE = STATIC; PRODUCT_NAME = KernelEventMonitor; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; 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; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_base (Embedded)"; }; @@ -7455,7 +7002,6 @@ }; 158316DA0CFB774B006F62B9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_base (Embedded)"; }; @@ -7463,7 +7009,6 @@ }; 158317010CFB7761006F62B9 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_plugins (Embedded)"; }; @@ -7471,7 +7016,6 @@ }; 158317020CFB7761006F62B9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_plugins (Embedded)"; }; @@ -7479,7 +7023,6 @@ }; 1583170C0CFB7782006F62B9 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_executables (Embedded)"; }; @@ -7487,7 +7030,6 @@ }; 1583170D0CFB7782006F62B9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { PRODUCT_NAME = "configd_executables (Embedded)"; }; @@ -7495,10 +7037,10 @@ }; 1583175E0CFB80A1006F62B9 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; @@ -7507,15 +7049,17 @@ "$(SDKROOT)/usr/local/lib/SystemConfiguration", ); PRODUCT_NAME = configd; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Debug; }; 1583175F0CFB80A1006F62B9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; @@ -7524,762 +7068,392 @@ "$(SDKROOT)/usr/local/lib/SystemConfiguration", ); PRODUCT_NAME = configd; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; 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; + SDKROOT = iphoneos.internal; + SUPPORTED_PLATFORMS = iphoneos; }; name = Release; }; - 1583E9EA1083959E00A3BC0C /* Debug */ = { + 15A5A2670D5B94190087BDA0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583E9EB1083959E00A3BC0C /* Release */ = { + 15A5A2680D5B94190087BDA0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583EA02108395BB00A3BC0C /* Debug */ = { + 15AB751716EBFF3400FAA8CE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583EA03108395BB00A3BC0C /* Release */ = { + 15AB751816EBFF3400FAA8CE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583EA0E108395BB00A3BC0C /* Debug */ = { + 15AB751D16EBFF8A00FAA8CE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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_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; }; - 1583EA0F108395BB00A3BC0C /* Release */ = { + 15AB751E16EBFF8A00FAA8CE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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_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; }; - 1583EB49108395BD00A3BC0C /* Debug */ = { + 15C64A1F0F684C3300D78394 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - PRODUCT_NAME = "configd_executables (EmbeddedOther)"; + INSTALL_PATH = /usr/local/lib/system; + PRODUCT_NAME = configd_libSystem; }; name = Debug; }; - 1583EB4A108395BD00A3BC0C /* Release */ = { + 15C64A200F684C3300D78394 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - PRODUCT_NAME = "configd_executables (EmbeddedOther)"; + INSTALL_PATH = /usr/local/lib/system; + PRODUCT_NAME = configd_libSystem; }; name = Release; }; - 1583EB82108395BD00A3BC0C /* Debug */ = { + 15C64A2C0F684C6B00D78394 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; }; - 1583EB83108395BD00A3BC0C /* Release */ = { + 15C64A2D0F684C6B00D78394 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; 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; }; - 1583EB8E108395BE00A3BC0C /* Debug */ = { + 15D3082516F3E4DA00014F82 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583EB8F108395BE00A3BC0C /* Release */ = { + 15D3082616F3E4DA00014F82 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 1583EBB4108395BE00A3BC0C /* Debug */ = { + 15D3082B16F3E4E100014F82 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; + INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist; 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; }; - 1583EBB5108395BE00A3BC0C /* Release */ = { + 15D3082C16F3E4E100014F82 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; + INFOPLIST_FILE = Plugins/SimulatorSupport/Info.plist; 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; }; - 15A5A2670D5B94190087BDA0 /* Debug */ = { + 15E1B05716EBAE3C00E5F06F /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; 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_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; }; - 15A5A2680D5B94190087BDA0 /* Release */ = { + 15E1B05816EBAE3C00E5F06F /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; 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_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; }; - 15C64A1F0F684C3300D78394 /* Debug */ = { + 15E1B05F16EBAE7800E5F06F /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 15C64A200F684C3300D78394 /* Release */ = { + 15E1B06016EBAE7800E5F06F /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 15FD147B0D594FE700F9409C /* IndigoSDK.xcconfig */; 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; }; - 15C64A2C0F684C6B00D78394 /* Debug */ = { + 15E83105167F9AF600FD51EC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - INSTALL_PATH = /usr/local/lib/system; - PRODUCT_NAME = "configd_libSystem (Embedded)"; + PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - 15C64A2D0F684C6B00D78394 /* Release */ = { + 15E83106167F9AF600FD51EC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15AEABBC0DAD5B3000D1C969 /* AspenSDK.xcconfig */; buildSettings = { - INSTALL_PATH = /usr/local/lib/system; - PRODUCT_NAME = "configd_libSystem (Embedded)"; + PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; @@ -8383,24 +7557,6 @@ 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 = ( @@ -8410,7 +7566,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "DNSConfiguration" */ = { + 156EB5DA0905594A00EEF749 /* Build configuration list for PBXNativeTarget "libsystem_configuration" */ = { isa = XCConfigurationList; buildConfigurations = ( 156EB5DB0905594A00EEF749 /* Debug */, @@ -8608,6 +7764,33 @@ 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 = ( @@ -8626,7 +7809,7 @@ 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 */, @@ -8680,6 +7863,15 @@ 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 = ( @@ -8770,227 +7962,92 @@ 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 = ( - 1583EB1F108395BC00A3BC0C /* Debug */, - 1583EB20108395BC00A3BC0C /* Release */, + 15A5A2670D5B94190087BDA0 /* Debug */, + 15A5A2680D5B94190087BDA0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 1583EB36108395BD00A3BC0C /* Build configuration list for PBXNativeTarget "PreferencesMonitor-EmbeddedOther" */ = { + 15AB751616EBFF3400FAA8CE /* Build configuration list for PBXNativeTarget "SCNetworkReachability-EmbeddedSimulator" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1583EB37108395BD00A3BC0C /* Debug */, - 1583EB38108395BD00A3BC0C /* Release */, + 15AB751716EBFF3400FAA8CE /* Debug */, + 15AB751816EBFF3400FAA8CE /* 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 = ( - 1583EB3D108395BD00A3BC0C /* Debug */, - 1583EB3E108395BD00A3BC0C /* Release */, + 15AB751D16EBFF8A00FAA8CE /* Debug */, + 15AB751E16EBFF8A00FAA8CE /* 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 = ( - 1583EB49108395BD00A3BC0C /* Debug */, - 1583EB4A108395BD00A3BC0C /* Release */, + 15C64A1F0F684C3300D78394 /* Debug */, + 15C64A200F684C3300D78394 /* 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 = ( - 1583EB82108395BD00A3BC0C /* Debug */, - 1583EB83108395BD00A3BC0C /* Release */, + 15C64A2C0F684C6B00D78394 /* Debug */, + 15C64A2D0F684C6B00D78394 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 1583EB8D108395BE00A3BC0C /* Build configuration list for PBXNativeTarget "scselect-EmbeddedOther" */ = { + 15D3082416F3E4DA00014F82 /* Build configuration list for PBXNativeTarget "SimulatorSupport-EmbeddedSimulator" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1583EB8E108395BE00A3BC0C /* Debug */, - 1583EB8F108395BE00A3BC0C /* Release */, + 15D3082516F3E4DA00014F82 /* Debug */, + 15D3082616F3E4DA00014F82 /* 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 = ( - 1583EBB4108395BE00A3BC0C /* Debug */, - 1583EBB5108395BE00A3BC0C /* Release */, + 15D3082B16F3E4E100014F82 /* Debug */, + 15D3082C16F3E4E100014F82 /* 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 = ( - 15A5A2670D5B94190087BDA0 /* Debug */, - 15A5A2680D5B94190087BDA0 /* Release */, + 15E1B05716EBAE3C00E5F06F /* Debug */, + 15E1B05816EBAE3C00E5F06F /* 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 = ( - 15C64A1F0F684C3300D78394 /* Debug */, - 15C64A200F684C3300D78394 /* Release */, + 15E1B05F16EBAE7800E5F06F /* Debug */, + 15E1B06016EBAE7800E5F06F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 15C64A2B0F684C6B00D78394 /* Build configuration list for PBXAggregateTarget "configd_libSystem-Embedded" */ = { + 15E83107167F9AF600FD51EC /* Build configuration list for PBXAggregateTarget "EVERYTHING" */ = { isa = XCConfigurationList; buildConfigurations = ( - 15C64A2C0F684C6B00D78394 /* Debug */, - 15C64A2D0F684C6B00D78394 /* Release */, + 15E83105167F9AF600FD51EC /* Debug */, + 15E83106167F9AF600FD51EC /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/dnsinfo/dnsinfo.h b/dnsinfo/dnsinfo.h index 020e51a..60be01a 100644 --- a/dnsinfo/dnsinfo.h +++ b/dnsinfo/dnsinfo.h @@ -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@ * @@ -35,7 +35,7 @@ #include #include -#define DNSINFO_VERSION 20111104 +#define DNSINFO_VERSION 20130402 #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, reserved[5]); + DNS_VAR(uint32_t, service_identifier); + DNS_VAR(uint32_t, reserved[4]); } 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 { @@ -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_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() diff --git a/dnsinfo/dnsinfo_copy.c b/dnsinfo/dnsinfo_copy.c index 26b1e9d..ee0a17a 100644 --- a/dnsinfo/dnsinfo_copy.c +++ b/dnsinfo/dnsinfo_copy.c @@ -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@ * @@ -33,43 +33,15 @@ #include #include #include +#include +#include +#include "libSystemConfiguration_client.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; -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) { @@ -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 -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) { @@ -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); + // initialize service_identifier + + resolver->service_identifier = ntohl(resolver->service_identifier); + // 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)) { - int32_t attribute_length = ntohl(attribute->length); + uint32_t attribute_length = ntohl(attribute->length); 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; + int32_t n_service_specific_resolver = 0; void *padding; // establish padding @@ -392,6 +237,15 @@ expand_config(_dns_config_buf_t *buf) 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); @@ -403,7 +257,8 @@ expand_config(_dns_config_buf_t *buf) 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 @@ -420,8 +275,10 @@ expand_config(_dns_config_buf_t *buf) 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; + } else if (attribute_type == CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER) { + config->service_specific_resolver[n_service_specific_resolver++] = resolver; } break; @@ -443,6 +300,10 @@ expand_config(_dns_config_buf_t *buf) goto error; } + if (n_service_specific_resolver != config->n_service_specific_resolver) { + goto error; + } + return config; error : @@ -456,29 +317,124 @@ dns_configuration_notify_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; } +#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_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; } - 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; @@ -489,9 +445,17 @@ void 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; } @@ -500,6 +464,34 @@ dns_configuration_free(dns_config_t *config) 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; } @@ -512,7 +504,7 @@ main(int argc, char **argv) config = dns_configuration_copy(); if (config != NULL) { - dns_configuration_free(&config); + dns_configuration_free(config); } exit(0); diff --git a/dnsinfo/dnsinfo_create.c b/dnsinfo/dnsinfo_create.c index db361d5..9bc5499 100644 --- a/dnsinfo/dnsinfo_create.c +++ b/dnsinfo/dnsinfo_create.c @@ -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@ * @@ -25,13 +25,18 @@ #include #include #include +#include #include +#include +#include +#include #include "dnsinfo_create.h" #include "dnsinfo_private.h" -#include "shared_dns_info.h" #include "network_information_priv.h" +#include "ip_plugin.h" + #define ROUNDUP(a, size) \ (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) @@ -51,12 +56,14 @@ */ +__private_extern__ 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; @@ -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) @@ -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; + /* + * 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 @@ -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)); } - 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_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 { - 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_ATTRIBUTE_SCOPED_RESOLVER, + CONFIG_ATTRIBUTE_RESOLVER, 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; } -_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, @@ -191,9 +192,13 @@ _dns_configuration_signature(dns_create_config_t *_config, if (config != NULL) { CC_SHA1_CTX ctx; + uint64_t generation_save; 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, @@ -203,46 +208,16 @@ _dns_configuration_signature(dns_create_config_t *_config, 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) { @@ -258,6 +233,7 @@ _dns_configuration_free(dns_create_config_t *_config) * DNS resolver configuration functions */ +__private_extern__ dns_create_resolver_t _dns_resolver_create() { @@ -296,7 +272,7 @@ _dns_resolver_add_attribute(dns_create_resolver_t *_resolver, // 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); @@ -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) { + uint32_t new_flags = 0; + uint32_t old_flags; _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); + + 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; } +__private_extern__ 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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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; } +__private_extern__ 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) { diff --git a/dnsinfo/dnsinfo_create.h b/dnsinfo/dnsinfo_create.h index 89c71b5..decc575 100644 --- a/dnsinfo/dnsinfo_create.h +++ b/dnsinfo/dnsinfo_create.h @@ -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@ * @@ -49,110 +49,86 @@ typedef const struct __dns_create_resolver * dns_create_resolver_t; __BEGIN_DECLS -/* - * NOTE: __private_extern__ and __OSX_AVAILABLE_STARTING() cannot be mixed - * due to a "visibility" conflict - */ - /* * DNS configuration creation APIs */ -__private_extern__ 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, - 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, - 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 -_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 */ -__private_extern__ 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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 -_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 -_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 -_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 */ -__private_extern__ 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 diff --git a/dnsinfo/dnsinfo_flatfile.c b/dnsinfo/dnsinfo_flatfile.c index e052d2e..65861b7 100644 --- a/dnsinfo/dnsinfo_flatfile.c +++ b/dnsinfo/dnsinfo_flatfile.c @@ -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@ * @@ -39,6 +39,8 @@ #include "dnsinfo_private.h" #include "dnsinfo_create.h" +static uint32_t _dnsinfo_flatfile_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 * @@ -243,6 +273,7 @@ static dns_create_resolver_t _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; @@ -339,20 +370,18 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path) } case TOKEN_FLAGS: { - uint32_t flags = 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); } - - if (flags != 0) { - _dns_resolver_set_flags(&res, flags); - } break; } @@ -480,6 +509,15 @@ _dnsinfo_flatfile_create_resolver(const char *dir, const char *path) _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); @@ -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. */ +__private_extern__ 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 index 0000000..a7dc643 --- /dev/null +++ b/dnsinfo/dnsinfo_internal.h @@ -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 +#include +#include +#include +#include +#include "SCNetworkReachabilityInternal.h" +#include + +#include + +__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 index f7b256f..0000000 --- a/dnsinfo/dnsinfo_private.c +++ /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 - * - initial revision - */ - -#include -#include -#include -#include -#include -#include - -#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; -} - diff --git a/dnsinfo/dnsinfo_private.h b/dnsinfo/dnsinfo_private.h index 58128a8..d6e65b5 100644 --- a/dnsinfo/dnsinfo_private.h +++ b/dnsinfo/dnsinfo_private.h @@ -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@ * @@ -72,6 +72,15 @@ * | | | | | | 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" @@ -152,6 +161,7 @@ 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_IF_INDEX, - RESOLVER_ATTRIBUTE_FLAGS, RESOLVER_ATTRIBUTE_OPTIONS, }; @@ -197,19 +205,6 @@ typedef struct { __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__ */ diff --git a/dnsinfo/dnsinfo_server.c b/dnsinfo/dnsinfo_server.c index 1d8bcac..9a3e588 100644 --- a/dnsinfo/dnsinfo_server.c +++ b/dnsinfo/dnsinfo_server.c @@ -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@ * @@ -37,151 +37,448 @@ #include #include #include +#include +#include #include #include +#include "libSystemConfiguration_client.h" +#include "libSystemConfiguration_server.h" + +#include "dnsinfo_create.h" #include "dnsinfo_server.h" #include "dnsinfo_private.h" -#include -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__ -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__ -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 */ diff --git a/dnsinfo/dnsinfo_server.h b/dnsinfo/dnsinfo_server.h index 7483a3e..53b7779 100644 --- a/dnsinfo/dnsinfo_server.h +++ b/dnsinfo/dnsinfo_server.h @@ -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@ * @@ -25,34 +25,25 @@ #define _S_DNSINFO_SERVER_H #include +#include #include #include +#include -#include "shared_dns_info_types.h" +#include "dnsinfo_create.h" + +typedef void (^_dns_sync_handler_t)(Boolean inSync); __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 diff --git a/dnsinfo/shared_dns_info.defs b/dnsinfo/shared_dns_info.defs deleted file mode 100644 index 4a24c43..0000000 --- a/dnsinfo/shared_dns_info.defs +++ /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 - * - initial revision - */ - -#include -#include - -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/get-mobility-info b/get-mobility-info index 818391c..a0b66a9 100755 --- a/get-mobility-info +++ b/get-mobility-info @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2004-2012 Apple Inc. +# Copyright (c) 2004-2013 Apple Inc. # # get-mobility-info # @@ -13,12 +13,20 @@ if [ ${EUID} -ne 0 ]; then 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 - OUTDIR=/Library/Logs/CrashReporter/SystemConfiguration + OUTDIR=/Library/Logs/CrashReporter mkdir -p ${OUTDIR} fi @@ -50,35 +58,63 @@ 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 # -ps axlww > ps 2>&1 +if [ -x /bin/ps ]; then + /bin/ps axlww > ps 2>&1 +fi # # 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 # -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 # -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 @@ -88,6 +124,22 @@ if [ -x /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport > 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 # @@ -103,41 +155,34 @@ fi # # 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 # -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 # -hostname > hostname 2>&1 +if [ -x /bin/hostname ]; then + /bin/hostname > hostname 2>&1 +fi # # 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 @@ -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 /etc/resolver ]; then + tar -c -H /etc/resolver > etc.resolver.tar 2>/dev/null +fi # # Proxy configuration @@ -161,7 +209,20 @@ scutil -d -v --proxy > proxy-configuration 2>&1 # # 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 @@ -185,6 +246,27 @@ do 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 # @@ -216,211 +298,154 @@ if [ -f /var/tmp/configd-reachability ]; then 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 -# -# 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 - kextstat > kextstat 2>&1 + /usr/sbin/kextstat > kextstat 2>&1 elif [ -x /usr/sbin/kmodstat ]; then - kmodstat > kmodstat 2>&1 + /usr/sbin/kmodstat > kmodstat 2>&1 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 - 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 - 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 - 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 - ${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 - echo "# ip6fw -at show" >> network-statistics + echo "# ip6fw -at show" >> 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 - ${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 - ${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 - ${PRIV} pfctl -a ${ANCHOR} -s all >> pf 2>&1 + ${PRIV} /sbin/pfctl -a ${ANCHOR} -s all >> pf 2>&1 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 - ${PRIV} lsof -i -U -n -P >> network-statistics 2>&1 + ${PRIV} /usr/sbin/lsof -i -U -n -P >> network-statistics 2>&1 fi # @@ -438,425 +463,390 @@ if [ -x /usr/bin/odutil ]; then 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 - 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 - 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 - dscacheutil -cachedump -entries >> ds-info 2>&1 + /usr/bin/dscacheutil -cachedump -entries >> ds-info 2>&1 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", $_; } - ' >> 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 - 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 - ${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 "# klist -e -k -t -K" >> kerberos + echo "# gsstool list --verbose" >> 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 # -# 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 =\"\(.*\)\"/\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 -} -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 - return + if [ ${BOOL} = "TRUE" ]; then + ENABLED="Enabled*" + else + ENABLED="Disabled" + 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 - - 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 - URLISH=`BTMM_URLISH "${DOMAIN}"` - ACCOUNT=`cat .btmminfo | sed -n 's/.*\"acct\"=\"\(.*\)\"/\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 - 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\"=\"\(.*\)\"/\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 -show Setup:/Network/BackToMyMac +show Setup:/Network/Service/[^/]+/PPP pattern quit _END_OF_INPUT do - BTMM_REPORTZONE "$DOMAIN" + if [ -f "${logFile}" ]; then + b="`basename ${logFile}`" + cat "${logFile}" > "${b}" 2>&1 + fi 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}`" - ${PRIV} cat "${log}" > "${b}" 2>&1 + ${PRIV} cat "${log}" > "${b}" 2>&1 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 -# -# 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}/.." -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 @@ -869,10 +859,3 @@ fi 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 index 0000000..5023329 --- /dev/null +++ b/libSystemConfiguration/libSystemConfiguration_client.c @@ -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 +#include +#include +#include +#include +#include +#include + +#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 index 0000000..c93d477 --- /dev/null +++ b/libSystemConfiguration/libSystemConfiguration_client.h @@ -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 +#include +#include +#include +#include + +// ------------------------------------------------------------ + +#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 index 0000000..82a201a --- /dev/null +++ b/libSystemConfiguration/libSystemConfiguration_server.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 index 0000000..4093bb7 --- /dev/null +++ b/libSystemConfiguration/libSystemConfiguration_server.h @@ -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 +#include +#include +#include +#include +#include + +// ------------------------------------------------------------ + +#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 diff --git a/nwi/network_information.c b/nwi/network_information.c index 18b4c6b..4153c00 100644 --- a/nwi/network_information.c +++ b/nwi/network_information.c @@ -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@ * @@ -27,6 +27,10 @@ #include #include #include +#include +#include + +#include "libSystemConfiguration_client.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 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) @@ -57,7 +83,7 @@ _nwi_state_initialize(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; @@ -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++) { - 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: @@ -105,12 +135,23 @@ _nwi_state_reset_alias(nwi_state_t state) { const char * nwi_state_get_notify_key() { +#if !TARGET_IPHONE_SIMULATOR 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); +void +_nwi_state_force_refresh() +{ + ATOMIC_CMPXCHG(&nwi_store_force_refresh, FALSE, TRUE); +} + 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) { - 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; } +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: @@ -141,12 +272,15 @@ nwi_state_release(nwi_state_t state) 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); + force_refresh = ATOMIC_CMPXCHG(&nwi_store_force_refresh, TRUE, FALSE); + if (G_nwi_state != NULL) { int check = 0; uint32_t status; @@ -164,7 +298,7 @@ nwi_state_copy(void) check = 1; } } - if (check != 0) { + if (check != 0 || force_refresh) { /* 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) { - 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); @@ -202,6 +336,34 @@ nwi_state_copy(void) 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; } @@ -218,6 +380,17 @@ nwi_state_get_generation(nwi_state_t state) 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: @@ -370,3 +543,238 @@ nwi_ifstate_compare_rank(nwi_ifstate_t ifstate1, nwi_ifstate_t ifstate2) { 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 diff --git a/nwi/network_information.h b/nwi/network_information.h index 418b304..7c364fc 100644 --- a/nwi/network_information.h +++ b/nwi/network_information.h @@ -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@ * @@ -26,10 +26,13 @@ #define _NETWORK_INFORMATION_H_ #include +#include typedef struct _nwi_state * nwi_state_t; typedef struct _nwi_ifstate * nwi_ifstate_t; +__BEGIN_DECLS + /* * 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: - * 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); +/* + * 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: @@ -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_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 diff --git a/nwi/network_information_priv.c b/nwi/network_information_priv.c index 7dfc706..af1f1ba 100644 --- a/nwi/network_information_priv.c +++ b/nwi/network_information_priv.c @@ -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@ * @@ -22,16 +22,18 @@ */ #include +#include #include #include #include #include -#include #include #include "network_information_priv.h" #include +#include -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) @@ -55,6 +57,7 @@ nwi_state_copy_priv(nwi_state_t src) bcopy(src, dest, src->size); dest->ref = 1; + dest->svr = FALSE; } return dest; } @@ -86,6 +89,7 @@ nwi_state_new(nwi_state_t old_state, int elems) return NULL; } + bzero(state, 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; - 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; + state->svr = FALSE; 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; - 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]; - } __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, - const char* ifname, int af, + const char * ifname, int af, uint64_t flags, Rank rank, - void* ifa) + void * ifa, + struct sockaddr * vpn_server_addr, + uint32_t reach_flags) { 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) { - 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); - strcpy(ifstate->ifname, ifname); - ifstate->af_alias = NULL; + bzero(ifstate, sizeof(*ifstate)); + strlcpy(ifstate->ifname, ifname, sizeof(ifstate->ifname)); ifstate->af = af; - ifstate->diff_ch = NULL; (*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; - return; + return ifstate; } __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 */ - 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].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, ""); - 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 rank_change "R" __private_extern__ void * @@ -305,7 +267,10 @@ __private_extern__ 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 @@ -313,10 +278,6 @@ inline 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; } @@ -350,85 +311,116 @@ nwi_ifstate_append(nwi_state_t state, nwi_ifstate_t scan) 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 -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; } -static void nwi_state_merge_removed(nwi_state_t state, nwi_state_t old_state) { - int idx; + int i; 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) @@ -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); - /* 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; } +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; +} diff --git a/nwi/network_information_priv.h b/nwi/network_information_priv.h index 3eb3c12..5ea1ded 100644 --- a/nwi/network_information_priv.h +++ b/nwi/network_information_priv.h @@ -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@ * @@ -24,7 +24,9 @@ #ifndef _NETWORK_INFORMATION_PRIV_H_ #define _NETWORK_INFORMATION_PRIV_H_ +#include #include +#include #include #include #include @@ -32,25 +34,40 @@ #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_HAS_SIGNATURE 0x10 + +#define NWI_PTR(type, name) \ + union { \ + type name; \ + uint64_t _ ## name ## _p; \ + } typedef uint32_t Rank; +#pragma pack(4) 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 { - 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; +#pragma pack() /* * nwi_state @@ -71,7 +88,16 @@ typedef struct _nwi_ifstate { *| 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 | | @@ -92,21 +118,26 @@ typedef struct _nwi_ifstate { *|---------------------------------------------+ * */ +#pragma pack(4) 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; +#pragma pack() static __inline__ int uint32_cmp(uint32_t a, uint32_t b) { int ret; - + if (a == b) { ret = 0; } @@ -203,50 +234,73 @@ nwi_state_get_ifstate_with_name(nwi_state_t state, 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); -__private_extern__ 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, - 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); -__private_extern__ 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); -__private_extern__ void * nwi_ifstate_get_address(nwi_ifstate_t ifstate); -__private_extern__ 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 -_nwi_state_dump(int level, nwi_state_t state); +_nwi_state_force_refresh(); #endif diff --git a/nwi/network_information_server.c b/nwi/network_information_server.c new file mode 100644 index 0000000..00c9ff3 --- /dev/null +++ b/nwi/network_information_server.c @@ -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 + * - initial revision + */ + +#include +#include +#include +#include +#include +#include + +#include "libSystemConfiguration_client.h" +#include "libSystemConfiguration_server.h" + +#include +#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 index 0000000..bdd8b34 --- /dev/null +++ b/nwi/network_information_server.h @@ -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 +#include +#include +#include +#include + +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 */ diff --git a/scselect.tproj/scselect.c b/scselect.tproj/scselect.c index 4d9e278..a5319b7 100644 --- a/scselect.tproj/scselect.c +++ b/scselect.tproj/scselect.c @@ -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@ * @@ -49,7 +49,7 @@ #include #if !TARGET_OS_IPHONE -#include +#include #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) { @@ -179,6 +91,13 @@ main(int argc, char **argv) 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) { @@ -228,12 +147,37 @@ main(int argc, char **argv) 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); } +#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) { @@ -330,35 +274,43 @@ main(int argc, char **argv) break; } + CFRelease(prefix); 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, - CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"), + CFSTR("SCPreferencesSetValue(...,%@,%@) failed: %s\n"), kSCPrefCurrentSet, - current); + current, + SCErrorString(SCError())); 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)) { - SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n")); + SCPrint(TRUE, stderr, + CFSTR("SCPreferencesApplyChanges() failed %s\n"), + SCErrorString(SCError())); exit (1); } } @@ -375,6 +327,11 @@ main(int argc, char **argv) CFRelease(prefix); CFRelease(prefs); +#if !TARGET_OS_IPHONE + AuthorizationFree(authorization, kAuthorizationFlagDefaults); +// AuthorizationFree(authorization, kAuthorizationFlagDestroyRights); +#endif /* !TARGET_OS_IPHONE */ + exit (0); return 0; } diff --git a/scutil.tproj/cache.c b/scutil.tproj/cache.c index 76fd819..b8016e7 100644 --- a/scutil.tproj/cache.c +++ b/scutil.tproj/cache.c @@ -296,7 +296,7 @@ do_list(int argc, char **argv) CFIndex n; n = CFDictionaryGetCount(cached_set); - if (n > 0){ + if (n > 0) { const void * cachedKeys_q[N_QUICK]; const void ** cachedKeys = cachedKeys_q; diff --git a/scutil.tproj/nc.c b/scutil.tproj/nc.c index 551289c..76ba1de 100644 --- a/scutil.tproj/nc.c +++ b/scutil.tproj/nc.c @@ -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@ * @@ -41,11 +41,20 @@ #include "nc.h" #include "prefs.h" +#include + +#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#include +#endif // TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR + #include -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; @@ -143,7 +152,7 @@ nc_copy_service_from_arguments(int argc, char **argv, SCNetworkSetRef set) { SCNetworkServiceRef service = NULL; if (argc == 0) { - serviceID = _copyStringFromSTDIN(); + serviceID = _copyStringFromSTDIN(CFSTR("Service"), NULL); } 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 @@ -402,7 +475,7 @@ nc_watch(int argc, char **argv) // 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); } @@ -486,6 +559,44 @@ checkOnDemandHost(SCDynamicStoreRef store, CFStringRef nodeName, Boolean retry) 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) { @@ -494,28 +605,64 @@ nc_ondemand(int argc, char **argv) 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 (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); - 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 { - 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; @@ -523,63 +670,97 @@ done: my_CFRelease(&ondemand_dict); my_CFRelease(&key); my_CFRelease(&store); + my_CFRelease(&ondemand_nodename); exit(exit_code); } /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - CFStringRef -copy_padded_string(CFStringRef original, int width) +copy_padded_string(CFStringRef original, int width, CFStringRef prefix, CFStringRef suffix) { 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; } +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) { - 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 type = NULL; 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, - CFSTR("%@ %@ %@ %@ [%@%@%@]\n"), + CFSTR("%@ %@ %@ %@ %@ [%@%@%@]\n"), 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); - CFRelease(service_name_quoted); + 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); } +/* ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- */ +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\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 \n")); + SCPrint(TRUE, stderr, CFSTR("\t\tDisplay configuration information for a given service\n")); + SCPrint(TRUE, stderr, CFSTR("\n")); + SCPrint(TRUE, stderr, CFSTR("\tstatistics \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 \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 [--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 \n")); + SCPrint(TRUE, stderr, CFSTR("\t\tStop a given service\n")); + SCPrint(TRUE, stderr, CFSTR("\n")); + SCPrint(TRUE, stderr, CFSTR("\tsuspend \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 \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 [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 [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 \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 \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); @@ -739,7 +1308,12 @@ static const struct { char *cmd; nc_func func; } nc_cmds[] = { + { "enablevpn", nc_enablevpn }, + { "help", nc_help }, { "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 }, @@ -749,6 +1323,7 @@ static const struct { { "status", nc_status }, { "stop", nc_stop }, { "suspend", nc_suspend }, + { "trigger", nc_trigger }, }; #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; - 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); } diff --git a/scutil.tproj/net_interface.c b/scutil.tproj/net_interface.c index ba12204..61110c0 100644 --- a/scutil.tproj/net_interface.c +++ b/scutil.tproj/net_interface.c @@ -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@ * @@ -34,12 +34,10 @@ #include "net.h" #include "prefs.h" -#include - -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE #define INLINE_PASSWORDS_USE_CFSTRING -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE #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; + Boolean isPhysicalEthernet; CFArrayRef supported; if_localized_name = SCNetworkInterfaceGetLocalizedDisplayName(interface); @@ -713,6 +712,10 @@ _show_interface(SCNetworkInterfaceRef interface, CFStringRef prefix, Boolean sho } SCPrint(TRUE, stdout, CFSTR("\n")); + isPhysicalEthernet = _SCNetworkInterfaceIsPhysicalEthernet(interface); + SCPrint(TRUE, stdout, CFSTR("%@ is physical ethernet = %s \n"), + prefix, (isPhysicalEthernet == TRUE) ? "YES" : "NO"); + if (configuration != NULL) { CFMutableDictionaryRef effective; @@ -920,6 +923,33 @@ show_interfaces(int argc, char **argv) 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); diff --git a/scutil.tproj/net_set.c b/scutil.tproj/net_set.c index 6dfc9da..3149566 100644 --- a/scutil.tproj/net_set.c +++ b/scutil.tproj/net_set.c @@ -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@ * @@ -504,6 +504,7 @@ __private_extern__ void show_set(int argc, char **argv) { + CFArrayRef interfaces; CFArrayRef services; SCNetworkSetRef set = NULL; CFStringRef setName; @@ -593,6 +594,25 @@ show_set(int argc, char **argv) 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); } diff --git a/scutil.tproj/notifications.c b/scutil.tproj/notifications.c index a50302e..19507fc 100644 --- a/scutil.tproj/notifications.c +++ b/scutil.tproj/notifications.c @@ -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@ * @@ -286,7 +286,7 @@ _watcher(void *arg) } 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; diff --git a/scutil.tproj/prefs.c b/scutil.tproj/prefs.c index 34e534d..d8761fe 100644 --- a/scutil.tproj/prefs.c +++ b/scutil.tproj/prefs.c @@ -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@ * @@ -69,7 +69,7 @@ __loadSecurity(void) { } -__private_extern__ OSStatus +static OSStatus _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 -__private_extern__ OSStatus +static OSStatus _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; - 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; } + + +__private_extern__ +void +_prefs_AuthorizationFree(AuthorizationRef authorization) +{ + if (authorization != kSCPreferencesUseEntitlementAuthorization) { + AuthorizationFree(authorization, kAuthorizationFlagDefaults); +// AuthorizationFree(authorization, kAuthorizationFlagDestroyRights); + } + + return; +} + #endif /* !TARGET_OS_IPHONE */ /* -------------------- */ @@ -144,9 +163,9 @@ _prefs_open(CFStringRef name, CFStringRef prefsID) useHelper = TRUE; #if !TARGET_OS_IPHONE - authorization = _createAuthorization(); + authorization = _prefs_AuthorizationCreate(); #else - authorization = (AuthorizationRef)kSCPreferencesUseEntitlementAuthorization; + authorization = kSCPreferencesUseEntitlementAuthorization; #endif /* !TARGET_OS_IPHONE */ } @@ -228,8 +247,7 @@ _prefs_close() 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 */ @@ -320,7 +338,12 @@ set_ComputerName(int argc, char **argv) } 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); } @@ -400,7 +423,7 @@ set_HostName(int argc, char **argv) } if (argc == 0) { - hostname = _copyStringFromSTDIN(); + hostname = _copyStringFromSTDIN(CFSTR("HostName"), SCPreferencesGetHostName(prefs)); } else { hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); } @@ -470,7 +493,11 @@ set_LocalHostName(int argc, char **argv) } 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); } @@ -531,11 +558,37 @@ do_getPref(char *pref, int argc, char **argv) { 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 + 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; } + +/* -------------------- */ + +#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; +} + + diff --git a/scutil.tproj/prefs.h b/scutil.tproj/prefs.h index feb55be..f1a3437 100644 --- a/scutil.tproj/prefs.h +++ b/scutil.tproj/prefs.h @@ -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@ * @@ -40,6 +40,9 @@ Boolean _prefs_changed; __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); @@ -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_log (char *pref, int argc, char **argv); __END_DECLS #endif /* !_PREFS_H */ diff --git a/scutil.tproj/scutil.8 b/scutil.tproj/scutil.8 index 3350639..d058366 100644 --- a/scutil.tproj/scutil.8 +++ b/scutil.tproj/scutil.8 @@ -32,6 +32,9 @@ .Br .Nm .Fl -proxy +.Br +.Nm +.Fl -nc Ar nc-arguments .\".Br .\".Nm .\".Fl -net @@ -85,7 +88,7 @@ The .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. @@ -101,6 +104,14 @@ configuration in addition to the first listed. 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 @@ -178,7 +189,7 @@ The user-friendly name for the system. The local (Bonjour) host name. .It HostName The name associated with -.Xr hostname 1 +.Xr hostname 1 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. +.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 . diff --git a/scutil.tproj/scutil.c b/scutil.tproj/scutil.c index 7578f44..c4bff2a 100644 --- a/scutil.tproj/scutil.c +++ b/scutil.tproj/scutil.c @@ -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@ * @@ -102,33 +102,77 @@ static const struct option longopts[] = { { "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 }, + { "log", required_argument, NULL, 0 }, { NULL, 0, NULL, 0 } }; __private_extern__ CFStringRef -_copyStringFromSTDIN() +_copyStringFromSTDIN(CFStringRef prompt, CFStringRef defaultValue) { char buf[1024]; + int i; + Boolean is_user_prompt = (prompt != NULL && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)); size_t len; + char *modbuf; + size_t modlen; 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; } + /* Prepare for trim */ 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; } @@ -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(" 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")); @@ -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 --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")); @@ -321,7 +369,11 @@ usage(const char *command) static char * prompt(EditLine *el) { +#if !TARGET_IPHONE_SIMULATOR 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; + char *log = NULL; extern int optind; int opt; int opti; const char *prog = argv[0]; + char *renew = NULL; 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, "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, "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) { @@ -427,6 +487,7 @@ main(int argc, char * const argv[]) // 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) { @@ -458,7 +519,11 @@ main(int argc, char * const argv[]) } if (doSnap) { - if (!enablePrivateAPI || (geteuid() != 0)) { + if (!enablePrivateAPI +#if !TARGET_IPHONE_SIMULATOR + || (geteuid() != 0) +#endif // !TARGET_IPHONE_SIMULATOR + ) { usage(prog); } @@ -469,9 +534,17 @@ main(int argc, char * const argv[]) /* 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 */ } @@ -491,6 +564,14 @@ main(int argc, char * const argv[]) /* 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) { @@ -509,15 +590,15 @@ main(int argc, char * const argv[]) 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; - 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 */ @@ -528,6 +609,12 @@ main(int argc, char * const argv[]) 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; diff --git a/scutil.tproj/scutil.h b/scutil.tproj/scutil.h index cbffecf..4c0d0b9 100644 --- a/scutil.tproj/scutil.h +++ b/scutil.tproj/scutil.h @@ -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@ * @@ -65,7 +65,8 @@ extern CFMutableArrayRef watchedPatterns; __BEGIN_DECLS Boolean process_line (InputRef src); -CFStringRef _copyStringFromSTDIN (); +CFStringRef _copyStringFromSTDIN (CFStringRef prompt, + CFStringRef defaultValue); __END_DECLS diff --git a/scutil.tproj/tests.c b/scutil.tproj/tests.c index bc9160e..9b75f7f 100644 --- a/scutil.tproj/tests.c +++ b/scutil.tproj/tests.c @@ -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@ * @@ -37,6 +37,7 @@ */ #include "scutil.h" +#include "prefs.h" #include "tests.h" #include @@ -47,14 +48,17 @@ #include #include +#include "dnsinfo_internal.h" #include #include "SCNetworkReachabilityInternal.h" +#include -static Boolean resolver_bypass; +static Boolean resolver_bypass; static CF_RETURNS_RETAINED CFMutableDictionaryRef _setupReachabilityOptions(int argc, char **argv, const char *interface) { + int i; CFMutableDictionaryRef options; options = CFDictionaryCreateMutable(NULL, @@ -62,103 +66,54 @@ _setupReachabilityOptions(int argc, char **argv, const char *interface) &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) { @@ -189,6 +144,8 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) 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; @@ -209,9 +166,19 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) } 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) { @@ -238,9 +205,7 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) } } } else { - char *remote_address = argv[1]; const char *interface2; - struct sockaddr_in r_sin; interface2 = strchr(argv[1], '%'); if (interface2 != NULL) { @@ -259,19 +224,11 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) 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); } - options = _setupReachabilityOptions(argc, argv, interface); + options = _setupReachabilityOptions(argc - 2, argv + 2, interface); 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) { + struct sockaddr_in6 r_sin6; + 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) { @@ -328,22 +296,12 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) } } } 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); } - options = _setupReachabilityOptions(argc, argv, NULL); + options = _setupReachabilityOptions(argc - 2, argv + 2, NULL); if (options == NULL) { target = SCNetworkReachabilityCreateWithAddressPair(NULL, (struct sockaddr *)&sin6, @@ -367,60 +325,28 @@ _setupReachability(int argc, char **argv, SCNetworkReachabilityContext *context) } } } 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 { - 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); - } - 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 (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; } -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) @@ -506,21 +372,21 @@ _printReachability(SCNetworkReachabilityRef target) 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); - _printReachabilityFlags(flags); + __SCNetworkReachabilityPrintFlags(flags); SCPrint(_sc_debug, stdout, CFSTR(")")); + SCPrint(TRUE, stdout, CFSTR("\n")); 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; } @@ -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: ")); + } + + SCPrint(TRUE, stdout, CFSTR("\n generation %llu\n"), + nwi_ifstate_get_generation(ifstate)); + + return; +} + + __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) { - 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]); } @@ -607,7 +509,9 @@ do_nwi(int argc, char **argv) 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); @@ -616,14 +520,7 @@ do_nwi(int argc, char **argv) } 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); } @@ -635,14 +532,7 @@ do_nwi(int argc, char **argv) } 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); } @@ -726,7 +616,7 @@ do_watchReachability(int argc, char **argv) } 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); } @@ -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) { - dns_config_t *dns_config; + dns_config_t *dns_config; SCNetworkReachabilityRef target; dns_config = dns_configuration_copy(); @@ -852,10 +654,10 @@ do_showDNSConfiguration(int argc, char **argv) } 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; @@ -870,7 +672,7 @@ do_showDNSConfiguration(int argc, char **argv) } ok = __SC_checkResolverReachabilityInternal(&store, &flags, - &haveDNS, targetPrivate->name, NULL, + &haveDNS, targetPrivate->name, &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]; } - showResolver(resolver, dns_config_index + 1); + _dns_resolver_print(resolver, dns_config_index + 1); 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); @@ -924,8 +712,9 @@ showProxy(CFDictionaryRef proxy) if (!_sc_debug) { cleaned = CFDictionaryCreateMutableCopy(NULL, 0, proxy); - CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesSupplemental); CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesScoped); + CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesServices); + CFDictionaryRemoveValue(cleaned, kSCPropNetProxiesSupplemental); proxy = cleaned; } @@ -939,9 +728,22 @@ __private_extern__ 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; @@ -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() { @@ -1116,8 +1029,9 @@ do_wait(char *waitKey, int timeout) CFRunLoopRun(); } -#ifdef TEST_DNS_CONFIGURATION_COPY +#ifdef TEST_DNS_CONFIGURATION +Boolean doDispatch = FALSE; CFRunLoopSourceRef notifyRls = NULL; SCDynamicStoreRef store = NULL; CFPropertyListRef value = NULL; @@ -1125,8 +1039,26 @@ CFPropertyListRef value = NULL; 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); } -#endif // TEST_DNS_CONFIGURATION_COPY +#endif // TEST_DNS_CONFIGURATION diff --git a/scutil.tproj/tests.h b/scutil.tproj/tests.h index 6b5c0e9..996a64e 100644 --- a/scutil.tproj/tests.h +++ b/scutil.tproj/tests.h @@ -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@ * @@ -42,6 +42,7 @@ __BEGIN_DECLS 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); diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..5079e8f --- /dev/null +++ b/tests/Makefile @@ -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 index 0000000..41ee485 --- /dev/null +++ b/tests/ReachabilityTester.c @@ -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 +#include + +#include +#include +#include + +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 [-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; +} -- 2.45.2