--- /dev/null
+.DS_Store
+*.xcodeproj/project.xcworkspace
+*.xcodeproj/xcuserdata
+.svn
+build
+*~
+*~.c
+*~.h
+*~.m
#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 uint32_t
#define N_QUICK 32
+static void
+merge_configuration_flags(CFMutableDictionaryRef newDNS, uint32_t mergeFlags)
+{
+ uint32_t flags;
+ CFNumberRef num;
+
+ if (!CFDictionaryGetValueIfPresent(newDNS, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&num) ||
+ !isA_CFNumber(num) ||
+ !CFNumberGetValue(num, kCFNumberSInt32Type, &flags)) {
+ flags = 0;
+ }
+
+ flags |= mergeFlags;
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
+ CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
+ CFRelease(num);
+
+ return;
+}
+
+
static void
add_supplemental_resolvers(CFMutableArrayRef resolvers,
CFDictionaryRef services,
uint32_t dns_resolver_flags;
CFStringRef interface;
CFMutableDictionaryRef newDNS = NULL;
+ uint32_t newFlags;
CFDictionaryRef service = (CFDictionaryRef)vals[i];
CFStringRef serviceID = (CFStringRef)keys[i];
+ Boolean trusted = FALSE; // trusted config w/interface
if (!isA_CFDictionary(service)) {
continue;
isA_CFBoolean(val) &&
CFBooleanGetValue(val)) {
// leave the [trusted configuration] InterfaceName in place
+ trusted = TRUE;
} else {
CFDictionaryRemoveValue(newDNS, kSCPropInterfaceName);
}
}
+ // set "supplemental" flag
+ newFlags = DNS_RESOLVER_FLAGS_SUPPLEMENTAL;
+
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;
+ // set "scoped" configuration flag
+ newFlags |= DNS_RESOLVER_FLAGS_SCOPED;
// add "Request A/AAAA query" flag(s)
- flags |= dns_resolver_flags;
-
- num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
- CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
- CFRelease(num);
+ newFlags |= dns_resolver_flags;
+ } else if (trusted) {
+ // use the DNS query flags from the supplemental match service
+ newFlags |= dns_resolver_flags_service(service, 0);
}
+ merge_configuration_flags(newDNS, newFlags);
+
// add [scoped] resolver entry
add_supplemental(resolvers, serviceID, newDNS, defaultOrder, (scoped_interface != NULL));
CFRelease(newDNS);
for (i = 0; i < n_order; i++) {
CFDictionaryRef dns;
uint32_t dns_resolver_flags;
- uint32_t flags;
char if_name[IF_NAMESIZE];
CFStringRef interface;
CFMutableDictionaryRef newDNS;
- CFNumberRef num;
+ uint32_t newFlags;
CFArrayRef searchDomains;
CFDictionaryRef service;
CFStringRef serviceID;
CFRelease(searchDomains);
}
- // 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 "Request A/AAAA query" flag(s)
+ // get "Request A/AAAA query" flag(s)
dns_resolver_flags = dns_resolver_flags_service(service, 0);
if (dns_resolver_flags == 0) {
goto skip;
}
- flags |= dns_resolver_flags;
- num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
- CFDictionarySetValue(newDNS, DNS_CONFIGURATION_FLAGS_KEY, num);
- CFRelease(num);
+ // set "scoped" configuration flag
+ newFlags = DNS_RESOLVER_FLAGS_SCOPED;
+
+ // add "Request A/AAAA query" flag(s)
+ newFlags |= dns_resolver_flags;
+
+ merge_configuration_flags(newDNS, newFlags);
// remove keys we don't want in a [scoped] resolver
CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains);
for (i = 0; i < n_services; i++) {
CFDictionaryRef dns;
CFNumberRef dns_service_identifier;
- CFNumberRef flags_num;
- int32_t flags = 0;
- CFMutableDictionaryRef new_resolver;
+ CFMutableDictionaryRef newDNS;
+ uint32_t newFlags = 0;
CFDictionaryRef service = vals[i];
CFStringRef serviceID = keys[i];
}
CFSetSetValue(seen, dns_service_identifier);
- new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, dns);
+ newDNS = CFDictionaryCreateMutableCopy(NULL, 0, dns);
- if (!CFDictionaryGetValueIfPresent(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, (const void **)&flags_num) ||
- !isA_CFNumber(flags_num) ||
- !CFNumberGetValue(flags_num, kCFNumberSInt32Type, &flags)) {
- flags = 0;
- }
+ if (CFDictionaryContainsKey(newDNS, kSCPropInterfaceName)) {
+ CFArrayRef searchDomains;
- flags |= DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS;
+ // set "scoped" configuration flag
+ newFlags |= DNS_RESOLVER_FLAGS_SCOPED;
- if (CFDictionaryContainsKey(new_resolver, kSCPropInterfaceName)) {
- CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_SCOPED_QUERY_KEY, kCFBooleanTrue);
- CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSServiceIdentifier);
- flags |= DNS_RESOLVER_FLAGS_SCOPED;
+ CFDictionarySetValue(newDNS, DNS_CONFIGURATION_SCOPED_QUERY_KEY, kCFBooleanTrue);
+ CFDictionaryRemoveValue(newDNS, kSCPropNetDNSServiceIdentifier);
+
+ // set search list
+ searchDomains = extract_search_domains(newDNS, NULL);
+ if (searchDomains != NULL) {
+ CFDictionarySetValue(newDNS, kSCPropNetDNSSearchDomains, searchDomains);
+ CFRelease(searchDomains);
+ }
} else {
- flags |= DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
+ // set "service specific" configuration flag
+ newFlags |= DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
}
- flags_num = CFNumberCreate(NULL, kCFNumberSInt32Type, &flags);
- CFDictionarySetValue(new_resolver, DNS_CONFIGURATION_FLAGS_KEY, flags_num);
- CFRelease(flags_num);
+ // add "Request A/AAAA query" flag(s)
+ newFlags |= DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS;
- CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchDomains);
- CFDictionaryRemoveValue(new_resolver, kSCPropNetDNSSupplementalMatchOrders);
+ merge_configuration_flags(newDNS, newFlags);
- add_resolver_signature(new_resolver, "Service", serviceID, 0);
- add_resolver(resolvers, new_resolver);
- CFRelease(new_resolver);
+ CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchDomains);
+ CFDictionaryRemoveValue(newDNS, kSCPropNetDNSSupplementalMatchOrders);
+
+ add_resolver_signature(newDNS, "Service", serviceID, 0);
+ add_resolver(resolvers, newDNS);
+ CFRelease(newDNS);
}
CFRelease(seen);
}
-static __inline__ Boolean
-isDefaultConfiguration(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_SCOPED ) != 0) ||
- ((flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) != 0))
- ) {
- // if scoped or service-specific
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-
static __inline__ Boolean
isScopedConfiguration(CFDictionaryRef dns)
{
}
+static __inline__ Boolean
+needsMergeWithDefaultConfiguration(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)) {
+
+ // check if merge needed (at all)
+ if (dns_resolver_flags_all_queries(flags)) {
+ // if we are already querying for both A/AAAA
+ return FALSE;
+ }
+
+ // check if scoped or service-specific
+ if (((flags & DNS_RESOLVER_FLAGS_SCOPED ) != 0) ||
+ ((flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) != 0)) {
+ // yes, skip merge
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
__private_extern__
Boolean
dns_configuration_set(CFDictionaryRef defaultResolver,
{
dns_create_config_t _config;
Boolean changed = FALSE;
- uint32_t dns_resolver_flags = 0;
CFIndex i;
CFMutableDictionaryRef myDefault;
Boolean myOrderAdded = FALSE;
*/
_config = NULL;
} else {
+ uint32_t default_resolver_flags = 0;
+ Boolean have_default_flags = FALSE;
+
/*
* if default and/or supplemental/scoped resolvers are defined
*/
_config = _dns_configuration_create();
- CFDictionaryApplyFunction(services, add_dns_resolver_flags, &dns_resolver_flags);
-
for (i = 0; i < n_resolvers; i++) {
- boolean_t is_default_resolver;
+ Boolean merge_default_flags;
CFDictionaryRef resolver;
dns_create_resolver_t _resolver;
resolver = CFArrayGetValueAtIndex(resolvers, i);
- is_default_resolver = isDefaultConfiguration(resolver);
- if (is_default_resolver) {
+ merge_default_flags = needsMergeWithDefaultConfiguration(resolver);
+ if (merge_default_flags) {
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);
+ if (!have_default_flags) {
+ CFDictionaryApplyFunction(services,
+ add_dns_resolver_flags,
+ &default_resolver_flags);
+ have_default_flags = TRUE;
+ }
+ new_resolver = CFDictionaryCreateMutableCopy(NULL, 0, resolver);
+ merge_configuration_flags(new_resolver, default_resolver_flags);
resolver = new_resolver;
}
_dns_configuration_add_resolver(&_config, _resolver);
_dns_resolver_free(&_resolver);
- if (is_default_resolver) {
+ if (merge_default_flags) {
CFRelease(resolver);
}
}
#if !TARGET_OS_IPHONE
// add flatfile resolvers
- _dnsinfo_flatfile_set_flags(dns_resolver_flags);
+ _dnsinfo_flatfile_set_flags(default_resolver_flags);
_dnsinfo_flatfile_add_resolvers(&_config);
#endif // !TARGET_OS_IPHONE
}
#include <SystemConfiguration/SCDPlugin.h>
#include <SystemConfiguration/SCPrivate.h>
#include <SystemConfiguration/SCValidation.h>
+#include "plugin_shared.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOKitLibPrivate.h>
#if !TARGET_OS_EMBEDDED
-#define BT_PAN_NAME "Bluetooth PAN"
-#define BT_PAN_MAC BT_PAN_NAME " (MAC)"
-
static void
updateBTPANInformation(const void *value, void *context)
{
return;
}
- CFDictionaryAddValue(S_state, CFSTR("_" BT_PAN_NAME "_"), if_name);
+ CFDictionaryAddValue(S_state, kInterfaceNamerKey_BT_PAN_Name, if_name);
addr = CFDictionaryGetValue(dict, CFSTR(kIOMACAddress));
if (isA_CFData(addr)) {
- CFDictionaryAddValue(S_state, CFSTR("_" BT_PAN_MAC "_"), addr);
+ CFDictionaryAddValue(S_state, kInterfaceNamerKey_BT_PAN_Mac, addr);
}
return;
}
#if !TARGET_OS_IPHONE
+static Boolean
+isRecoveryOS()
+{
+ static Boolean isRecovery = FALSE;
+ static dispatch_once_t once;
+
+ /*
+ * We check to see if the UserEventAgent daemon is present. If not, then
+ * we are most likely booted into the Recovery OS with no "SCMonitor"
+ * [UserEventAgent] plugin.
+ */
+ dispatch_once(&once, ^{
+ if ((access("/usr/libexec/UserEventAgent", X_OK) == -1) && (errno == ENOENT)) {
+ isRecovery = TRUE;
+ }
+
+ });
+
+ return isRecovery;
+}
+
static void
updateNetworkConfiguration(CFArrayRef if_list)
{
}
#endif // !TARGET_OS_IPHONE
+static void
+updatePreConfigured(CFArrayRef interfaces)
+{
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef new_list = NULL;
+ Boolean updated = FALSE;
+
+ n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
+ for (i = 0; i < n; i++) {
+ SCNetworkInterfaceRef interface;
+
+ interface = CFArrayGetValueAtIndex(interfaces, i);
+ if (_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+ CFStringRef bsdName;
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (bsdName == NULL) {
+ continue;
+ }
+
+ // add pre-configured interface
+ if (new_list == NULL) {
+ CFArrayRef cur_list;
+
+ cur_list = CFDictionaryGetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces);
+ if (cur_list != NULL) {
+ new_list = CFArrayCreateMutableCopy(NULL, 0, cur_list);
+ } else {
+ new_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+ }
+
+ if (!CFArrayContainsValue(new_list, CFRangeMake(0, CFArrayGetCount(new_list)), bsdName)) {
+ CFArrayAppendValue(new_list, bsdName);
+ updated = TRUE;
+ }
+ }
+ }
+
+ if (new_list != NULL) {
+ if (updated) {
+ CFDictionarySetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces, new_list);
+ updateStore();
+ }
+
+ CFRelease(new_list);
+ }
+
+ return;
+}
+
static void
updateInterfaces()
{
nameInterfaces(S_iflist);
}
+ /*
+ * Update the list of [Apple] pre-configured interfaces
+ */
+ updatePreConfigured(S_iflist);
+
if (isQuiet()) {
/*
* The registry [matching] has quiesced so let's
updateVirtualNetworkInterfaceConfiguration(NULL, kSCPreferencesNotificationApply, NULL);
#if !TARGET_OS_IPHONE
- if (access("/usr/libexec/UserEventAgent", X_OK) == -1
- && errno == ENOENT) {
+ if (isRecoveryOS()) {
/*
* We are most likely booted into the Recovery OS with no "SCMonitor"
* UserEventAgent plugin running so let's make sure we update the
os_activity_scope(activity);
if (messageType == kIOMessageServiceBusyStateChange) {
- addTimestamp(S_state, CFSTR("*QUIET*"));
+ addTimestamp(S_state, kInterfaceNamerKey_Quiet);
SC_log(LOG_INFO, "IOKit quiet");
}
// We've been waiting for IOKit to quiesce and it just
// hasn't happenned. Time to just move on!
- addTimestamp(S_state, CFSTR("*TIMEOUT*"));
+ addTimestamp(S_state, kInterfaceNamerKey_Timeout);
// log busy nodes
SC_log(LOG_ERR, "timed out waiting for IOKit to quiesce");
#include <TargetConditionals.h>
#include <fcntl.h>
+#include <net/if.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
#include <SystemConfiguration/SCValidation.h>
+#include "plugin_shared.h"
+#include <CommonCrypto/CommonDigest.h>
+
/* globals */
-static SCPreferencesRef prefs = NULL;
-static SCDynamicStoreRef store = NULL;
+static SCPreferencesRef prefs = NULL;
+static SCDynamicStoreRef store = NULL;
+
+/* InterfaceNamer[.plugin] monitoring globals */
+Boolean haveConfiguration = FALSE;
+static CFStringRef namerKey = NULL;
+static CFArrayRef preconfigured = NULL;
-/* preferences "initialization" globals */
-static CFStringRef initKey = NULL;
-static CFRunLoopSourceRef initRls = NULL;
+/* KernelEventMonitor[.plugin] monitoring globals */
+static CFStringRef interfacesKey = NULL;
/* SCDynamicStore (Setup:) */
static CFMutableDictionaryRef currentPrefs; /* current prefs */
static CFMutableArrayRef unchangedPrefsKeys; /* new prefs keys which match current */
static CFMutableArrayRef removedPrefsKeys; /* old prefs keys to be removed */
-static Boolean rofs = FALSE;
-static Boolean restorePrefs = FALSE;
+static Boolean rofs = FALSE;
+static Boolean restorePrefs = FALSE;
#define MY_PLUGIN_NAME "PreferencesMonitor"
#define MY_PLUGIN_ID CFSTR("com.apple.SystemConfiguration." MY_PLUGIN_NAME)
+static void
+updateConfiguration(SCPreferencesRef prefs,
+ SCPreferencesNotification notificationType,
+ void *info);
+
+
static os_log_t
__log_PreferencesMonitor()
{
}
-static Boolean
-quiet(Boolean *timeout)
+static void
+watchSCDynamicStore()
{
- CFDictionaryRef dict;
- Boolean _quiet = FALSE;
- Boolean _timeout = FALSE;
-
- // keep the static analyzer happy
- assert(initKey != NULL);
-
- // check if quiet
- dict = SCDynamicStoreCopyValue(store, initKey);
- if (dict != NULL) {
- if (isA_CFDictionary(dict)) {
- if (CFDictionaryContainsKey(dict, CFSTR("*QUIET*"))) {
- _quiet = TRUE;
- }
- if (CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*"))) {
- _timeout = TRUE;
- }
- }
- CFRelease(dict);
- }
-
- if (timeout != NULL) {
- *timeout = _timeout;
- }
- return _quiet;
-}
+ CFMutableArrayRef keys;
+ Boolean ok;
+ CFRunLoopSourceRef rls;
+ /*
+ * watch for KernelEventMonitor[.bundle] changes (the list of
+ * active network interfaces)
+ */
+ interfacesKey = SCDynamicStoreKeyCreateNetworkInterface(NULL,
+ kSCDynamicStoreDomainState);
-static void
-watchQuietDisable()
-{
- if ((initKey == NULL) || (initRls == NULL)) {
+ /*
+ * watch for InterfaceNamer[.bundle] changes (quiet, timeout,
+ * and the list of pre-configured interfaces)
+ */
+ namerKey = SCDynamicStoreKeyCreate(NULL,
+ CFSTR("%@" "InterfaceNamer"),
+ kSCDynamicStoreDomainPlugin);
+
+ rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+ if (rls == NULL) {
+ SC_log(LOG_NOTICE, "SCDynamicStoreCreateRunLoopSource() failed: %s", SCErrorString(SCError()));
+ haveConfiguration = TRUE;
return;
}
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
- (void) SCDynamicStoreSetNotificationKeys(store, NULL, NULL);
-
- CFRunLoopSourceInvalidate(initRls);
- CFRelease(initRls);
- initRls = NULL;
-
- CFRelease(initKey);
- initKey = NULL;
-
- return;
-}
-
-
-static void
-watchQuietEnable()
-{
- CFArrayRef keys;
- Boolean ok;
-
- initKey = SCDynamicStoreKeyCreate(NULL,
- CFSTR("%@" "InterfaceNamer"),
- kSCDynamicStoreDomainPlugin);
-
- initRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
- CFRunLoopAddSource(CFRunLoopGetCurrent(), initRls, kCFRunLoopDefaultMode);
-
- keys = CFArrayCreate(NULL, (const void **)&initKey, 1, &kCFTypeArrayCallBacks);
+ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(keys, interfacesKey);
+ CFArrayAppendValue(keys, namerKey);
ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
CFRelease(keys);
if (!ok) {
SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
- watchQuietDisable();
+ haveConfiguration = TRUE;
}
return;
+
static Boolean
previousConfigurationAvailable()
{
return (properties != NULL);
}
+
static void
-watchQuietCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
{
- Boolean _quiet;
- Boolean _timeout = FALSE;
+ CFDictionaryRef dict;
+ CFArrayRef interfaces = NULL;
+ Boolean quiet = FALSE;
+ Boolean timeout = FALSE;
+ Boolean updated = FALSE;
- _quiet = quiet(&_timeout);
- if (_quiet
-#if !TARGET_OS_IPHONE
- || _timeout
-#endif /* !TARGET_OS_IPHONE */
- ) {
- watchQuietDisable();
+ /*
+ * Capture/process KernelEventMonitor[.bundle] info
+ * 1. get list of active network interfaces
+ */
+ dict = SCDynamicStoreCopyValue(store, interfacesKey);
+ if (dict != NULL) {
+ if (isA_CFDictionary(dict)) {
+ interfaces = CFDictionaryGetValue(dict, kSCPropNetInterfaces);
+ interfaces = isA_CFArray(interfaces);
+ if (interfaces != NULL) {
+ CFRetain(interfaces);
+ }
+ }
+
+ CFRelease(dict);
+ }
+
+ /*
+ * Capture/process InterfaceNamer[.bundle] info
+ * 1. check if IORegistry "quiet", "timeout"
+ * 2. get list of named pre-configured interfaces
+ * 3. merge list of active interfaces (from KEV) with the
+ * list of preconfigured interfaces.
+ */
+ dict = SCDynamicStoreCopyValue(store, namerKey);
+ if (dict != NULL) {
+ if (isA_CFDictionary(dict)) {
+ CFArrayRef cur_preconfigured;
+ CFMutableArrayRef new_preconfigured = NULL;
+
+ if (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet)) {
+ quiet = TRUE;
+ }
+ if (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout)) {
+ timeout = TRUE;
+ }
+
+ cur_preconfigured = CFDictionaryGetValue(dict, kInterfaceNamerKey_PreConfiguredInterfaces);
+ cur_preconfigured = isA_CFArray(cur_preconfigured);
+ if ((cur_preconfigured != NULL) && (interfaces != NULL)) {
+ CFIndex i;
+ CFIndex n;
+ CFRange r = CFRangeMake(0, CFArrayGetCount(interfaces));
+
+ n = CFArrayGetCount(cur_preconfigured);
+ for (i = 0; i < n; i++) {
+ CFStringRef bsdName;
+
+ bsdName = CFArrayGetValueAtIndex(cur_preconfigured, i);
+ if (!CFArrayContainsValue(interfaces, r, bsdName)) {
+ // if interface not currently active
+ continue;
+ }
+
+ if (new_preconfigured == NULL) {
+ new_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+ CFArrayAppendValue(new_preconfigured, bsdName);
+ }
+ }
+
+ if (!_SC_CFEqual(preconfigured, new_preconfigured)) {
+ SC_log(LOG_INFO, "pre-configured interface list changed");
+
+ if (preconfigured != NULL) {
+ CFRelease(preconfigured);
+ }
+ if (new_preconfigured != NULL) {
+ CFRetain(new_preconfigured);
+ }
+ preconfigured = new_preconfigured;
+
+ updated = TRUE;
+ }
+
+ if (new_preconfigured != NULL) {
+ CFRelease(new_preconfigured);
+ }
+ }
+
+ CFRelease(dict);
+ }
+
+ if (interfaces != NULL) {
+ CFRelease(interfaces);
}
- if (_quiet || _timeout) {
+ if (!haveConfiguration && (quiet || timeout)) {
static int logged = 0;
+ if (quiet
+#if !TARGET_OS_IPHONE
+ || timeout
+#endif /* !TARGET_OS_IPHONE */
+ ) {
+ haveConfiguration = TRUE;
+ }
+
(void) establishNewPreferences();
if (restorePrefs) {
restorePrefs = FALSE;
}
- if (_timeout && (logged++ == 0)) {
+ if (timeout && (logged++ == 0)) {
SC_log(LOG_ERR, "Network configuration creation timed out waiting for IORegistry");
}
}
+ if (updated && (changedKeys != NULL)) {
+ // if pre-configured interface list changed
+ updateConfiguration(prefs, kSCPreferencesNotificationApply, (void *)store);
+ }
+
return;
}
}
+static CF_RETURNS_RETAINED SCNetworkServiceRef
+copyInterfaceService(SCNetworkSetRef set, CFStringRef matchName)
+{
+ CFIndex i;
+ CFIndex n;
+ SCNetworkServiceRef service = NULL;
+ CFArrayRef services;
+
+ services = SCNetworkSetCopyServices(set);
+ assert(services != NULL);
+
+ n = CFArrayGetCount(services);
+ for (i = 0; i < n; i++) {
+ SCNetworkInterfaceRef interface;
+
+ service = CFArrayGetValueAtIndex(services, i);
+ interface = SCNetworkServiceGetInterface(service);
+ if (interface != NULL) {
+ CFStringRef bsdName;
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (_SC_CFEqual(bsdName, matchName)) {
+ // if match
+ CFRetain(service);
+ break;
+ }
+ }
+
+ service = NULL;
+ }
+
+ CFRelease(services);
+ return service;
+}
+
+
+static CF_RETURNS_RETAINED CFStringRef
+copyInterfaceUUID(CFStringRef bsdName)
+{
+ union {
+ unsigned char sha1_bytes[CC_SHA1_DIGEST_LENGTH];
+ CFUUIDBytes uuid_bytes;
+ } bytes;
+ CC_SHA1_CTX ctx;
+ char if_name[IF_NAMESIZE];
+ CFUUIDRef uuid;
+ CFStringRef uuid_str;
+
+ // start with interface name
+ bzero(&if_name, sizeof(if_name));
+ (void) _SC_cfstring_to_cstring(bsdName,
+ if_name,
+ sizeof(if_name),
+ kCFStringEncodingASCII);
+
+ // create SHA1 hash
+ bzero(&bytes, sizeof(bytes));
+ CC_SHA1_Init(&ctx);
+ CC_SHA1_Update(&ctx,
+ if_name,
+ sizeof(if_name));
+ CC_SHA1_Final(bytes.sha1_bytes, &ctx);
+
+ // create UUID string
+ uuid = CFUUIDCreateFromUUIDBytes(NULL, bytes.uuid_bytes);
+ uuid_str = CFUUIDCreateString(NULL, uuid);
+ CFRelease(uuid);
+
+ return uuid_str;
+}
+
+
+static void
+updatePreConfiguredConfiguration(SCPreferencesRef prefs)
+{
+ Boolean ok;
+ CFRange range;
+ SCNetworkSetRef set;
+ Boolean updated = FALSE;
+
+ range.length = (preconfigured != NULL) ? CFArrayGetCount(preconfigured) : 0;
+ if (range.length == 0) {
+ // if no [preconfigured] interfaces
+ return;
+ }
+ range.location = 0;
+
+ set = SCNetworkSetCopyCurrent(prefs);
+ if (set != NULL) {
+ CFArrayRef services;
+
+ /*
+ * Check for (and remove) and network services associated with
+ * a pre-configured interface from the prefs.
+ */
+ services = SCNetworkSetCopyServices(set);
+ if (services != NULL) {
+ CFIndex n;
+
+ n = CFArrayGetCount(services);
+ for (CFIndex i = 0; i < n; i++) {
+ CFStringRef bsdName;
+ SCNetworkInterfaceRef interface;
+ SCNetworkServiceRef service;
+
+ service = CFArrayGetValueAtIndex(services, i);
+
+ interface = SCNetworkServiceGetInterface(service);
+ if (interface == NULL) {
+ // if no interface
+ continue;
+ }
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (bsdName == NULL) {
+ // if no interface name
+ continue;
+ }
+
+ if (!CFArrayContainsValue(preconfigured, range, bsdName)) {
+ // if not preconfigured
+ continue;
+ }
+
+ // remove [preconfigured] network service from the prefs
+ SC_log(LOG_NOTICE, "removing network service for %@", bsdName);
+ SCNetworkServiceRemove(service);
+ updated = TRUE;
+ }
+
+ CFRelease(services);
+ }
+
+ if (updated) {
+ // commit the updated prefs ... but don't apply
+ ok = SCPreferencesCommitChanges(prefs);
+ if (!ok) {
+ if (SCError() != EROFS) {
+ SC_log(LOG_NOTICE, "SCPreferencesCommitChanges() failed: %s",
+ SCErrorString(SCError()));
+ }
+ }
+ }
+
+ /*
+ * Now, add a new network service for each pre-configured interface
+ */
+ for (CFIndex i = 0; i < range.length; i++) {
+ CFStringRef bsdName;
+ SCNetworkInterfaceRef interface;
+ SCNetworkServiceRef service;
+
+ bsdName = CFArrayGetValueAtIndex(preconfigured, i);
+ interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeNoVirtualInterfaces);
+ if (interface == NULL) {
+ SC_log(LOG_ERR, "could not create network interface for %@", bsdName);
+ continue;
+ }
+
+ if (_SCNetworkInterfaceGetIOPath(interface) == NULL) {
+ // if no [real] interface exists
+ CFRelease(interface);
+ continue;
+ }
+
+ ok = SCNetworkSetEstablishDefaultInterfaceConfiguration(set, interface);
+ CFRelease(interface);
+ if (!ok) {
+ SC_log(LOG_ERR, "could not create network service for %@", bsdName);
+ continue;
+ }
+
+ service = copyInterfaceService(set, bsdName);
+ if (service != NULL) {
+ CFStringRef serviceID;
+
+ serviceID = copyInterfaceUUID(bsdName);
+ if (serviceID != NULL) {
+ ok = _SCNetworkServiceSetServiceID(service, serviceID);
+ CFRelease(serviceID);
+ if (!ok) {
+ SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s",
+ SCErrorString(SCError()));
+ // ... and keep whatever random UUID was created for the service
+ }
+ } else {
+ SC_log(LOG_ERR, "could not create serviceID for %@", bsdName);
+ // ... and we'll use whatever random UUID was created for the service
+ }
+
+ SC_log(LOG_INFO, "network service %@ added for %@",
+ SCNetworkServiceGetServiceID(service),
+ bsdName);
+
+ CFRelease(service);
+ } else {
+ SC_log(LOG_ERR, "could not find network service for %@", bsdName);
+ }
+ }
+
+ CFRelease(set);
+ }
+
+ return;
+}
+
+
static void
updateSCDynamicStore(SCPreferencesRef prefs)
{
current = SCNetworkSetCopyCurrent(prefs);
if (current != NULL) {
/* network configuration available, disable template creation */
- watchQuietDisable();
+ haveConfiguration = TRUE;
CFRelease(current);
}
}
SC_log(LOG_INFO, "updating configuration");
+ /* add any [Apple] pre-configured network services */
+ updatePreConfiguredConfiguration(prefs);
+
/* update SCDynamicStore (Setup:) */
updateSCDynamicStore(prefs);
void
load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose)
{
- Boolean initPrefs = TRUE;
-
SC_log(LOG_DEBUG, "load() called");
SC_log(LOG_DEBUG, " bundle ID = %@", CFBundleGetIdentifier(bundle));
/* open a SCDynamicStore session to allow cache updates */
store = SCDynamicStoreCreate(NULL,
CFSTR("PreferencesMonitor.bundle"),
- watchQuietCallback,
+ storeCallback,
NULL);
if (store == NULL) {
SC_log(LOG_NOTICE, "SCDynamicStoreCreate() failed: %s", SCErrorString(SCError()));
current = SCNetworkSetCopyCurrent(prefs);
if (current != NULL) {
/* network configuration available, disable template creation */
- initPrefs = FALSE;
+ haveConfiguration = TRUE;
CFRelease(current);
}
}
}
/*
- * if no preferences, initialize with a template (now or
- * when IOKit has quiesced).
+ * watch InterfaceNamer and KernelEventMonitor changes to know when
+ * the IORegistry has quiesced (to create the initial configuration
+ * template), to track any pre-configured interfaces, and to ensure
+ * that we create a network service for any active interfaces.
*/
- if (initPrefs) {
- watchQuietEnable();
- watchQuietCallback(store, NULL, NULL);
- }
+ watchSCDynamicStore();
+ storeCallback(store, NULL, NULL);
return;
error :
- watchQuietDisable();
if (store != NULL) CFRelease(store);
if (prefs != NULL) CFRelease(prefs);
+ haveConfiguration = TRUE;
return;
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * 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
+ *
+ * September 8, 2016 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#ifndef _PLUGIN_SHARED_H
+#define _PLUGIN_SHARED_H
+
+
+#include <CoreFoundation/CoreFoundation.h>
+
+
+#pragma mark -
+#pragma mark InterfaceNamer.bundle --> others
+
+/*
+ * Plugin:InterfaceNamer [SCDynamicStore] dictionary content
+ */
+
+// IORegistry "quiet" (and timeout)
+#define kInterfaceNamerKey_Quiet CFSTR("*QUIET*")
+#define kInterfaceNamerKey_Timeout CFSTR("*TIMEOUT*")
+
+// [Apple] pre-configured network interfaces
+#define kInterfaceNamerKey_PreConfiguredInterfaces CFSTR("_PreConfigured_")
+
+// BT-PAN network interfaces
+#define BT_PAN_NAME "Bluetooth PAN"
+#define kInterfaceNamerKey_BT_PAN_Name CFSTR("_" BT_PAN_NAME "_")
+#define kInterfaceNamerKey_BT_PAN_Mac CFSTR("_" BT_PAN_NAME " (MAC)" "_")
+
+
+#endif /* _PLUGIN_SHARED_H */
uint64_t
_SCNetworkInterfaceGetIORegistryEntryID (SCNetworkInterfaceRef interface) __OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_0);
+/*!
+ @function _SCNetworkInterfaceIsApplePreconfigured
+ @discussion Identifies if a network interface is internal/pre-configured.
+ @param interface The network interface.
+ @result TRUE if the interface is an internal/pre-configured.
+ */
+Boolean
+_SCNetworkInterfaceIsApplePreconfigured (SCNetworkInterfaceRef interface) __OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0);
+
/*!
@function _SCNetworkInterfaceIsBluetoothPAN
@discussion Identifies if a network interface is a Bluetooth PAN (GN) device.
#include "SCNetworkConfigurationInternal.h"
#include "SCPreferencesInternal.h"
#include "SCHelper_client.h"
+#include "plugin_shared.h"
#if !TARGET_OS_IPHONE
#include <EAP8021X/EAPClientProperties.h>
#define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
#endif
+#ifndef kIOUSBHostInterfaceClassName
+#define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
+#endif
+
#include <string.h>
#include <sysdir.h>
#include <mach/mach.h>
}
-#define BT_PAN_NAME "Bluetooth PAN"
-#define BT_PAN_MAC BT_PAN_NAME " (MAC)"
-
static Boolean
processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate,
io_registry_entry_t interface,
while (provider != NULL) {
#if !TARGET_OS_SIMULATOR
if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) ||
- CFEqual(provider, CFSTR(kIOUSBInterfaceClassName))) {
+ CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) ||
+ CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) {
// get USB info (if available)
processUSBInterface(interfacePrivate,
interface,
static CF_RETURNS_RETAINED CFArrayRef
-findMatchingInterfaces(CFDictionaryRef matching, processInterface func,
- CFStringRef hidden_key)
+findMatchingInterfaces(CFDictionaryRef matching,
+ processInterface func,
+ CFStringRef hidden_key,
+ Boolean keep_pre_configured)
{
CFMutableArrayRef interfaces;
io_registry_entry_t interface;
match = createInterface(interface, func, hidden_key);
if (match != NULL) {
- CFArrayAppendValue(interfaces, match);
+ if (keep_pre_configured || !_SCNetworkInterfaceIsApplePreconfigured(match)) {
+ CFArrayAppendValue(interfaces, match);
+ }
CFRelease(match);
}
if (matching == NULL) {
goto done;
}
- matching_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey);
+ matching_interfaces = findMatchingInterfaces(matching,
+ processNetworkInterface,
+ kSCNetworkInterfaceHiddenInterfaceKey,
+ TRUE);
CFRelease(matching);
}
} else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+ matching_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ TRUE);
CFRelease(matching);
}
if (ifUnique == NULL) {
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- matching_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+ matching_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ TRUE);
CFRelease(matching);
}
}
// get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
matching = IOServiceMatching(kIONetworkInterfaceClass);
- new_interfaces = findMatchingInterfaces(matching, processNetworkInterface, kSCNetworkInterfaceHiddenInterfaceKey);
+ new_interfaces = findMatchingInterfaces(matching,
+ processNetworkInterface,
+ kSCNetworkInterfaceHiddenInterfaceKey,
+ FALSE);
CFRelease(matching);
return new_interfaces;
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+ new_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ FALSE);
CFRelease(matching);
return new_interfaces;
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- new_interfaces = findMatchingInterfaces(matching, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+ new_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ FALSE);
CFRelease(matching);
return new_interfaces;
dict = SCDynamicStoreCopyValue(store, key);
if (dict != NULL) {
if (isA_CFDictionary(dict) &&
- (CFDictionaryContainsKey(dict, CFSTR("*QUIET*")) ||
- CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*")))) {
+ (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet) ||
+ CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout))) {
quiet = TRUE;
}
CFRelease(dict);
if (isA_CFDictionary(dict) &&
CFDictionaryGetValueIfPresent(dict,
- CFSTR("_" BT_PAN_NAME "_"),
+ kInterfaceNamerKey_BT_PAN_Name,
(const void **)&if_name) &&
isA_CFString(if_name)) {
CFMutableDictionaryRef entity;
if ((interfacePrivate != NULL) &&
(interfacePrivate->address == NULL) &&
CFDictionaryGetValueIfPresent(dict,
- CFSTR("_" BT_PAN_MAC "_"),
+ kInterfaceNamerKey_BT_PAN_Mac,
(const void **)&addr) &&
isA_CFData(addr)) {
interfacePrivate->address = CFRetain(addr);
#pragma mark -
+Boolean
+_SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface)
+{
+#if !TARGET_OS_SIMULATOR
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if (!interfacePrivate->hidden) {
+ // if not HiddenConfiguration
+ return FALSE;
+ }
+
+ if ((interfacePrivate->overrides == NULL) ||
+ (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) &&
+ !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) {
+ // if no [IPv4/IPv6] configuration overrides
+ return FALSE;
+ }
+
+ if (interfacePrivate->builtin) {
+ // if built-in (and overrides are present)
+ return TRUE;
+ }
+
+ if (isA_CFNumber(interfacePrivate->usb.vid)) {
+ int vid;
+
+ if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) &&
+ (vid == kIOUSBVendorIDAppleComputer)) {
+ // if Apple interface (and overrides are present)
+ return TRUE;
+ }
+ }
+#endif // !TARGET_OS_SIMULATOR
+
+ return FALSE;
+}
+
+
Boolean
_SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface)
{
1565D85018B847590097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; };
1565D85118B847F20097062B /* SCNetworkMigration.c in Sources */ = {isa = PBXBuildFile; fileRef = 55A3DB9D183C2A8200ED3DB7 /* SCNetworkMigration.c */; };
156BD6BC07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1572AA8C1D8235390021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA8D1D8235940021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA8E1D8235A40021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA8F1D82375A0021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA901D8237810021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA911D82379E0021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
+ 1572AA921D8237A30021E093 /* plugin_shared.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572AA8B1D8234500021E093 /* plugin_shared.h */; };
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 = (Project, Public, ); }; };
1572C4AB0CFB55B400E2776E /* SCPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 15CB691505C0722B0099E85F /* SCPrivate.h */; settings = {ATTRIBUTES = (Private, Project, ); }; };
155F49A51C864FE500E47D08 /* qos-marking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "qos-marking.m"; path = "Plugins/QoSMarking/qos-marking.m"; sourceTree = "<group>"; };
1567333E0DD1FD6500145179 /* entitlements-ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "entitlements-ios.plist"; sourceTree = "<group>"; };
156BD6BB07E0DFA9008698FF /* SCPreferencesSetSpecificPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SCPreferencesSetSpecificPrivate.h; sourceTree = "<group>"; };
+ 1572AA8B1D8234500021E093 /* plugin_shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_shared.h; sourceTree = "<group>"; };
1572C57E171CCF9500870549 /* pppcontroller_mach_defines.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; name = pppcontroller_mach_defines.h; path = usr/local/include/ppp/pppcontroller_mach_defines.h; sourceTree = SDKROOT; };
1572EB7A0A506D3B00D02459 /* smb-configuration.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "smb-configuration.c"; sourceTree = "<group>"; };
15732AAC16EA503300F3AC4C /* configd_sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = configd_sim; sourceTree = BUILT_PRODUCTS_DIR; };
F9A3780F16A4846E00C57CDC /* IPMonitorControlPrefs.h */,
159D53CA07528B36004F8947 /* cache.c */,
159D53CB07528B36004F8947 /* cache.h */,
+ 1572AA8B1D8234500021E093 /* plugin_shared.h */,
);
name = common;
path = Plugins/common;
1572C4D40CFB55B400E2776E /* SCNetworkConnectionPrivate.h in Headers */,
1572C4D50CFB55B400E2776E /* SCPreferencesKeychainPrivate.h in Headers */,
F9347FF8187C7993003D4178 /* IPMonitorControl.h in Headers */,
+ 1572AA901D8237810021E093 /* plugin_shared.h in Headers */,
F9347FF9187C7993003D4178 /* IPMonitorControlPrivate.h in Headers */,
F9347FFA187C7993003D4178 /* symbol_scope.h in Headers */,
1572C4D60CFB55B400E2776E /* SCSchemaDefinitionsPrivate.h in Headers */,
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1572AA8C1D8235390021E093 /* plugin_shared.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1572AA911D82379E0021E093 /* plugin_shared.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1572AA8F1D82375A0021E093 /* plugin_shared.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1572AA8D1D8235940021E093 /* plugin_shared.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
15A1FF3410597F17004C9CC9 /* CaptiveNetwork.h in Headers */,
159A7528107FEAA400A57EAB /* VPNPrivate.h in Headers */,
159A752A107FEAA400A57EAB /* VPNConfiguration.h in Headers */,
+ 1572AA921D8237A30021E093 /* plugin_shared.h in Headers */,
15C330D3134B95AA0028E36B /* SCNetworkReachabilityInternal.h in Headers */,
727AF25419138699009AB153 /* VPNAppLayerPrivate.h in Headers */,
15D8B22C1450D8450090CECF /* SCD.h in Headers */,
154CF3F407E1EA4D00D8302E /* SCPreferencesGetSpecificPrivate.h in Headers */,
C4CDB8171631938000819B44 /* VPNFlow.h in Headers */,
155A1E6C081079CC00F70D98 /* SCNetworkConfigurationPrivate.h in Headers */,
+ 1572AA8E1D8235A40021E093 /* plugin_shared.h in Headers */,
155B7BF80847776D00F0E262 /* SCHelper_client.h in Headers */,
15D8B22A1450D8450090CECF /* SCD.h in Headers */,
15A297300A13C08C009879B3 /* SCNetworkConnectionPrivate.h in Headers */,
/*
- * Copyright (c) 2004-2006, 2008, 2009, 2011-2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006, 2008, 2009, 2011-2013, 2015, 2016 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* 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 <sys/socket.h>
#include <netinet/in.h>
-#define DNSINFO_VERSION 20140114
+#define DNSINFO_VERSION 20160901
#define DEFAULT_SEARCH_ORDER 200000 /* search order for the "default" resolver domain name */
#pragma pack()
-#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_A_RECORDS 0x0002 /* always requesting for A dns records in queries */
+#define DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS 0x0004 /* always requesting for AAAA dns records in queries */
#define DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS \
(DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS | DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS)
+#define DNS_RESOLVER_FLAGS_SCOPED 0x1000 /* configuration is for scoped questions */
+#define DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC 0x2000 /* configuration is service-specific */
+#define DNS_RESOLVER_FLAGS_SUPPLEMENTAL 0x4000 /* supplemental match configuration */
+
+
#pragma pack(4)
typedef struct {
DNS_VAR(int32_t, n_resolver); /* resolver configurations */
flags &= ~DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
CFStringAppendFormat(str, NULL, CFSTR("Service-specific%s"), flags != 0 ? ", " : "");
}
+ if (flags & DNS_RESOLVER_FLAGS_SUPPLEMENTAL) {
+ flags &= ~DNS_RESOLVER_FLAGS_SUPPLEMENTAL;
+ CFStringAppendFormat(str, NULL, CFSTR("Supplemental%s"), flags != 0 ? ", " : "");
+ }
if (flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) {
flags &= ~DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
CFStringAppendFormat(str, NULL, CFSTR("Request A records%s"), flags != 0 ? ", " : "");
goto done;
}
+ // try to select an [Apple] pre-configured / hidden interface by its BSD name
+
+ selected = _SCNetworkInterfaceCreateWithBSDName(NULL, select_name, kIncludeNoVirtualInterfaces);
+ if (selected != NULL) {
+ goto done;
+ }
+
// try to select the interface by its interface type
for (i = 0; i < n; i++) {
prefix,
isPhysicalEthernet ? "" : " not");
+ if (_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+ SCPrint(TRUE, stdout, CFSTR("%@ is pre-configured\n"), prefix);
+ }
+
if (configuration != NULL) {
CFMutableDictionaryRef effective;