2 * Copyright (c) 2013, 2015-2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * March 15, 2013 Allan Nathanson <ajn@apple.com>
32 #include <TargetConditionals.h>
33 #include <SystemConfiguration/SystemConfiguration.h>
34 #include <SystemConfiguration/SCPrivate.h>
35 #include <SystemConfiguration/SCValidation.h>
38 #include <dns_sd_private.h>
40 #if TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
43 static CFMutableArrayRef mirror_keys
= NULL
;
44 static CFMutableArrayRef mirror_patterns
= NULL
;
45 static SCDynamicStoreRef store_host
= NULL
;
46 static SCDynamicStoreRef store_sim
= NULL
;
56 __private_extern__ os_log_t
57 __log_SimulatorSupport(void)
59 static os_log_t log
= NULL
;
62 log
= os_log_create("com.apple.SystemConfiguration", "SimulatorSupport");
70 #pragma mark iOS Simulator Support
74 mirror(SCDynamicStoreRef store
, CFArrayRef changes
, void *info
)
77 CFDictionaryRef content_host
;
78 CFDictionaryRef content_sim
;
82 n
= CFArrayGetCount(changes
);
88 // capture "host" content
90 content_host
= SCDynamicStoreCopyMultiple(store_host
, changes
, NULL
);
92 content_host
= (CFDictionaryRef
)info
;
95 // capture [current] "sim" content
96 content_sim
= SCDynamicStoreCopyMultiple(store_sim
, changes
, NULL
);
99 _SCDynamicStoreCacheOpen(store
);
100 for (i
= 0; i
< n
; i
++) {
102 CFPropertyListRef val
;
104 key
= CFArrayGetValueAtIndex(changes
, i
);
105 val
= (content_host
!= NULL
) ? CFDictionaryGetValue(content_host
, key
) : NULL
;
107 // if "host" content changed
108 SCDynamicStoreSetValue(store_sim
, key
, val
);
110 // if no "host" content
111 val
= (content_sim
!= NULL
) ? CFDictionaryGetValue(content_sim
, key
) : NULL
;
113 // if we need to remove the "sim" content
114 SCDynamicStoreRemoveValue(store_sim
, key
);
116 // if no "sim" content to remove, just notify
117 SCDynamicStoreNotifyValue(store_sim
, key
);
121 _SCDynamicStoreCacheCommitChanges(store_sim
);
122 _SCDynamicStoreCacheClose(store
);
125 if ((info
== NULL
) && (content_host
!= NULL
)) {
126 CFRelease(content_host
);
128 if (content_sim
!= NULL
) {
129 CFRelease(content_sim
);
142 mirror_keys
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
143 mirror_patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
145 // Plugin:InterfaceNamer
146 key
= SCDynamicStoreKeyCreate(NULL
,
147 CFSTR("%@" "InterfaceNamer"),
148 kSCDynamicStoreDomainPlugin
);
149 CFArrayAppendValue(mirror_keys
, key
);
153 // key = SCDynamicStoreKeyCreateComputerName(NULL);
154 // CFArrayAppendValue(mirror_keys, key);
158 // key = SCDynamicStoreKeyCreateHostNames(NULL);
159 // CFArrayAppendValue(mirror_keys, key);
162 // Setup:/Network/Global/.*
163 pattern
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
164 kSCDynamicStoreDomainSetup
,
166 CFArrayAppendValue(mirror_patterns
, pattern
);
169 // Setup:/Network/Service/.*
170 // State:/Network/Service/.*
171 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
,
175 CFArrayAppendValue(mirror_patterns
, pattern
);
178 // Setup:/Network/Interface/.*
179 // State:/Network/Interface/.*
180 pattern
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
184 CFArrayAppendValue(mirror_patterns
, pattern
);
187 // State:/Network/MulticastDNS
188 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@/%@/%@"),
189 kSCDynamicStoreDomainState
,
191 CFSTR(kDNSServiceCompMulticastDNS
));
192 CFArrayAppendValue(mirror_keys
, key
);
195 // State:/Network/PrivateDNS
196 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@/%@/%@"),
197 kSCDynamicStoreDomainState
,
199 CFSTR(kDNSServiceCompPrivateDNS
));
200 CFArrayAppendValue(mirror_keys
, key
);
212 prime_SimulatorSupport()
214 CFDictionaryRef content_host
;
217 SC_log(LOG_DEBUG
, "prime() called");
219 // copy current content from base OS store to _Sim store
220 content_host
= SCDynamicStoreCopyMultiple(store_host
, mirror_keys
, mirror_patterns
);
221 CFRelease(mirror_keys
);
223 CFRelease(mirror_patterns
);
224 mirror_patterns
= NULL
;
226 if (content_host
== NULL
) {
230 n
= CFDictionaryGetCount(content_host
);
233 const void * keys_host_q
[N_QUICK
];
234 const void ** keys_host
= keys_host_q
;
236 if (n
> (CFIndex
)(sizeof(keys_host_q
) / sizeof(CFStringRef
))) {
237 keys_host
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
240 CFDictionaryGetKeysAndValues(content_host
, keys_host
, NULL
);
242 changes
= CFArrayCreate(NULL
, keys_host
, n
, &kCFTypeArrayCallBacks
);
243 mirror(store_host
, changes
, (void *)content_host
);
246 if (keys_host
!= keys_host_q
) {
247 CFAllocatorDeallocate(NULL
, keys_host
);
251 CFRelease(content_host
);
258 load_SimulatorSupport(CFBundleRef bundle
, Boolean bundleVerbose
)
260 #pragma unused(bundleVerbose)
262 CFMutableDictionaryRef options
;
263 CFRunLoopSourceRef rls
;
265 SC_log(LOG_DEBUG
, "load() called");
266 SC_log(LOG_DEBUG
, " bundle ID = %@", CFBundleGetIdentifier(bundle
));
271 // setup SCDynamicStore mirroring (from "host")
272 options
= CFDictionaryCreateMutable(NULL
,
274 &kCFTypeDictionaryKeyCallBacks
,
275 &kCFTypeDictionaryValueCallBacks
);
276 CFDictionarySetValue(options
, kSCDynamicStoreUseHostServer
, kCFBooleanTrue
);
277 store_host
= SCDynamicStoreCreateWithOptions(NULL
,
278 CFSTR("SimulatorSupport(host)"),
283 assert(store_host
!= NULL
);
285 ok
= SCDynamicStoreSetNotificationKeys(store_host
, mirror_keys
, mirror_patterns
);
288 rls
= SCDynamicStoreCreateRunLoopSource(NULL
, store_host
, 0);
291 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls
, kCFRunLoopDefaultMode
);
294 // setup SCDynamicStore mirroring (to "iOS Simulator")
295 store_sim
= SCDynamicStoreCreate(NULL
,
296 CFSTR("SimulatorSupport(sim)"),
308 #pragma mark Standalone test code
312 main(int argc
, char **argv
)
314 _sc_log
= kSCLogDestinationFile
;
315 _sc_verbose
= (argc
> 1) ? TRUE
: FALSE
;
317 load_SimulatorSupport(CFBundleGetMainBundle(), (argc
> 1) ? TRUE
: FALSE
);
318 prime_SimulatorSupport();
326 #endif // TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST