X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/4c5e92e2493bdfbbce40e998f3b607c72c47af2c..dbf6a266c384fc8b55e00a396eebe5cb62e21547:/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c?ds=sidebyside diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c new file mode 100644 index 0000000..d9f1579 --- /dev/null +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2004 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 + * + * May 27, 2004 Allan Nathanson + * - initial revision + */ + + +#include +#include +#include +#include + +#include +#include + + +__private_extern__ CFDictionaryRef +__getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path) +{ + CFDictionaryRef config; + CFIndex n; + + config = SCPreferencesPathGetValue(prefs, path); + + n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0; + switch (n) { + case 0 : + // ignore empty configuration entities + config = NULL; + break; + case 1 : + if (CFDictionaryContainsKey(config, kSCResvInactive)) { + // ignore [effectively] empty configuration entities + config = NULL; + } + break; + default : + break; + } + + return config; +} + + +__private_extern__ Boolean +__setPrefsConfiguration(SCPreferencesRef prefs, + CFStringRef path, + CFDictionaryRef config, + Boolean keepInactive) +{ + CFMutableDictionaryRef newConfig = NULL; + Boolean ok = FALSE; + + if (config != NULL) { + if (!isA_CFDictionary(config)) { + _SCErrorSet(kSCStatusInvalidArgument); + return FALSE; + } + newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); + } else { + newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + + if (keepInactive) { + CFDictionaryRef curConfig; + + /* + * preserve enabled/disabled state + */ + + curConfig = SCPreferencesPathGetValue(prefs, path); + if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { + // if currently disabled + CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); + } else { + // if currently enabled + CFDictionaryRemoveValue(newConfig, kSCResvInactive); + } + } + + /* + * set new configuration + */ + + if (CFDictionaryGetCount(newConfig) == 0) { + CFRelease(newConfig); + newConfig = NULL; + } + + if (newConfig == NULL) { + ok = SCPreferencesPathRemoveValue(prefs, path); + } else { + ok = SCPreferencesPathSetValue(prefs, path, newConfig); + } + + if (newConfig != NULL) CFRelease(newConfig); + 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) +{ + CFDictionaryRef curConfig = NULL; + CFMutableDictionaryRef newConfig = NULL; + Boolean ok = FALSE; + + /* + * preserve current configuration + */ + + curConfig = SCPreferencesPathGetValue(prefs, path); + if (curConfig != NULL) { + if (!isA_CFDictionary(curConfig)) { + _SCErrorSet(kSCStatusFailed); + return FALSE; + } + newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig); + } else { + newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + + if (enabled) { + // enable + CFDictionaryRemoveValue(newConfig, kSCResvInactive); + } else { + // disable + CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); + } + + /* + * update configuration + */ + + if (CFDictionaryGetCount(newConfig) == 0) { + CFRelease(newConfig); + newConfig = NULL; + } + + if (newConfig == NULL) { + ok = SCPreferencesPathRemoveValue(prefs, path); + } else { + ok = SCPreferencesPathSetValue(prefs, path, newConfig); + } + + if (newConfig != NULL) CFRelease(newConfig); + return ok; +} + + +#define SYSTEMCONFIGURATION_BUNDLE_ID CFSTR("com.apple.SystemConfiguration") +#define SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration.framework" + + +static CFDictionaryRef +__copyTemplates() +{ + CFBundleRef bundle; + Boolean ok; + CFDictionaryRef templates; + CFURLRef url; + CFStringRef xmlError = NULL; + CFDataRef xmlTemplates = NULL; + + bundle = CFBundleGetBundleWithIdentifier(SYSTEMCONFIGURATION_BUNDLE_ID); + if (bundle == NULL) { + return NULL; + } + + url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL); + if (url == NULL) { + return NULL; + } + + ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL); + CFRelease(url); + if (!ok || (xmlTemplates == NULL)) { + return NULL; + } + + /* convert the XML data into a property list */ + templates = CFPropertyListCreateFromXMLData(NULL, xmlTemplates, kCFPropertyListImmutable, &xmlError); + CFRelease(xmlTemplates); + if (templates == NULL) { + if (xmlError != NULL) { + SCLog(TRUE, LOG_DEBUG, CFSTR("could not load SCNetworkConfiguration templates: %@"), xmlError); + CFRelease(xmlError); + } + return NULL; + } + + if (!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; + + 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; + + 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) && (CFDictionaryGetCount(protocol) > 0)) { + CFRetain(protocol); + } else { + protocol = NULL; + } + } + + CFRelease(templates); + + return protocol; +} + + +__private_extern__ Boolean +__createInterface(int s, CFStringRef interface) +{ + struct ifreq ifr; + + bzero(&ifr, sizeof(ifr)); + (void) _SC_cfstring_to_cstring(interface, + ifr.ifr_name, + sizeof(ifr.ifr_name), + kCFStringEncodingASCII); + + if (ioctl(s, SIOCIFCREATE, &ifr) == -1) { + SCLog(TRUE, + LOG_ERR, + CFSTR("could not create interface \"%@\": %s"), + interface, + strerror(errno)); + return FALSE; + } + + return TRUE; +} + + +__private_extern__ Boolean +__destroyInterface(int s, CFStringRef interface) +{ + struct ifreq ifr; + + bzero(&ifr, sizeof(ifr)); + (void) _SC_cfstring_to_cstring(interface, + ifr.ifr_name, + sizeof(ifr.ifr_name), + kCFStringEncodingASCII); + + if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) { + SCLog(TRUE, + LOG_ERR, + CFSTR("could not destroy interface \"%@\": %s"), + interface, + strerror(errno)); + return FALSE; + } + + return TRUE; +} + + +__private_extern__ Boolean +__markInterfaceUp(int s, CFStringRef interface) +{ + struct ifreq ifr; + + bzero(&ifr, sizeof(ifr)); + (void) _SC_cfstring_to_cstring(interface, + ifr.ifr_name, + sizeof(ifr.ifr_name), + kCFStringEncodingASCII); + + if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) { + SCLog(TRUE, + LOG_ERR, + CFSTR("could not get flags for interface \"%@\": %s"), + interface, + strerror(errno)); + return FALSE; + } + + ifr.ifr_flags |= IFF_UP; + if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) { + SCLog(TRUE, + LOG_ERR, + CFSTR("could not set flags for interface \"%@\": %s"), + interface, + strerror(errno)); + return FALSE; + } + + return TRUE; +}