SCNetworkConfigurationInternal.c [plain text]
#include "SCNetworkConfigurationInternal.h"
#include "SCPreferencesInternal.h"
#include <sys/ioctl.h>
#include <net/if.h>
#pragma mark -
#pragma mark SCNetworkConfiguration logging
__private_extern__ os_log_t
__log_SCNetworkConfiguration(void)
{
static os_log_t log = NULL;
if (log == NULL) {
log = os_log_create("com.apple.SystemConfiguration", "SCNetworkConfiguration");
}
return log;
}
static void
logConfiguration_NetworkInterfaces(int level, const char *description, SCPreferencesRef prefs)
{
CFArrayRef interfaces;
interfaces = SCPreferencesGetValue(prefs, INTERFACES);
if (isA_CFArray(interfaces)) {
CFStringRef model = SCPreferencesGetValue(prefs, MODEL);
CFIndex n = CFArrayGetCount(interfaces);
SC_log(level, "%s%sinterfaces (%@)",
description != NULL ? description : "",
description != NULL ? " " : "",
model != NULL ? model : CFSTR("No model"));
for (CFIndex i = 0; i < n; i++) {
CFStringRef bsdName;
CFDictionaryRef dict;
CFDictionaryRef info;
CFStringRef name;
dict = CFArrayGetValueAtIndex(interfaces, i);
if (!isA_CFDictionary(dict)) {
continue;
}
bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName));
if (!isA_CFString(bsdName)) {
continue;
}
info = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceInfo));
name = CFDictionaryGetValue(info, kSCPropUserDefinedName);
SC_log(level, " %@ (%@)",
bsdName,
name != NULL ? name : CFSTR("???"));
}
}
}
static void
logConfiguration_preferences(int level, const char *description, SCPreferencesRef prefs)
{
CFStringRef model = SCPreferencesGetValue(prefs, MODEL);
CFIndex n;
CFMutableArrayRef orphans;
CFArrayRef services;
CFArrayRef sets;
SC_log(level, "%s%sconfiguration (%@)",
description != NULL ? description : "",
description != NULL ? " " : "",
model != NULL ? model : CFSTR("No model"));
services = SCNetworkServiceCopyAll(prefs);
if (services != NULL) {
orphans = CFArrayCreateMutableCopy(NULL, 0, services);
CFRelease(services);
} else {
orphans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
}
sets = SCNetworkSetCopyAll(prefs);
if (sets != NULL) {
n = CFArrayGetCount(sets);
for (CFIndex i = 0; i < n; i++) {
SCNetworkSetRef set;
set = CFArrayGetValueAtIndex(sets, i);
SC_log(level, " Set %@ (%@)",
SCNetworkSetGetSetID(set),
SCNetworkSetGetName(set));
services = SCNetworkSetCopyServices(set);
if (services != NULL) {
CFIndex n;
CFIndex nOrder = 0;
CFArrayRef order;
order = SCNetworkSetGetServiceOrder(set);
if (order != NULL) {
nOrder = CFArrayGetCount(order);
}
n = CFArrayGetCount(services);
if (n > 1) {
CFMutableArrayRef sorted;
sorted = CFArrayCreateMutableCopy(NULL, 0, services);
CFArraySortValues(sorted,
CFRangeMake(0, CFArrayGetCount(sorted)),
_SCNetworkServiceCompare,
(void *)order);
CFRelease(services);
services = sorted;
}
for (CFIndex i = 0; i < n; i++) {
CFStringRef bsdName;
SCNetworkInterfaceRef interface;
CFIndex o;
CFIndex orderIndex = kCFNotFound;
SCNetworkServiceRef service;
CFStringRef serviceName;
CFStringRef serviceID;
CFStringRef userDefinedName;
service = CFArrayGetValueAtIndex(services, i);
serviceID = SCNetworkServiceGetServiceID(service);
serviceName = SCNetworkServiceGetName(service);
if (serviceName == NULL) serviceName = CFSTR("");
interface = SCNetworkServiceGetInterface(service);
bsdName = SCNetworkInterfaceGetBSDName(interface);
userDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
if (_SC_CFEqual(serviceName, userDefinedName)) {
userDefinedName = NULL;
}
if (order != NULL) {
orderIndex = CFArrayGetFirstIndexOfValue(order,
CFRangeMake(0, nOrder),
serviceID);
}
if (orderIndex != kCFNotFound) {
SC_log(level, " Service %2ld : %@, %2d (%@%s%@%s%@)",
orderIndex + 1,
serviceID,
__SCNetworkInterfaceOrder(interface), serviceName,
bsdName != NULL ? ", " : "",
bsdName != NULL ? bsdName : CFSTR(""),
userDefinedName != NULL ? " : " : "",
userDefinedName != NULL ? userDefinedName : CFSTR(""));
} else {
SC_log(level, " Service : %@, %2d (%@%s%@%s%@)",
serviceID,
__SCNetworkInterfaceOrder(interface), serviceName,
bsdName != NULL ? ", " : "",
bsdName != NULL ? bsdName : CFSTR(""),
userDefinedName != NULL ? " : " : "",
userDefinedName != NULL ? userDefinedName : CFSTR(""));
}
o = CFArrayGetFirstIndexOfValue(orphans, CFRangeMake(0, CFArrayGetCount(orphans)), service);
if (o != kCFNotFound) {
CFArrayRemoveValueAtIndex(orphans, o);
}
}
CFRelease(services);
}
}
CFRelease(sets);
}
n = CFArrayGetCount(orphans);
if (n > 0) {
SC_log(level, " Orphans");
for (CFIndex i = 0; i < n; i++) {
CFStringRef bsdName;
SCNetworkInterfaceRef interface;
SCNetworkServiceRef service;
CFStringRef serviceName;
CFStringRef serviceID;
service = CFArrayGetValueAtIndex(orphans, i);
serviceID = SCNetworkServiceGetServiceID(service);
serviceName = SCNetworkServiceGetName(service);
if (serviceName == NULL) serviceName = CFSTR("");
interface = SCNetworkServiceGetInterface(service);
bsdName = SCNetworkInterfaceGetBSDName(interface);
SC_log(level, " Service : %@, %2d (%@%s%@)",
serviceID,
__SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), serviceName,
bsdName != NULL ? ", " : "",
bsdName != NULL ? bsdName : CFSTR(""));
}
}
CFRelease(orphans);
return;
}
void
__SCNetworkConfigurationReport(int level, const char *description, SCPreferencesRef prefs, SCPreferencesRef ni_prefs)
{
logConfiguration_NetworkInterfaces(level, description, ni_prefs);
logConfiguration_preferences (level, description, prefs);
return;
}
#pragma mark -
#pragma mark Misc
static Boolean
isEffectivelyEmptyConfiguration(CFDictionaryRef config)
{
Boolean empty = FALSE;
CFIndex n;
n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0;
switch (n) {
case 0 :
empty = TRUE;
break;
case 1 :
if (CFDictionaryContainsKey(config, kSCResvInactive)) {
empty = TRUE;
}
break;
default :
break;
}
return empty;
}
__private_extern__ CFDictionaryRef
__SCNetworkConfigurationGetValue(SCPreferencesRef prefs, CFStringRef path)
{
CFDictionaryRef config;
config = SCPreferencesPathGetValue(prefs, path);
if (isEffectivelyEmptyConfiguration(config)) {
config = NULL;
}
return config;
}
__private_extern__ Boolean
__SCNetworkConfigurationSetValue(SCPreferencesRef prefs,
CFStringRef path,
CFDictionaryRef config,
Boolean keepInactive)
{
Boolean changed;
CFDictionaryRef curConfig;
CFMutableDictionaryRef newConfig = NULL;
Boolean ok;
if ((config != NULL) && !isA_CFDictionary(config)) {
_SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
}
curConfig = SCPreferencesPathGetValue(prefs, path);
curConfig = isA_CFDictionary(curConfig);
if (config != NULL) {
newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
}
if (keepInactive) {
if (config == NULL) {
newConfig = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
} else {
CFDictionaryRemoveValue(newConfig, kSCResvInactive);
}
}
changed = !_SC_CFEqual(curConfig, newConfig);
if (!changed) {
if (newConfig != NULL) CFRelease(newConfig);
ok = TRUE;
} else if (newConfig != NULL) {
ok = SCPreferencesPathSetValue(prefs, path, newConfig);
CFRelease(newConfig);
} else {
ok = SCPreferencesPathRemoveValue(prefs, path);
if (!ok && (SCError() == kSCStatusNoKey)) {
ok = TRUE;
}
}
return ok;
}
__private_extern__ Boolean
__getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path)
{
CFDictionaryRef config;
config = SCPreferencesPathGetValue(prefs, path);
if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) {
return FALSE;
}
return TRUE;
}
__private_extern__ Boolean
__setPrefsEnabled(SCPreferencesRef prefs,
CFStringRef path,
Boolean enabled)
{
Boolean changed;
CFDictionaryRef curConfig;
CFMutableDictionaryRef newConfig = NULL;
Boolean ok = FALSE;
curConfig = SCPreferencesPathGetValue(prefs, path);
if (curConfig != NULL) {
if (!isA_CFDictionary(curConfig)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig);
if (enabled) {
CFDictionaryRemoveValue(newConfig, kSCResvInactive);
} else {
CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
}
} else {
if (!enabled) {
newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
}
}
changed = !_SC_CFEqual(curConfig, newConfig);
if (!changed) {
if (newConfig != NULL) CFRelease(newConfig);
ok = TRUE;
} else if (newConfig != NULL) {
ok = SCPreferencesPathSetValue(prefs, path, newConfig);
CFRelease(newConfig);
} else {
ok = SCPreferencesPathRemoveValue(prefs, path);
if (!ok && (SCError() == kSCStatusNoKey)) {
ok = TRUE;
}
}
return ok;
}
#if TARGET_OS_OSX
#define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH "/Resources"
#else
#define SYSTEMCONFIGURATION_RESOURCES_PATH SYSTEMCONFIGURATION_FRAMEWORK_PATH
#endif // TARGET_OS_OSX
#define NETWORKCONFIGURATION_RESOURCE_FILE "NetworkConfiguration.plist"
static CFDictionaryRef
__copyTemplates()
{
CFBundleRef bundle;
CFDictionaryRef templates;
CFURLRef url;
bundle = _SC_CFBundleGet();
if (bundle == NULL) {
return NULL;
}
url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL);
if (url == NULL) {
SC_log(LOG_ERR, "failed to GET resource URL to \"%s\". Trying harder...", NETWORKCONFIGURATION_RESOURCE_FILE);
url = CFURLCreateWithFileSystemPath(NULL,
CFSTR(SYSTEMCONFIGURATION_RESOURCES_PATH
"/"
NETWORKCONFIGURATION_RESOURCE_FILE),
kCFURLPOSIXPathStyle,
TRUE);
if (url == NULL) {
SC_log(LOG_ERR, "failed to CREATE resource URL to \"%s\"", SYSTEMCONFIGURATION_RESOURCES_PATH
"/"
NETWORKCONFIGURATION_RESOURCE_FILE);
return NULL;
}
}
templates = _SCCreatePropertyListFromResource(url);
CFRelease(url);
if ((templates != NULL) && !isA_CFDictionary(templates)) {
CFRelease(templates);
return NULL;
}
return templates;
}
__private_extern__ CFDictionaryRef
__copyInterfaceTemplate(CFStringRef interfaceType,
CFStringRef childInterfaceType)
{
CFDictionaryRef interface = NULL;
CFDictionaryRef interfaces;
CFDictionaryRef templates;
templates = __copyTemplates();
if (templates == NULL) {
return NULL;
}
interfaces = CFDictionaryGetValue(templates, CFSTR("Interface"));
if (!isA_CFDictionary(interfaces)) {
CFRelease(templates);
return NULL;
}
if (childInterfaceType == NULL) {
interface = CFDictionaryGetValue(interfaces, interfaceType);
} else {
CFStringRef expandedType;
if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) {
childInterfaceType = CFSTR("*");
}
expandedType = CFStringCreateWithFormat(NULL,
NULL,
CFSTR("%@-%@"),
interfaceType,
childInterfaceType);
interface = CFDictionaryGetValue(interfaces, expandedType);
CFRelease(expandedType);
}
if (isA_CFDictionary(interface) && (CFDictionaryGetCount(interface) > 0)) {
CFRetain(interface);
} else {
interface = NULL;
}
CFRelease(templates);
return interface;
}
__private_extern__ CFDictionaryRef
__copyProtocolTemplate(CFStringRef interfaceType,
CFStringRef childInterfaceType,
CFStringRef protocolType)
{
CFDictionaryRef interface = NULL;
CFDictionaryRef protocol = NULL;
CFDictionaryRef protocols;
CFDictionaryRef templates;
templates = __copyTemplates();
if (templates == NULL) {
return NULL;
}
protocols = CFDictionaryGetValue(templates, CFSTR("Protocol"));
if (!isA_CFDictionary(protocols)) {
CFRelease(templates);
return NULL;
}
if (childInterfaceType == NULL) {
interface = CFDictionaryGetValue(protocols, interfaceType);
} else {
CFStringRef expandedType;
if (CFStringFind(childInterfaceType, CFSTR("."), 0).location != kCFNotFound) {
childInterfaceType = CFSTR("*");
}
expandedType = CFStringCreateWithFormat(NULL,
NULL,
CFSTR("%@-%@"),
interfaceType,
childInterfaceType);
interface = CFDictionaryGetValue(protocols, expandedType);
CFRelease(expandedType);
}
if (isA_CFDictionary(interface)) {
protocol = CFDictionaryGetValue(interface, protocolType);
if (isA_CFDictionary(protocol)) {
CFRetain(protocol);
} else {
protocol = NULL;
}
}
CFRelease(templates);
return protocol;
}
__private_extern__ Boolean
__createInterface(int s, CFStringRef interface)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
(void) _SC_cfstring_to_cstring(interface,
ifr.ifr_name,
sizeof(ifr.ifr_name),
kCFStringEncodingASCII);
if (ioctl(s, SIOCIFCREATE, &ifr) == -1) {
SC_log(LOG_NOTICE, "could not create interface \"%@\": %s",
interface,
strerror(errno));
return FALSE;
}
return TRUE;
}
__private_extern__ Boolean
__destroyInterface(int s, CFStringRef interface)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
(void) _SC_cfstring_to_cstring(interface,
ifr.ifr_name,
sizeof(ifr.ifr_name),
kCFStringEncodingASCII);
if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) {
SC_log(LOG_NOTICE, "could not destroy interface \"%@\": %s",
interface,
strerror(errno));
return FALSE;
}
return TRUE;
}
__private_extern__
CFStringRef
__SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(SCPreferencesRef prefs, CFStringRef prefix)
{
static int hack = -1;
CFStringRef path = NULL;
if (hack < 0) {
CFBooleanRef enable;
enable = SCPreferencesGetValue(prefs, CFSTR("MoreSCF"));
hack = (isA_CFBoolean(enable) && CFBooleanGetValue(enable)) ? 1 : 0;
}
if (hack > 0) {
CFDictionaryRef dict;
Boolean ok;
path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), prefix, CFSTR("0"));
dict = SCPreferencesPathGetValue(prefs, path);
if (dict != NULL) {
CFRelease(path);
return NULL;
}
dict = CFDictionaryCreate(NULL,
NULL, NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
ok = SCPreferencesPathSetValue(prefs, path, dict);
CFRelease(dict);
if (!ok) {
CFRelease(path);
return NULL;
}
}
return path;
}
static CFDataRef
__copy_legacy_password(CFTypeRef password)
{
if (password == NULL) {
return NULL;
}
if (isA_CFData(password)) {
CFIndex n;
n = CFDataGetLength(password);
if ((n % sizeof(UniChar)) == 0) {
CFStringEncoding encoding;
CFStringRef str;
#if __BIG_ENDIAN__
encoding = (*(CFDataGetBytePtr(password) + 1) == 0x00) ? kCFStringEncodingUTF16LE : kCFStringEncodingUTF16BE;
#else // __LITTLE_ENDIAN__
encoding = (*(CFDataGetBytePtr(password) ) == 0x00) ? kCFStringEncodingUTF16BE : kCFStringEncodingUTF16LE;
#endif
str = CFStringCreateWithBytes(NULL,
(const UInt8 *)CFDataGetBytePtr(password),
n,
encoding,
FALSE);
password = CFStringCreateExternalRepresentation(NULL,
str,
kCFStringEncodingUTF8,
0);
CFRelease(str);
} else {
password = NULL;
}
} else if (isA_CFString(password) && (CFStringGetLength(password) > 0)) {
password = CFStringCreateExternalRepresentation(NULL,
password,
kCFStringEncodingUTF8,
0);
} else {
password = NULL;
}
return password;
}
__private_extern__
Boolean
__extract_password(SCPreferencesRef prefs,
CFDictionaryRef config,
CFStringRef passwordKey,
CFStringRef encryptionKey,
CFStringRef encryptionKeyChainValue,
CFStringRef unique_id,
CFDataRef *password)
{
CFStringRef encryption = NULL;
Boolean exists = FALSE;
if (config != NULL) {
encryption = CFDictionaryGetValue(config, encryptionKey);
}
if ((encryption == NULL) ||
(isA_CFString(encryption) &&
CFEqual(encryption, encryptionKeyChainValue))) {
if (password != NULL) {
if (prefs != NULL) {
*password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id);
} else {
*password = _SCSecKeychainPasswordItemCopy(NULL, unique_id);
}
exists = (*password != NULL);
} else {
if (prefs != NULL) {
exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id);
} else {
exists = _SCSecKeychainPasswordItemExists(NULL, unique_id);
}
}
}
if (!exists && (encryption == NULL) && (config != NULL)) {
CFDataRef inline_password;
inline_password = CFDictionaryGetValue(config, passwordKey);
inline_password = __copy_legacy_password(inline_password);
if (inline_password != NULL) {
exists = TRUE;
if (password != NULL) {
*password = inline_password;
} else {
CFRelease(inline_password);
}
}
}
return exists;
}
__private_extern__
Boolean
__remove_password(SCPreferencesRef prefs,
CFDictionaryRef config,
CFStringRef passwordKey,
CFStringRef encryptionKey,
CFStringRef encryptionKeyChainValue,
CFStringRef unique_id,
CFDictionaryRef *newConfig)
{
CFStringRef encryption = NULL;
Boolean ok = FALSE;
if (config != NULL) {
encryption = CFDictionaryGetValue(config, encryptionKey);
}
if ((encryption == NULL) ||
(isA_CFString(encryption) &&
CFEqual(encryption, encryptionKeyChainValue))) {
if (prefs != NULL) {
ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
} else {
ok = _SCSecKeychainPasswordItemRemove(NULL, unique_id);
}
}
if (!ok && (encryption == NULL) && (config != NULL)) {
CFDataRef inline_password;
inline_password = CFDictionaryGetValue(config, passwordKey);
inline_password = __copy_legacy_password(inline_password);
if (inline_password != NULL) {
CFRelease(inline_password);
ok = TRUE;
}
}
if (newConfig != NULL) {
if (ok && (config != NULL)) {
CFMutableDictionaryRef temp;
temp = CFDictionaryCreateMutableCopy(NULL, 0, config);
CFDictionaryRemoveValue(temp, passwordKey);
CFDictionaryRemoveValue(temp, encryptionKey);
*newConfig = (CFDictionaryRef)temp;
} else {
*newConfig = NULL;
}
}
return ok;
}
__private_extern__ Boolean
__rank_to_str(SCNetworkServicePrimaryRank rank, CFStringRef *rankStr)
{
switch (rank) {
case kSCNetworkServicePrimaryRankDefault :
*rankStr = NULL;
break;
case kSCNetworkServicePrimaryRankFirst :
*rankStr = kSCValNetServicePrimaryRankFirst;
break;
case kSCNetworkServicePrimaryRankLast :
*rankStr = kSCValNetServicePrimaryRankLast;
break;
case kSCNetworkServicePrimaryRankNever :
*rankStr = kSCValNetServicePrimaryRankNever;
break;
case kSCNetworkServicePrimaryRankScoped :
*rankStr = kSCValNetServicePrimaryRankScoped;
break;
default :
return FALSE;
}
return TRUE;
}
__private_extern__ Boolean
__str_to_rank(CFStringRef rankStr, SCNetworkServicePrimaryRank *rank)
{
if (isA_CFString(rankStr)) {
if (CFEqual(rankStr, kSCValNetServicePrimaryRankFirst)) {
*rank = kSCNetworkServicePrimaryRankFirst;
} else if (CFEqual(rankStr, kSCValNetServicePrimaryRankLast)) {
*rank = kSCNetworkServicePrimaryRankLast;
} else if (CFEqual(rankStr, kSCValNetServicePrimaryRankNever)) {
*rank = kSCNetworkServicePrimaryRankNever;
} else if (CFEqual(rankStr, kSCValNetServicePrimaryRankScoped)) {
*rank = kSCNetworkServicePrimaryRankScoped;
} else {
return FALSE;
}
} else if (rankStr == NULL) {
*rank = kSCNetworkServicePrimaryRankDefault;
} else {
return FALSE;
}
return TRUE;
}
#define kSCNetworkConfigurationFlagsBypassSystemInterfaces (1<<0)
#define kSCNetworkConfigurationFlagsBypassSystemInterfacesForced (1<<1)
Boolean
_SCNetworkConfigurationBypassSystemInterfaces(SCPreferencesRef prefs)
{
Boolean bypass;
uint32_t nc_flags;
nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
bypass = ((nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfaces) != 0);
if (bypass ||
(nc_flags & kSCNetworkConfigurationFlagsBypassSystemInterfacesForced) != 0) {
return bypass;
}
if (!__SCPreferencesUsingDefaultPrefs(prefs)) {
return TRUE;
}
return FALSE;
}
void
_SCNetworkConfigurationSetBypassSystemInterfaces(SCPreferencesRef prefs, Boolean shouldBypass)
{
uint32_t nc_flags;
nc_flags = __SCPreferencesGetNetworkConfigurationFlags(prefs);
if (shouldBypass) {
nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfaces;
} else {
nc_flags &= ~kSCNetworkConfigurationFlagsBypassSystemInterfaces;
}
nc_flags |= kSCNetworkConfigurationFlagsBypassSystemInterfacesForced;
__SCPreferencesSetNetworkConfigurationFlags(prefs, nc_flags);
return;
}