/* * 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; }