From: Apple Date: Mon, 7 Aug 2006 22:37:29 +0000 (+0000) Subject: configd-136.2.tar.gz X-Git-Tag: mac-os-x-10410ppc^0 X-Git-Url: https://git.saurik.com/apple/configd.git/commitdiff_plain/c387a05da0fa0df1d260acaa042ff33357016d94 configd-136.2.tar.gz --- diff --git a/Plugins/ATconfig/Info.plist b/Plugins/ATconfig/Info.plist index f0f3990..b7032f7 100644 --- a/Plugins/ATconfig/Info.plist +++ b/Plugins/ATconfig/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/IPMonitor/Info.plist b/Plugins/IPMonitor/Info.plist index ab41868..eacab67 100644 --- a/Plugins/IPMonitor/Info.plist +++ b/Plugins/IPMonitor/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/IPMonitor/dns-configuration.c b/Plugins/IPMonitor/dns-configuration.c index bcbae5a..d8ed304 100644 --- a/Plugins/IPMonitor/dns-configuration.c +++ b/Plugins/IPMonitor/dns-configuration.c @@ -108,6 +108,8 @@ add_supplemental(CFMutableArrayRef supplemental, CFDictionaryRef dns, uint32_t d num = CFNumberCreate(NULL, kCFNumberIntType, &defaultOrder); CFDictionarySetValue(match_resolver, kSCPropNetDNSSearchOrder, num); CFRelease(num); + + defaultOrder++; // if multiple domains, maintain ordering } match_order = CFDictionaryGetValue(match_resolver, kSCPropNetDNSSearchOrder); @@ -291,6 +293,42 @@ compareBySearchOrder(const void *val1, const void *val2, void *context) } +static CFStringRef +trimDomain(CFStringRef domain) +{ + CFIndex length; + CFRange range; + Boolean trimmed = FALSE; + + if (!isA_CFString(domain)) { + return NULL; + } + + // remove trailing dots + length = CFStringGetLength(domain); + while (CFStringFindWithOptions(domain, + CFSTR("."), + CFRangeMake(0, length), + kCFCompareAnchored|kCFCompareBackwards, + &range)) { + trimmed = TRUE; + length = range.location; + } + + if (length == 0) { + return NULL; + } + + if (trimmed) { + domain = CFStringCreateWithSubstring(NULL, domain, CFRangeMake(0, length)); + } else { + CFRetain(domain); + } + + return domain; +} + + static void update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef supplemental) { @@ -299,13 +337,13 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme CFArrayRef defaultSearchDomains = NULL; CFIndex defaultSearchIndex = 0; CFIndex i; - CFIndex n; CFMutableArrayRef mySearchDomains; CFMutableArrayRef mySupplemental = (CFMutableArrayRef)supplemental; + CFIndex n_supplemental; Boolean searchDomainAdded = FALSE; - n = CFArrayGetCount(supplemental); - if (n == 0) { + n_supplemental = CFArrayGetCount(supplemental); + if (n_supplemental == 0) { // if no supplemental domains return; } @@ -323,20 +361,36 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme defaultSearchDomains = CFDictionaryGetValue(*defaultDomain, kSCPropNetDNSSearchDomains); } + mySearchDomains = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + if (isA_CFArray(defaultSearchDomains)) { - mySearchDomains = CFArrayCreateMutableCopy(NULL, 0, defaultSearchDomains); + CFIndex n_search; + + n_search = CFArrayGetCount(defaultSearchDomains); + for (i = 0; i < n_search; i++) { + CFStringRef search; + + search = CFArrayGetValueAtIndex(defaultSearchDomains, i); + search = trimDomain(search); + if (search != NULL) { + CFArrayAppendValue(mySearchDomains, search); + CFRelease(search); + } + } } else { - mySearchDomains = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - if (isA_CFString(defaultDomainName)) { + defaultDomainName = trimDomain(defaultDomainName); + if (defaultDomainName != NULL) { char *domain; - int domain_parts = 1; - char *dp; + int domain_parts = 1; + char *dp; domain = _SC_cfstring_to_cstring(defaultDomainName, NULL, 0, kCFStringEncodingUTF8); + CFRelease(defaultDomainName); + // count domain parts for (dp = domain; *dp != '\0'; dp++) { if (*dp == '.') { domain_parts++; @@ -345,13 +399,13 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme dp = domain; for (i = LOCALDOMAINPARTS; i <= domain_parts; i++) { - CFStringRef searchDomain; + CFStringRef search; - searchDomain = CFStringCreateWithCString(NULL, - dp, - kCFStringEncodingUTF8); - CFArrayAppendValue(mySearchDomains, searchDomain); - CFRelease(searchDomain); + search = CFStringCreateWithCString(NULL, + dp, + kCFStringEncodingUTF8); + CFArrayAppendValue(mySearchDomains, search); + CFRelease(search); dp = strchr(dp, '.') + 1; } @@ -360,16 +414,17 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme } } - if (n > 1) { + if (n_supplemental > 1) { mySupplemental = CFArrayCreateMutableCopy(NULL, 0, supplemental); CFArraySortValues(mySupplemental, - CFRangeMake(0, n), + CFRangeMake(0, n_supplemental), compareBySearchOrder, NULL); } - for (i = 0; i < n; i++) { + for (i = 0; i < n_supplemental; i++) { CFDictionaryRef dns; + CFIndex domainIndex; CFNumberRef num; CFStringRef supplementalDomain; uint32_t supplementalOrder; @@ -377,13 +432,21 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme dns = CFArrayGetValueAtIndex(mySupplemental, i); supplementalDomain = CFDictionaryGetValue(dns, kSCPropNetDNSDomainName); - if (CFArrayContainsValue(mySearchDomains, - CFRangeMake(0, CFArrayGetCount(mySearchDomains)), - supplementalDomain)) { - // if supplemental domain is already in the search list + supplementalDomain = trimDomain(supplementalDomain); + if (supplementalDomain == NULL) { continue; } + if (CFStringHasSuffix(supplementalDomain, CFSTR(".in-addr.arpa")) || + CFStringHasSuffix(supplementalDomain, CFSTR(".ip6.arpa" ))) { + CFRelease(supplementalDomain); + continue; + } + + domainIndex = CFArrayGetFirstIndexOfValue(mySearchDomains, + CFRangeMake(0, CFArrayGetCount(mySearchDomains)), + supplementalDomain); + num = CFDictionaryGetValue(dns, kSCPropNetDNSSearchOrder); if (!isA_CFNumber(num) || !CFNumberGetValue(num, kCFNumberIntType, &supplementalOrder)) { @@ -391,15 +454,27 @@ update_search_domains(CFMutableDictionaryRef *defaultDomain, CFArrayRef suppleme } if (supplementalOrder < defaultOrder) { + if (domainIndex != kCFNotFound) { + // if supplemental domain is already in the search list + CFArrayRemoveValueAtIndex(mySearchDomains, domainIndex); + if (domainIndex < defaultSearchIndex) { + defaultSearchIndex--; + } + } CFArrayInsertValueAtIndex(mySearchDomains, defaultSearchIndex, supplementalDomain); defaultSearchIndex++; + searchDomainAdded = TRUE; } else { - CFArrayAppendValue(mySearchDomains, supplementalDomain); + if (domainIndex == kCFNotFound) { + // add to the (end of the) search list + CFArrayAppendValue(mySearchDomains, supplementalDomain); + searchDomainAdded = TRUE; + } } - searchDomainAdded = TRUE; + CFRelease(supplementalDomain); } if (searchDomainAdded) { @@ -492,7 +567,7 @@ create_resolver(CFDictionaryRef dns) p = strchr(buf, '%'); if (p != NULL) { - addr.sin6.sin6_scope_id = if_nametoindex(p+1); + addr.sin6.sin6_scope_id = if_nametoindex(p + 1); } addr.sin6.sin6_len = sizeof(addr.sin6); diff --git a/Plugins/IPMonitor/ip_plugin.c b/Plugins/IPMonitor/ip_plugin.c index 8603a74..daa9065 100644 --- a/Plugins/IPMonitor/ip_plugin.c +++ b/Plugins/IPMonitor/ip_plugin.c @@ -1697,20 +1697,16 @@ update_dnsinfo(CFStringRef primary, CFArrayRef service_order, keyChangeListRef k { CFDictionaryRef dict = NULL; - if (primary != NULL) { + if (primary == NULL) { + dns_configuration_set(NULL, NULL, NULL); + } else { CFDictionaryRef service_dict; service_dict = CFDictionaryGetValue(S_service_state_dict, primary); if (service_dict != NULL) { dict = CFDictionaryGetValue(service_dict, kSCEntNetDNS); } - } - if (dict == NULL) { - /* update DNS configuration */ - dns_configuration_set(NULL, NULL, NULL); - } - else { - /* update DNS configuration */ + dns_configuration_set(dict, S_service_state_dict, service_order); } keyChangeListNotifyKey(keys, S_notify_dnsinfo); diff --git a/Plugins/InterfaceNamer/Info.plist b/Plugins/InterfaceNamer/Info.plist index f726585..a65b992 100644 --- a/Plugins/InterfaceNamer/Info.plist +++ b/Plugins/InterfaceNamer/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/KernelEventMonitor/Info.plist b/Plugins/KernelEventMonitor/Info.plist index 46962c3..d223f68 100644 --- a/Plugins/KernelEventMonitor/Info.plist +++ b/Plugins/KernelEventMonitor/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/Kicker/Info.plist b/Plugins/Kicker/Info.plist index 7fcdde6..17bf9e3 100644 --- a/Plugins/Kicker/Info.plist +++ b/Plugins/Kicker/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/LinkConfiguration/Info.plist b/Plugins/LinkConfiguration/Info.plist index 37c3026..f403d7d 100644 --- a/Plugins/LinkConfiguration/Info.plist +++ b/Plugins/LinkConfiguration/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/Plugins/PreferencesMonitor/Info.plist b/Plugins/PreferencesMonitor/Info.plist index a1ae55c..578b826 100644 --- a/Plugins/PreferencesMonitor/Info.plist +++ b/Plugins/PreferencesMonitor/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion diff --git a/SystemConfiguration.fproj/Info.plist b/SystemConfiguration.fproj/Info.plist index fdd2fa0..4f233ea 100644 --- a/SystemConfiguration.fproj/Info.plist +++ b/SystemConfiguration.fproj/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable SystemConfiguration CFBundleGetInfoString - 1.8.2 + 1.8.3 CFBundleIdentifier com.apple.SystemConfiguration CFBundleInfoDictionaryVersion @@ -17,10 +17,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.8.2 + 1.8.3 CFBundleSignature ???? CFBundleVersion - 1.8.2 + 1.8.3 diff --git a/SystemConfiguration.fproj/NetworkConfiguration.plist b/SystemConfiguration.fproj/NetworkConfiguration.plist index a56f100..46a3254 100644 --- a/SystemConfiguration.fproj/NetworkConfiguration.plist +++ b/SystemConfiguration.fproj/NetworkConfiguration.plist @@ -23,7 +23,7 @@ Modem ConnectionScript - Apple Internal 56K Modem (v.92) + Apple Internal 56K Modem (v.34) DataCompression 1 DialMode @@ -88,6 +88,47 @@ VerboseLogging 0 + PPP-IEEE80211 + + ACSPEnabled + 0 + CommDisplayTerminalWindow + 0 + CommRedialCount + 1 + CommRedialEnabled + 1 + CommRedialInterval + 5 + CommUseTerminalScript + 0 + DialOnDemand + 0 + DisconnectOnIdle + 0 + DisconnectOnIdleTimer + 1800 + DisconnectOnLogout + 1 + DisconnectOnSleep + 1 + IPCPCompressionVJ + 1 + IdleReminder + 0 + IdleReminderTimer + 1800 + LCPEchoEnabled + 1 + LCPEchoFailure + 4 + LCPEchoInterval + 10 + Logfile + /var/log/ppp.log + VerboseLogging + 0 + PPP-IrDA PPP-L2TP @@ -222,7 +263,12 @@ IEEE80211 AppleTalk - + + ConfigMethod + Node + __INACTIVE__ + + DNS IPv4 @@ -231,7 +277,10 @@ DHCP IPv6 - + + ConfigMethod + Automatic + Proxies FTPPassive diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c index d9f1579..14266e6 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004,2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -72,26 +72,20 @@ __setPrefsConfiguration(SCPreferencesRef prefs, CFDictionaryRef config, Boolean keepInactive) { - CFMutableDictionaryRef newConfig = NULL; - Boolean ok = FALSE; + CFMutableDictionaryRef newConfig; + Boolean ok; - if (config != NULL) { - if (!isA_CFDictionary(config)) { - _SCErrorSet(kSCStatusInvalidArgument); - return FALSE; - } - newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); - } else { - newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (!isA_CFDictionary(config)) { + _SCErrorSet(kSCStatusInvalidArgument); + return FALSE; } + newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); + if (keepInactive) { CFDictionaryRef curConfig; - /* - * preserve enabled/disabled state - */ - + // preserve enabled/disabled state curConfig = SCPreferencesPathGetValue(prefs, path); if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { // if currently disabled @@ -102,22 +96,10 @@ __setPrefsConfiguration(SCPreferencesRef prefs, } } - /* - * set new configuration - */ + // set new configuration + ok = SCPreferencesPathSetValue(prefs, path, newConfig); - 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); + CFRelease(newConfig); return ok; } @@ -145,10 +127,7 @@ __setPrefsEnabled(SCPreferencesRef prefs, CFMutableDictionaryRef newConfig = NULL; Boolean ok = FALSE; - /* - * preserve current configuration - */ - + // preserve current configuration curConfig = SCPreferencesPathGetValue(prefs, path); if (curConfig != NULL) { if (!isA_CFDictionary(curConfig)) { @@ -168,10 +147,7 @@ __setPrefsEnabled(SCPreferencesRef prefs, CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } - /* - * update configuration - */ - + // update configuration if (CFDictionaryGetCount(newConfig) == 0) { CFRelease(newConfig); newConfig = NULL; @@ -218,7 +194,7 @@ __copyTemplates() return NULL; } - /* convert the XML data into a property list */ + // convert the XML data into a property list templates = CFPropertyListCreateFromXMLData(NULL, xmlTemplates, kCFPropertyListImmutable, &xmlError); CFRelease(xmlTemplates); if (templates == NULL) { diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h index e0c981b..0a3f2dd 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -104,7 +104,6 @@ typedef struct { // [SCPreferences] interface entity information CFStringRef entity_device; // interface device - CFStringRef entity_hardware; // interface hardware CFStringRef entity_type; // interface type CFStringRef entity_subtype; // interface subtype @@ -117,7 +116,8 @@ typedef struct { Boolean builtin; CFStringRef location; CFStringRef path; - Boolean supportsDeviceOnHold; + CFStringRef modemCCL; + Boolean modemIsV92; Boolean supportsBond; Boolean supportsVLAN; @@ -156,6 +156,9 @@ __SCNetworkInterfaceCreatePrivate (CFAllocatorRef allocator, SCNetworkServiceRef service, io_string_t path); +CFDictionaryRef +__SCNetworkInterfaceCopyInterfaceEntity (SCNetworkInterfaceRef interface); + SCNetworkInterfaceRef __SCNetworkInterfaceCreateWithEntity (CFAllocatorRef allocator, CFDictionaryRef interface_entity, @@ -164,6 +167,12 @@ __SCNetworkInterfaceCreateWithEntity (CFAllocatorRef allocator, CFArrayRef __SCNetworkInterfaceCopyDeepConfiguration (SCNetworkInterfaceRef interface); +CFStringRef +__SCNetworkInterfaceGetModemCCL (SCNetworkInterfaceRef interface); + +Boolean +__SCNetworkInterfaceIsModemV92 (SCNetworkInterfaceRef interface); + Boolean __SCNetworkInterfaceSetConfiguration (SCNetworkInterfaceRef interface, CFDictionaryRef config, diff --git a/SystemConfiguration.fproj/SCNetworkInterface.c b/SystemConfiguration.fproj/SCNetworkInterface.c index 058a032..9943ed1 100644 --- a/SystemConfiguration.fproj/SCNetworkInterface.c +++ b/SystemConfiguration.fproj/SCNetworkInterface.c @@ -59,10 +59,15 @@ #include "SCNetworkConfiguration.h" #include "SCNetworkConfigurationInternal.h" +#include #include #include #include +#include +#include +#include #include +#include static CFStringRef __SCNetworkInterfaceCopyDescription (CFTypeRef cf); @@ -114,7 +119,6 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4 = { NULL, // service NULL, // unsaved NULL, // entity_device - NULL, // entity_hardware NULL, // entity_type NULL, // entity_subtype NULL, // supported_interface_types @@ -123,7 +127,8 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4 = { FALSE, // builtin NULL, // location NULL, // path - FALSE, // supportsDeviceOnHold + NULL, // modemCCL + FALSE, // modemIsV92 FALSE, // supportsBond FALSE, // supportsVLAN kSortUnknown // sort_order @@ -146,28 +151,29 @@ const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4 = (SCNetworkInterfaceRef static const struct { const CFStringRef *interface_type; + const CFStringRef *entity_hardware; Boolean per_interface_config; uint32_t supported_interfaces; const CFStringRef *ppp_subtype; uint32_t supported_protocols; } configurations[] = { - // interface type if config? interface types PPP sub-type interface protocols - // ===================================== ========== ======================= ======================================= ========================================= - { &kSCNetworkInterfaceType6to4 , FALSE, doNone, NULL, doIPv6 }, - { &kSCNetworkInterfaceTypeBluetooth , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, - { &kSCNetworkInterfaceTypeBond , TRUE, doNone, NULL, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, - { &kSCNetworkInterfaceTypeEthernet , TRUE, doPPP, &kSCValNetInterfaceSubTypePPPoE, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, - { &kSCNetworkInterfaceTypeFireWire , TRUE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies }, - { &kSCNetworkInterfaceTypeIEEE80211 , TRUE, doPPP, &kSCValNetInterfaceSubTypePPPoE, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, - { &kSCNetworkInterfaceTypeIrDA , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, - { &kSCNetworkInterfaceTypeL2TP , FALSE, doPPP, &kSCValNetInterfaceSubTypeL2TP, doNone }, - { &kSCNetworkInterfaceTypeModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, - { &kSCNetworkInterfaceTypePPP , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies }, - { &kSCNetworkInterfaceTypePPTP , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone }, - { &kSCNetworkInterfaceTypeSerial , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, - { &kSCNetworkInterfaceTypeVLAN , TRUE, doNone, NULL, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, - // ===================================== ========== ======================= ======================================= ========================================= - { &kSCNetworkInterfaceTypeIPv4 , FALSE, do6to4|doPPTP|doL2TP, NULL, doNone } + // interface type entity_hardware if config? interface types PPP sub-type interface protocols + // ===================================== ================= ========== ======================= ======================================= ========================================= + { &kSCNetworkInterfaceType6to4 , &kSCEntNet6to4 , FALSE, doNone, NULL, doIPv6 }, + { &kSCNetworkInterfaceTypeBluetooth , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, + { &kSCNetworkInterfaceTypeBond , &kSCEntNetEthernet, TRUE , doNone, NULL, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, + { &kSCNetworkInterfaceTypeEthernet , &kSCEntNetEthernet, TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, + { &kSCNetworkInterfaceTypeFireWire , &kSCEntNetFireWire, TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies }, + { &kSCNetworkInterfaceTypeIEEE80211 , &kSCEntNetAirPort , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, + { &kSCNetworkInterfaceTypeIrDA , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, + { &kSCNetworkInterfaceTypeL2TP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypeL2TP, doNone }, + { &kSCNetworkInterfaceTypeModem , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, + { &kSCNetworkInterfaceTypePPP , &kSCEntNetPPP , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies }, + { &kSCNetworkInterfaceTypePPTP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone }, + { &kSCNetworkInterfaceTypeSerial , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone }, + { &kSCNetworkInterfaceTypeVLAN , &kSCEntNetEthernet, TRUE , doNone, NULL, doAppleTalk|doDNS|doIPv4|doIPv6|doProxies }, + // ===================================== ================= ========== ======================= ======================================= ========================================= + { &kSCNetworkInterfaceTypeIPv4 , NULL , FALSE, do6to4|doL2TP|doPPTP, NULL, doNone } }; @@ -210,12 +216,10 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf) SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)cf; result = CFStringCreateMutable(allocator, 0); - CFStringAppendFormat(result, NULL, CFSTR(" { "), cf, allocator); + CFStringAppendFormat(result, NULL, CFSTR(" {"), cf, allocator); CFStringAppendFormat(result, NULL, CFSTR("type = %@"), interfacePrivate->interface_type); - CFStringAppendFormat(result, NULL, CFSTR(", entity = %@ / %@ / %@"), - interfacePrivate->entity_device, - interfacePrivate->entity_hardware, - interfacePrivate->entity_type); + CFStringAppendFormat(result, NULL, CFSTR(", entity_device = %@"), interfacePrivate->entity_device); + CFStringAppendFormat(result, NULL, CFSTR(", entity_type = %@"), interfacePrivate->entity_type); if (interfacePrivate->entity_subtype != NULL) { CFStringAppendFormat(result, NULL, CFSTR(" / %@"), interfacePrivate->entity_subtype); } @@ -239,21 +243,23 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf) if (interfacePrivate->location != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", location = %@"), interfacePrivate->location); } - CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path); + if (interfacePrivate->path != NULL) { + CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path); + } + if (interfacePrivate->modemCCL != NULL) { + CFStringAppendFormat(result, NULL, CFSTR(", modemCCL = %@"), interfacePrivate->modemCCL); + } CFStringAppendFormat(result, NULL, CFSTR(", order = %d"), interfacePrivate->sort_order); - if (interfacePrivate->service != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", service=%@"), interfacePrivate->service); } - if (interfacePrivate->interface != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", interface=%@"), interfacePrivate->interface); } - if (interfacePrivate->unsaved != NULL) { CFStringAppendFormat(result, NULL, CFSTR(", unsaved=%@"), interfacePrivate->unsaved); } - CFStringAppendFormat(result, NULL, CFSTR(" }")); + CFStringAppendFormat(result, NULL, CFSTR("}")); return result; } @@ -299,6 +305,9 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf) if (interfacePrivate->path != NULL) CFRelease(interfacePrivate->path); + if (interfacePrivate->modemCCL != NULL) + CFRelease(interfacePrivate->modemCCL); + return; } @@ -390,7 +399,6 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator, interfacePrivate->service = service; interfacePrivate->unsaved = NULL; interfacePrivate->entity_device = NULL; - interfacePrivate->entity_hardware = NULL; interfacePrivate->entity_type = NULL; interfacePrivate->entity_subtype = NULL; interfacePrivate->supported_interface_types = NULL; @@ -400,7 +408,8 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator, interfacePrivate->path = (path != NULL) ? CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8) : NULL; interfacePrivate->location = NULL; - interfacePrivate->supportsDeviceOnHold = FALSE; + interfacePrivate->modemCCL = NULL; + interfacePrivate->modemIsV92 = FALSE; interfacePrivate->supportsBond = FALSE; interfacePrivate->supportsVLAN = FALSE; interfacePrivate->sort_order = kSortUnknown; @@ -711,77 +720,80 @@ static CFStringRef pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name) { kern_return_t kr; - io_registry_entry_t slot = interface; + io_registry_entry_t parent; + CFMutableStringRef slot; + CFTypeRef slot_name; + slot = NULL; if (pci_slot_name != NULL) *pci_slot_name = NULL; - while (slot != MACH_PORT_NULL) { - io_registry_entry_t parent; - CFTypeRef slot_name; - - slot_name = IORegistryEntryCreateCFProperty(slot, CFSTR("AAPL,slot-name"), NULL, 0); - if (slot_name != NULL) { - Boolean found; - - found = IOStringValueHasPrefix(slot_name, CFSTR("slot")); - if (found) { - CFIndex i; - CFMutableStringRef name; - - // if we found a slot # - name = CFStringCreateMutable(NULL, 0); - if (isA_CFString(slot_name)) { - if (pci_slot_name != NULL) *pci_slot_name = CFStringCreateCopy(NULL, slot_name); - CFStringAppend(name, slot_name); - } else if (isA_CFData(slot_name)) { - if (pci_slot_name != NULL) *pci_slot_name = CFDataCreateCopy(NULL, slot_name); - CFStringAppendCString(name, - (const char *)CFDataGetBytePtr(slot_name), - kCFStringEncodingUTF8); - } - - (void) CFStringFindAndReplace(name, - CFSTR("slot-"), - CFSTR(""), - CFRangeMake(0, 5), - kCFCompareCaseInsensitive|kCFCompareAnchored); - for (i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) { - if (CFStringCompareWithOptions(name, - slot_mappings[i].name, - CFRangeMake(0, CFStringGetLength(slot_mappings[i].name)), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - CFRelease(name); - name = (CFMutableStringRef)CFRetain(slot_mappings[i].slot); - break; - } - } - - CFRelease(slot_name); - if (slot != interface) IOObjectRelease(slot); - return name; - } + slot_name = IORegistryEntryCreateCFProperty(interface, CFSTR("AAPL,slot-name"), NULL, 0); + if (slot_name != NULL) { + CFIndex i; + + slot = CFStringCreateMutable(NULL, 0); + if (isA_CFString(slot_name)) { + if (pci_slot_name != NULL) *pci_slot_name = CFStringCreateCopy(NULL, slot_name); + CFStringAppend(slot, slot_name); + } else if (isA_CFData(slot_name)) { + if (pci_slot_name != NULL) *pci_slot_name = CFDataCreateCopy(NULL, slot_name); + CFStringAppendCString(slot, + (const char *)CFDataGetBytePtr(slot_name), + kCFStringEncodingUTF8); + } - CFRelease(slot_name); + if (CFStringGetLength(slot) > 5) { + (void) CFStringFindAndReplace(slot, + CFSTR("slot-"), + CFSTR(""), + CFRangeMake(0, 5), + kCFCompareCaseInsensitive|kCFCompareAnchored); } - kr = IORegistryEntryGetParentEntry(slot, kIOServicePlane, &parent); - if (slot != interface) IOObjectRelease(slot); - switch (kr) { - case kIOReturnSuccess : - slot = parent; + for (i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) { + if (CFStringCompare(slot, + slot_mappings[i].name, + kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + CFRelease(slot); + slot = (CFMutableStringRef)CFRetain(slot_mappings[i].slot); break; - case kIOReturnNoDevice : - // if we have hit the root node without finding a slot # - goto done; - default : - SCLog(TRUE, LOG_INFO, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr); - goto done; + } } + + CFRelease(slot_name); } - done : + kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &parent); + switch (kr) { + case kIOReturnSuccess : { + CFTypeRef parent_pci_slot_name = NULL; + CFStringRef parent_slot; - return NULL; + parent_slot = pci_slot(parent, &parent_pci_slot_name); + if (parent_slot != NULL) { + if (slot != NULL) CFRelease(slot); + slot = (CFMutableStringRef)parent_slot; + + if (pci_slot_name != NULL) { + if (*pci_slot_name != NULL) CFRelease(*pci_slot_name); + *pci_slot_name = parent_pci_slot_name; + } else { + CFRelease(parent_pci_slot_name); + } + } + + IOObjectRelease(parent); + break; + } + case kIOReturnNoDevice : + // if we have hit the root node + break; + default : + SCLog(TRUE, LOG_DEBUG, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr); + break; + } + + return slot; } @@ -837,7 +849,7 @@ pci_port(mach_port_t masterPort, CFTypeRef slot_name, CFStringRef bsdName) kr = IOServiceGetMatchingServices(masterPort, matching, &slot_iterator); if (kr != kIOReturnSuccess) { - SCPrint(TRUE, stderr, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x\n"), kr); + SCLog(TRUE, LOG_DEBUG, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr); return MACH_PORT_NULL; } @@ -852,7 +864,7 @@ pci_port(mach_port_t masterPort, CFTypeRef slot_name, CFStringRef bsdName) kIORegistryIterateRecursively, &child_iterator); if (kr != kIOReturnSuccess) { - SCPrint(TRUE, stderr, CFSTR("IORegistryEntryCreateIterator() failed, kr = 0x%x\n"), kr); + SCLog(TRUE, LOG_DEBUG, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr); return MACH_PORT_NULL; } @@ -922,43 +934,16 @@ pci_slot_info(mach_port_t masterPort, io_registry_entry_t interface, CFStringRef static Boolean isBuiltIn(io_registry_entry_t interface) { - kern_return_t kr; - io_registry_entry_t slot = interface; - - while (slot != MACH_PORT_NULL) { - io_registry_entry_t parent; - CFTypeRef slot_name; - - slot_name = IORegistryEntryCreateCFProperty(slot, CFSTR("AAPL,slot-name"), NULL, 0); - if (slot_name != NULL) { - Boolean found; - - found = IOStringValueHasPrefix(slot_name, CFSTR("slot")); - CFRelease(slot_name); + CFStringRef slot; - if (found) { - // if we found a slot # then this is not a built-in interface - if (slot != interface) IOObjectRelease(slot); - return FALSE; - } - } - - kr = IORegistryEntryGetParentEntry(slot, kIOServicePlane, &parent); - if (slot != interface) IOObjectRelease(slot); - switch (kr) { - case kIOReturnSuccess : - slot = parent; - break; - case kIOReturnNoDevice : - // if we have hit the root node without finding a slot # - return TRUE; - default : - SCLog(TRUE, LOG_INFO, CFSTR("isBuiltIn IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr); - return FALSE; - } + slot = pci_slot(interface, NULL); + if (slot != NULL) { + // interfaces which have a "slot" are not built-in + CFRelease(slot); + return FALSE; } - return FALSE; + return TRUE; } @@ -986,16 +971,12 @@ processNetworkInterface(mach_port_t masterPort, CFDictionaryRef bus_dict) { CFBooleanRef bVal; - io_name_t c_IOClass; - io_name_t c_IOName; - io_name_t i_IOClass; int ift = -1; int iVal; CFNumberRef num; CFStringRef str; - // get the interface type - + // interface type num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType)); if (!isA_CFNumber(num) || !CFNumberGetValue(num, kCFNumberIntType, &ift)) { @@ -1007,35 +988,21 @@ processNetworkInterface(mach_port_t masterPort, case IFT_ETHER : // Type, Hardware - if (IOObjectGetClass(interface, i_IOClass) != KERN_SUCCESS) { - i_IOClass[0] = '\0'; - } - if (IOObjectGetClass(controller, c_IOClass) != KERN_SUCCESS) { - c_IOClass[0] = '\0'; - } - if (IORegistryEntryGetName(controller, c_IOName) != KERN_SUCCESS) { - c_IOName[0] = '\0'; - } - - if ((strcmp(i_IOClass, "IO80211Interface" ) == 0) || - (strcmp(c_IOClass, "AirPortPCI" ) == 0) || - (strcmp(c_IOClass, "AirPortDriver" ) == 0) || - (strcmp(c_IOName , "AppleWireless80211") == 0)) { + if ((IOObjectConformsTo(controller, "IO80211Controller")) || + (IOObjectConformsTo(controller, "AirPortPCI" )) || + (IOObjectConformsTo(controller, "AirPortDriver" ))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211; interfacePrivate->entity_type = kSCEntNetEthernet; - interfacePrivate->entity_hardware = kSCEntNetAirPort; interfacePrivate->sort_order = kSortAirPort; } else { str = IODictionaryCopyCFStringValue(bus_dict, CFSTR("name")); if ((str != NULL) && CFEqual(str, CFSTR("radio"))) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; // ?? interfacePrivate->entity_type = kSCEntNetEthernet; - interfacePrivate->entity_hardware = kSCEntNetEthernet; // ?? interfacePrivate->sort_order = kSortOtherWireless; } else { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; interfacePrivate->entity_type = kSCEntNetEthernet; - interfacePrivate->entity_hardware = kSCEntNetEthernet; interfacePrivate->sort_order = kSortEthernet; // BOND support only enabled for ethernet devices @@ -1124,7 +1091,6 @@ processNetworkInterface(mach_port_t masterPort, // Entity interfacePrivate->entity_type = kSCEntNetFireWire; - interfacePrivate->entity_hardware = kSCEntNetFireWire; // built-in interfacePrivate->builtin = isBuiltIn(interface); @@ -1147,7 +1113,7 @@ processNetworkInterface(mach_port_t masterPort, break; default : - SCPrint(TRUE, stderr, CFSTR("Unknown interface type = %d\n"), ift); + SCLog(TRUE, LOG_DEBUG, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift); return FALSE; } @@ -1219,18 +1185,18 @@ processSerialInterface(mach_port_t masterPort, // Modem interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem; - // DeviceOnHold support + // V.92 support val = IORegistryEntrySearchCFProperty(interface, kIOServicePlane, CFSTR(kIODeviceSupportsHoldKey), NULL, kIORegistryIterateRecursively | kIORegistryIterateParents); if (val != NULL) { - uint32_t supportsHold; + uint32_t v92; if (isA_CFNumber(val) && - CFNumberGetValue(val, kCFNumberSInt32Type, &supportsHold)) { - interfacePrivate->supportsDeviceOnHold = (supportsHold == 1); + CFNumberGetValue(val, kCFNumberSInt32Type, &v92)) { + interfacePrivate->modemIsV92 = (v92 == 1); } CFRelease(val); } @@ -1248,7 +1214,6 @@ processSerialInterface(mach_port_t masterPort, if (CFEqual(ift, CFSTR(kIOSerialBSDModemType))) { // if modem isModem = TRUE; - interfacePrivate->entity_hardware = kSCEntNetModem; if (CFEqual(str, CFSTR("modem"))) { interfacePrivate->builtin = TRUE; @@ -1260,7 +1225,6 @@ processSerialInterface(mach_port_t masterPort, } } else if (CFEqual(ift, CFSTR(kIOSerialBSDRS232Type))) { // if serial port - interfacePrivate->entity_hardware = kSCEntNetModem; interfacePrivate->sort_order = kSortSerialPort; } else { return FALSE; @@ -1269,13 +1233,24 @@ processSerialInterface(mach_port_t masterPort, // Entity (Device) interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYDeviceKey)); + // modem CCL + val = IORegistryEntrySearchCFProperty(interface, + kIOServicePlane, + CFSTR("ModemCCL"), + NULL, + kIORegistryIterateRecursively | kIORegistryIterateParents); + if (val != NULL) { + interfacePrivate->modemCCL = IOCopyCFStringValue(val); + CFRelease(val); + } + // localized name if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIrDA)) { interfacePrivate->localized_key = CFSTR("irda"); } else if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBluetooth)) { interfacePrivate->localized_key = CFSTR("bluetooth"); } else { - CFStringRef localized; + CFStringRef localized = NULL; CFMutableStringRef port; port = CFStringCreateMutableCopy(NULL, 0, str); @@ -1285,10 +1260,12 @@ processSerialInterface(mach_port_t masterPort, CFStringAppend(port, CFSTR("-port")); } - localized = CFBundleCopyLocalizedString(bundle, - port, - port, - NETWORKINTERFACE_LOCALIZATIONS); + if (bundle != NULL) { + localized = CFBundleCopyLocalizedString(bundle, + port, + port, + NETWORKINTERFACE_LOCALIZATIONS); + } if (localized != NULL) { if (!CFEqual(port, localized)) { // if localization available @@ -1320,7 +1297,14 @@ processSerialInterface(mach_port_t masterPort, // if we have a [somewhat reasonable?] product name CFRelease(interfacePrivate->localized_name); interfacePrivate->localized_name = CFRetain(productName); + + // if not provided, also check if the product name + // matches a CCL script + if (interfacePrivate->modemCCL == NULL) { + interfacePrivate->modemCCL = CFRetain(productName); + } } + CFRelease(productName); } } @@ -1329,6 +1313,55 @@ processSerialInterface(mach_port_t masterPort, CFRelease(port); } + // validate the CCL script + if (interfacePrivate->modemCCL != NULL) { + char ccl[MAXPATHLEN]; + char path[MAXPATHLEN]; + NSSearchPathEnumerationState state; + Boolean valid = FALSE; + + (void) _SC_cfstring_to_cstring(interfacePrivate->modemCCL, + ccl, + sizeof(ccl), + kCFStringEncodingUTF8); + + state = NSStartSearchPathEnumeration(NSLibraryDirectory, + NSLocalDomainMask|NSSystemDomainMask); + while ((state = NSGetNextSearchPathEnumeration(state, path))) { + struct stat statBuf; + + if (ccl[0] == '/') { + path[0] = '\0'; // if modemCCL is a full path + } else { + strlcat(path, "/Modem Scripts/", sizeof(path)); + strlcat(path, ccl, sizeof(path)); + } + + if (stat(path, &statBuf) == 0) { + if (S_ISREG(statBuf.st_mode)) { + // if we have a valid CCL script + valid = TRUE; + break; + } + } else { + if (errno == ENOENT) { + continue; + } + + SCLog(TRUE, LOG_DEBUG, + CFSTR("processSerialInterface stat() failed: %s"), + strerror(errno)); + break; + } + } + + if (!valid) { + // if the CCL script is not valid + CFRelease(interfacePrivate->modemCCL); + interfacePrivate->modemCCL = NULL; + } + } + return TRUE; } @@ -1343,7 +1376,7 @@ findMatchingInterfaces(mach_port_t masterPort, CFDictionaryRef matching, process kr = IOServiceGetMatchingServices(masterPort, matching, &iterator); if (kr != kIOReturnSuccess) { - SCPrint(TRUE, stderr, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x\n"), kr); + SCLog(TRUE, LOG_DEBUG, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr); return NULL; } @@ -1451,7 +1484,6 @@ SCNetworkInterfaceCreateWithBond(BondInterfaceRef bond) interfacePrivate->interface_type = kSCNetworkInterfaceTypeBond; interfacePrivate->entity_type = kSCEntNetEthernet; - interfacePrivate->entity_hardware = kSCEntNetEthernet; interfacePrivate->entity_device = CFStringCreateCopy(NULL, bond_if); interfacePrivate->builtin = TRUE; interfacePrivate->sort_order = kSortBond; @@ -1539,7 +1571,6 @@ SCNetworkInterfaceCreateWithVLAN(VLANInterfaceRef vlan) interfacePrivate->interface_type = kSCNetworkInterfaceTypeVLAN; interfacePrivate->entity_type = kSCEntNetEthernet; - interfacePrivate->entity_hardware = kSCEntNetEthernet; interfacePrivate->entity_device = CFStringCreateCopy(NULL, vlan_if); interfacePrivate->builtin = TRUE; interfacePrivate->sort_order = kSortVLAN; @@ -1607,7 +1638,185 @@ findVLANInterfaces(CFStringRef match) } -/* ---------- interface from preferences ---------- */ +/* ---------- helper functions ---------- */ + + +static CFIndex +findConfiguration(CFStringRef interface_type) +{ + CFIndex i; + + for (i = 0; i < sizeof(configurations)/sizeof(configurations[0]); i++) { + if (CFEqual(interface_type, *configurations[i].interface_type)) { + return i; + } + } + + return kCFNotFound; +} + + +static CFArrayRef +copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate) +{ + CFMutableArrayRef array = NULL; + CFIndex interfaceIndex; + CFStringRef path; + SCNetworkServicePrivateRef servicePrivate; + + servicePrivate = (SCNetworkServicePrivateRef)interfacePrivate->service; + if (servicePrivate == NULL) { + // if not associated with a service (yet) + return NULL; + } + + array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + interfaceIndex = findConfiguration(interfacePrivate->interface_type); + if (interfaceIndex == kCFNotFound) { + // unknown interface type, use per-service configuration preferences + path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator + servicePrivate->serviceID, // service + interfacePrivate->interface_type); // entity + CFArrayAppendValue(array, path); + CFRelease(path); + goto done; + } + + if (configurations[interfaceIndex].entity_hardware == NULL) { + // if no configuration information can be associated with this interface type + CFRelease(array); + array = NULL; + goto done; + } + + if (configurations[interfaceIndex].per_interface_config) { + CFIndex i; + CFIndex n; + CFArrayRef sets; + + // known interface type, per-interface configuration preferences + // + // 1. look for all sets which contain the associated service + // 2. add a per-set path for the interface configuration for + // each set. + + sets = SCNetworkSetCopyAll(servicePrivate->prefs); + n = (sets != NULL) ? CFArrayGetCount(sets) : 0; + + for (i = 0; i < n; i++) { + CFArrayRef services; + SCNetworkSetRef set; + + set = CFArrayGetValueAtIndex(sets, i); + services = SCNetworkSetCopyServices(set); + if (CFArrayContainsValue(services, + CFRangeMake(0, CFArrayGetCount(services)), + interfacePrivate->service)) { + path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator + SCNetworkSetGetSetID(set), // set + interfacePrivate->entity_device, // service + *configurations[interfaceIndex].entity_hardware); // entity + CFArrayAppendValue(array, path); + CFRelease(path); + } + CFRelease(services); + } + + if (CFArrayGetCount(array) == 0) { + CFRelease(array); + array = NULL; + } + + if (sets != NULL) CFRelease(sets); + } else { + // known interface type, per-service configuration preferences + path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator + servicePrivate->serviceID, // service + *configurations[interfaceIndex].entity_hardware); // entity + CFArrayAppendValue(array, path); + CFRelease(path); + } + + done : + + return array; +} + + +/* ---------- preferences entity for interface ---------- */ + + +__private_extern__ CFDictionaryRef +__SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface) +{ + CFMutableDictionaryRef entity; + CFIndex interfaceIndex; + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + entity = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (interfacePrivate->entity_type != NULL) { + CFDictionarySetValue(entity, + kSCPropNetInterfaceType, + interfacePrivate->entity_type); + } + if (interfacePrivate->entity_subtype != NULL) { + CFDictionarySetValue(entity, + kSCPropNetInterfaceSubType, + interfacePrivate->entity_subtype); + } + if (interfacePrivate->entity_device != NULL) { + CFDictionarySetValue(entity, + kSCPropNetInterfaceDeviceName, + interfacePrivate->entity_device); + } + + // match the "hardware" with the lowest layer + while (TRUE) { + SCNetworkInterfaceRef nextInterface; + + nextInterface = SCNetworkInterfaceGetInterface(interface); + if (nextInterface == NULL) { + break; + } + + interface = nextInterface; + } + interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + interfaceIndex = findConfiguration(interfacePrivate->interface_type); + if (interfaceIndex != kCFNotFound) { + if (configurations[interfaceIndex].entity_hardware != NULL) { + CFDictionarySetValue(entity, + kSCPropNetInterfaceHardware, + *configurations[interfaceIndex].entity_hardware); + } + } else { + CFDictionarySetValue(entity, + kSCPropNetInterfaceHardware, + interfacePrivate->interface_type); + } + + if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeModem) && + interfacePrivate->modemIsV92) { + int one = 1; + CFNumberRef num; + + num = CFNumberCreate(NULL, kCFNumberIntType, &one); + CFDictionarySetValue(entity, + kSCPropNetInterfaceSupportsModemOnHold, + num); + CFRelease(num); + } + + return entity; +} + + +/* ---------- interface from preferences entity ---------- */ __private_extern__ SCNetworkInterfaceRef @@ -1622,6 +1831,9 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, static mach_port_t masterPort = MACH_PORT_NULL; CFArrayRef matching_interfaces = NULL; + /* initialize runtime (and kSCNetworkInterfaceIPv4) */ + pthread_once(&initialized, __SCNetworkInterfaceInitialize); + if (masterPort == MACH_PORT_NULL) { kern_return_t kr; @@ -1711,6 +1923,9 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, kSCNetworkInterfaceType6to4); + } else if (CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) { + interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, + ifType); } if (matching_interfaces != NULL) { @@ -1749,7 +1964,7 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, CFRetain(interfacePrivate); break; default : - SCPrint(TRUE, stderr, CFSTR("more than one interface matches %@\n"), ifDevice); + SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice); if (matching_interfaces != NULL) CFRelease(matching_interfaces); _SCErrorSet(kSCStatusFailed); return NULL; @@ -1760,6 +1975,8 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, done : if (interfacePrivate == NULL) { + CFStringRef entity_hardware; + /* * if device not present on this system */ @@ -1767,11 +1984,11 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, interfacePrivate->entity_type = ifType; interfacePrivate->entity_subtype = ifSubType; interfacePrivate->entity_device = (ifDevice != NULL) ? CFStringCreateCopy(NULL, ifDevice) : NULL; - interfacePrivate->entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware); + entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware); if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) { - if ((interfacePrivate->entity_hardware != NULL) && - CFEqual(interfacePrivate->entity_hardware, kSCEntNetAirPort)) { + if ((entity_hardware != NULL) && + CFEqual(entity_hardware, kSCEntNetAirPort)) { interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211; } else { interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet; @@ -1819,100 +2036,6 @@ __SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator, } -/* ---------- helper functions ---------- */ - - -static CFIndex -findConfiguration(CFStringRef interface_type) -{ - CFIndex i; - - for (i = 0; i < sizeof(configurations)/sizeof(configurations[0]); i++) { - if (CFEqual(interface_type, *configurations[i].interface_type)) { - return i; - } - } - - return kCFNotFound; -} - - -static CFArrayRef -copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate) -{ - CFMutableArrayRef array = NULL; - CFIndex interfaceIndex; - CFStringRef path; - SCNetworkServicePrivateRef servicePrivate; - - interfaceIndex = findConfiguration(interfacePrivate->interface_type); - if (interfaceIndex == kCFNotFound) { - // if unknown interface type - return NULL; - } - - servicePrivate = (SCNetworkServicePrivateRef)interfacePrivate->service; - if (servicePrivate == NULL) { - // if not associated with a service (yet) - return NULL; - } - - array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - - if (configurations[interfaceIndex].per_interface_config) { - CFIndex i; - CFIndex n; - CFArrayRef sets; - - /* - * per-interface configuration preferences - * - * 1. look for all sets which contain the associated service - * 2. add a per-set path for the interface configuration for - * each set. - */ - - sets = SCNetworkSetCopyAll(servicePrivate->prefs); - n = (sets != NULL) ? CFArrayGetCount(sets) : 0; - - for (i = 0; i < n; i++) { - CFArrayRef services; - SCNetworkSetRef set; - - set = CFArrayGetValueAtIndex(sets, i); - services = SCNetworkSetCopyServices(set); - if (CFArrayContainsValue(services, - CFRangeMake(0, CFArrayGetCount(services)), - interfacePrivate->service)) { - path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL, // allocator - SCNetworkSetGetSetID(set), // set - interfacePrivate->entity_device, // service - interfacePrivate->entity_type); // entity - CFArrayAppendValue(array, path); - CFRelease(path); - } - CFRelease(services); - } - - if (CFArrayGetCount(array) == 0) { - CFRelease(array); - array = NULL; - } - - CFRelease(sets); - } else { - // per-service configuration preferences - path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator - servicePrivate->serviceID, // service - interfacePrivate->entity_type); // entity - CFArrayAppendValue(array, path); - CFRelease(path); - } - - return array; -} - - /* ---------- SCNetworkInterface APIs ---------- */ @@ -2010,13 +2133,13 @@ SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface) CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + /* initialize runtime (and kSCNetworkInterfaceIPv4) */ + pthread_once(&initialized, __SCNetworkInterfaceInitialize); + if (interfacePrivate->supported_interface_types != NULL) { goto done; } - /* initialize runtime (and kSCNetworkInterfaceIPv4) */ - pthread_once(&initialized, __SCNetworkInterfaceInitialize); - i = findConfiguration(interfacePrivate->interface_type); if (i != kCFNotFound) { if (configurations[i].supported_interfaces != doNone) { @@ -2048,13 +2171,13 @@ SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface) CFIndex i; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + /* initialize runtime (and kSCNetworkInterfaceIPv4) */ + pthread_once(&initialized, __SCNetworkInterfaceInitialize); + if (interfacePrivate->supported_protocol_types != NULL) { goto done; } - /* initialize runtime (and kSCNetworkInterfaceIPv4) */ - pthread_once(&initialized, __SCNetworkInterfaceInitialize); - i = findConfiguration(interfacePrivate->interface_type); if (i != kCFNotFound) { if (configurations[i].supported_protocols != doNone) { @@ -2147,13 +2270,17 @@ SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef i parentPrivate->interface_type = kSCNetworkInterfaceType6to4; parentPrivate->entity_type = kSCEntNet6to4; parentPrivate->entity_device = CFRetain(CFSTR("stf0")); - CFRetain(parentPrivate->entity_device); + } else if (CFStringFind(interfaceType, CFSTR("."), 0).location != kCFNotFound) { + // if custom interface type + parentPrivate->interface_type = interfaceType; + parentPrivate->entity_type = interfaceType; // interface config goes into a + // a dictionary with the same + // name as the interfaceType } else { // unknown interface type goto fail; } - parentPrivate->entity_hardware = childPrivate->entity_hardware; parentPrivate->sort_order = childPrivate->sort_order; return (SCNetworkInterfaceRef)parentPrivate; @@ -2221,6 +2348,7 @@ SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface) return interfacePrivate->address; } + SCNetworkInterfaceRef SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface) { @@ -2251,13 +2379,11 @@ SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface) CFStringRef child = NULL; CFMutableStringRef local = NULL; - pthread_once(&initialized, __SCNetworkInterfaceInitialize); /* initialize runtime */ - if (interfacePrivate->interface != NULL) { child = SCNetworkInterfaceGetLocalizedDisplayName(interfacePrivate->interface); } - if (interfacePrivate->localized_key != NULL) { + if ((bundle != NULL) && (interfacePrivate->localized_key != NULL)) { CFStringRef fmt; fmt = CFBundleCopyLocalizedString(bundle, @@ -2303,6 +2429,26 @@ SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface) } +__private_extern__ +CFStringRef +__SCNetworkInterfaceGetModemCCL(SCNetworkInterfaceRef interface) +{ + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + return interfacePrivate->modemCCL; +} + + +__private_extern__ +Boolean +__SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface) +{ + SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + + return interfacePrivate->modemIsV92; +} + + CFTypeID SCNetworkInterfaceGetTypeID(void) { @@ -2372,8 +2518,11 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator, SCNetworkInterfacePrivateRef oldPrivate = (SCNetworkInterfacePrivateRef)interface; SCNetworkInterfacePrivateRef newPrivate; + /* initialize runtime (and kSCNetworkInterfaceIPv4) */ + pthread_once(&initialized, __SCNetworkInterfaceInitialize); + newPrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL); - newPrivate->interface_type = CFRetain(oldPrivate->interface_type); + newPrivate->interface_type = oldPrivate->interface_type; if (oldPrivate->interface != NULL) { newPrivate->interface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL, // allocator oldPrivate->interface, // interface @@ -2383,7 +2532,6 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator, newPrivate->service = service; newPrivate->unsaved = (oldPrivate->unsaved != NULL) ? CFRetain(oldPrivate->unsaved) : NULL; newPrivate->entity_device = (oldPrivate->entity_device != NULL) ? CFRetain(oldPrivate->entity_device) : NULL; - newPrivate->entity_hardware = CFRetain(oldPrivate->entity_hardware); newPrivate->entity_type = oldPrivate->entity_type; newPrivate->entity_subtype = oldPrivate->entity_subtype; if (oldPrivate->supported_interface_types != NULL) { @@ -2396,7 +2544,8 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator, newPrivate->builtin = oldPrivate->builtin; newPrivate->path = (oldPrivate->path != NULL) ? CFRetain(oldPrivate->path) : NULL; newPrivate->location = (oldPrivate->location != NULL) ? CFRetain(oldPrivate->location) : NULL; - newPrivate->supportsDeviceOnHold = oldPrivate->supportsDeviceOnHold; + newPrivate->modemCCL = (oldPrivate->modemCCL != NULL) ? CFRetain(oldPrivate->modemCCL) : NULL; + newPrivate->modemIsV92 = oldPrivate->modemIsV92; newPrivate->supportsBond = oldPrivate->supportsBond; newPrivate->supportsVLAN = oldPrivate->supportsVLAN; newPrivate->sort_order = oldPrivate->sort_order; diff --git a/SystemConfiguration.fproj/SCNetworkReachability.c b/SystemConfiguration.fproj/SCNetworkReachability.c index a1c41ef..038c61b 100644 --- a/SystemConfiguration.fproj/SCNetworkReachability.c +++ b/SystemConfiguration.fproj/SCNetworkReachability.c @@ -1696,14 +1696,26 @@ _SC_checkResolverReachability(SCDynamicStoreRef *storeP, } } else if (default_resolver->domain != NULL) { char *dp; - int domain_parts = 1; + int domain_parts = 0; + // count domain parts for (dp = default_resolver->domain; *dp != '\0'; dp++) { if (*dp == '.') { domain_parts++; } } + // remove trailing dots + for (dp--; (dp >= default_resolver->domain) && (*dp == '.'); dp--) { + *dp = '\0'; + domain_parts--; + } + + if (dp >= default_resolver->domain) { + // dots are separators, bump # of components + domain_parts++; + } + dp = default_resolver->domain; for (i = LOCALDOMAINPARTS; !found && (i <= domain_parts); i++) { int ret; diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c index db30ae7..5a88d53 100644 --- a/SystemConfiguration.fproj/SCNetworkService.c +++ b/SystemConfiguration.fproj/SCNetworkService.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004, 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -478,8 +478,7 @@ static Boolean __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef service, SCNetworkInterfaceRef interface) { - CFMutableDictionaryRef entity; - SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface; + CFDictionaryRef entity; Boolean ok; CFStringRef path; SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service; @@ -487,41 +486,7 @@ __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef service, path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator servicePrivate->serviceID, // service kSCEntNetInterface); // entity - entity = CFDictionaryCreateMutable(NULL, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - if (interfacePrivate->entity_type != NULL) { - CFDictionarySetValue(entity, - kSCPropNetInterfaceType, - interfacePrivate->entity_type); - } - if (interfacePrivate->entity_subtype != NULL) { - CFDictionarySetValue(entity, - kSCPropNetInterfaceSubType, - interfacePrivate->entity_subtype); - } - if (interfacePrivate->entity_device != NULL) { - CFDictionarySetValue(entity, - kSCPropNetInterfaceDeviceName, - interfacePrivate->entity_device); - } - if (interfacePrivate->entity_hardware != NULL) { - CFDictionarySetValue(entity, - kSCPropNetInterfaceHardware, - interfacePrivate->entity_hardware); - } - if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeModem) && - interfacePrivate->supportsDeviceOnHold) { - int one = 1; - CFNumberRef num; - - num = CFNumberCreate(NULL, kCFNumberIntType, &one); - CFDictionarySetValue(entity, - kSCPropNetInterfaceSupportsModemOnHold, - num); - CFRelease(num); - } + entity = __SCNetworkInterfaceCopyInterfaceEntity(interface); ok = SCPreferencesPathSetValue(servicePrivate->prefs, path, entity); CFRelease(entity); CFRelease(path); @@ -540,6 +505,20 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface) CFStringRef prefix; CFStringRef serviceID; SCNetworkServicePrivateRef servicePrivate; + CFArrayRef supported_protocols; + + // only allow network interfaces which support one or more protocols + // to be added to a service. The one exception is that we allow + // third-party interface types to be configured. + supported_protocols = SCNetworkInterfaceGetSupportedProtocolTypes(interface); + if (supported_protocols == NULL) { + CFStringRef interface_type; + + interface_type = SCNetworkInterfaceGetInterfaceType(interface); + if (CFStringFind(interface_type, CFSTR("."), 0).location == kCFNotFound) { + return NULL; + } + } // establish the service prefix = SCPreferencesPathKeyCreateNetworkServices(NULL); @@ -572,13 +551,35 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface) CFStringRef interfaceType; interfaceType = SCNetworkInterfaceGetInterfaceType(interface); - childInterface = SCNetworkInterfaceGetInterface(servicePrivate->interface); + childInterface = SCNetworkInterfaceGetInterface(interface); if (childInterface != NULL) { childInterfaceType = SCNetworkInterfaceGetInterfaceType(childInterface); } config = __copyInterfaceTemplate(interfaceType, childInterfaceType); if (config != NULL) { + if (CFEqual(interfaceType, kSCNetworkInterfaceTypeModem) || + CFEqual(interfaceType, kSCNetworkInterfaceTypeSerial)) { + CFStringRef modemCCL; + + modemCCL = __SCNetworkInterfaceGetModemCCL(interface); + if (modemCCL == NULL) { + if (__SCNetworkInterfaceIsModemV92(interface)) { + modemCCL = CFSTR("Apple Internal 56K Modem (v.92)"); + } + } + + if (modemCCL != NULL) { + CFMutableDictionaryRef newConfig; + + newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); + CFDictionarySetValue(newConfig, kSCPropNetModemConnectionScript, modemCCL); + + CFRelease(config); + config = newConfig; + } + } + (void) __SCNetworkInterfaceSetConfiguration(interface, config, TRUE); CFRelease(config); } @@ -588,7 +589,7 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface) (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef)servicePrivate, servicePrivate->interface); - // push the [deep] interface configuration into into the service. + // push the [deep] interface configuration into the service. interface_config = __SCNetworkInterfaceCopyDeepConfiguration(servicePrivate->interface); __SCNetworkInterfaceSetDeepConfiguration(servicePrivate->interface, interface_config); @@ -698,7 +699,8 @@ SCNetworkServiceRemove(SCNetworkServiceRef service) set = CFArrayGetValueAtIndex(sets, i); ok = SCNetworkSetRemoveService(set, service); if (!ok && (SCError() != kSCStatusNoKey)) { - break; + CFRelease(sets); + return ok; } } CFRelease(sets); diff --git a/SystemConfiguration.fproj/SCPPath.c b/SystemConfiguration.fproj/SCPPath.c index ef817dd..dce62a0 100644 --- a/SystemConfiguration.fproj/SCPPath.c +++ b/SystemConfiguration.fproj/SCPPath.c @@ -60,18 +60,13 @@ normalizePath(CFStringRef path) for (i = nElements; i > 0; i--) { CFStringRef pathElement; - pathElement = CFArrayGetValueAtIndex(elements, i-1); + pathElement = CFArrayGetValueAtIndex(elements, i - 1); if (CFStringGetLength(pathElement) == 0) { - CFArrayRemoveValueAtIndex(elements, i-1); + CFArrayRemoveValueAtIndex(elements, i - 1); nElements--; } } - if (nElements < 1) { - CFRelease(elements); - return NULL; - } - return elements; } @@ -86,7 +81,6 @@ getPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef *entity) CFIndex nElements; CFIndex nLinks = 0; Boolean ok = FALSE; - SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; CFDictionaryRef value = NULL; elements = normalizePath(path); @@ -95,16 +89,21 @@ getPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef *entity) return FALSE; } - __SCPreferencesAccess(prefs); - restart : nElements = CFArrayGetCount(elements); + + if (nElements < 1) { + SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + __SCPreferencesAccess(prefs); + value = prefsPrivate->prefs; + } + for (i = 0; i < nElements; i++) { element = CFArrayGetValueAtIndex(elements, i); if (i == 0) { - value = CFDictionaryGetValue(prefsPrivate->prefs, - CFArrayGetValueAtIndex(elements, 0)); + value = SCPreferencesGetValue(prefs, CFArrayGetValueAtIndex(elements, 0)); } else { value = CFDictionaryGetValue(value, element); } @@ -120,7 +119,7 @@ getPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef *entity) goto done; } - if ((i < nElements-1) && + if ((i < nElements - 1) && CFDictionaryGetValueIfPresent(value, kSCResvLink, (const void **)&link)) { /* * if not the last path component and this @@ -145,7 +144,7 @@ getPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef *entity) newElements = CFArrayCreateMutableCopy(NULL, 0, linkElements); CFArrayAppendArray(newElements, elements, - CFRangeMake(i+1, nElements-i-1)); + CFRangeMake(i + 1, nElements-i - 1)); CFRelease(elements); elements = newElements; @@ -174,9 +173,13 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) CFIndex nLinks = 0; CFDictionaryRef newEntity = NULL; CFDictionaryRef node = NULL; - CFMutableArrayRef nodes; + CFMutableArrayRef nodes = NULL; Boolean ok = FALSE; - SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + if ((entity != NULL) && !isA_CFDictionary(entity)) { + _SCErrorSet(kSCStatusInvalidArgument); + return FALSE; + } elements = normalizePath(path); if (elements == NULL) { @@ -184,16 +187,38 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) return FALSE; } - __SCPreferencesAccess(prefs); - restart : nElements = CFArrayGetCount(elements); - nodes = CFArrayCreateMutable(NULL, nElements-1, &kCFTypeArrayCallBacks); + + if (nElements < 1) { + SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; + + __SCPreferencesAccess(prefs); + + if (prefsPrivate->prefs != NULL) { + CFRelease(prefsPrivate->prefs); + } + + if (entity == NULL) { + prefsPrivate->prefs = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } else { + prefsPrivate->prefs = CFDictionaryCreateMutableCopy(NULL, 0, entity); + } + + prefsPrivate->changed = TRUE; + ok = TRUE; + goto done; + } + + nodes = CFArrayCreateMutable(NULL, nElements - 1, &kCFTypeArrayCallBacks); for (i = 0; i < nElements - 1; i++) { element = CFArrayGetValueAtIndex(elements, i); if (i == 0) { - node = CFDictionaryGetValue(prefsPrivate->prefs, element); + node = SCPreferencesGetValue(prefs, element); } else { node = CFDictionaryGetValue(node, element); @@ -219,7 +244,7 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) goto done; } - if ((i < nElements-1) && + if ((i < nElements - 1) && CFDictionaryGetValueIfPresent(node, kSCResvLink, (const void **)&link)) { /* * if not the last path component and this @@ -244,7 +269,7 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) newElements = CFArrayCreateMutableCopy(NULL, 0, linkElements); CFArrayAppendArray(newElements, elements, - CFRangeMake(i+1, nElements-i-1)); + CFRangeMake(i + 1, nElements-i - 1)); CFRelease(elements); elements = newElements; @@ -253,25 +278,40 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) } } - if (entity) { + /* + * make sure that the last component doesn't step on top + * of a non-dictionary component. + */ + element = CFArrayGetValueAtIndex(elements, nElements - 1); + if (nElements > 1) { + node = CFArrayGetValueAtIndex(nodes, nElements - 2); + node = CFDictionaryGetValue(node, element); + } else { + node = SCPreferencesGetValue(prefs, element); + } + if ((node != NULL) && !isA_CFDictionary(node)) { + // we won't step on a non-dictionary component + _SCErrorSet(kSCStatusInvalidArgument); + goto done; + } + + if (entity != NULL) { newEntity = CFRetain(entity); } for (i = nElements - 1; i >= 0; i--) { element = CFArrayGetValueAtIndex(elements, i); if (i == 0) { - if (newEntity) { - CFDictionarySetValue(prefsPrivate->prefs, element, newEntity); + if (newEntity != NULL) { + ok = SCPreferencesSetValue(prefs, element, newEntity); } else { - CFDictionaryRemoveValue(prefsPrivate->prefs, element); + ok = SCPreferencesRemoveValue(prefs, element); } - prefsPrivate->changed = TRUE; - ok = TRUE; } else { CFMutableDictionaryRef newNode; - node = CFArrayGetValueAtIndex(nodes, i-1); + node = CFArrayGetValueAtIndex(nodes, i - 1); newNode = CFDictionaryCreateMutableCopy(NULL, 0, node); - if (newEntity) { + if (newEntity != NULL) { CFDictionarySetValue(newNode, element, newEntity); CFRelease(newEntity); } else { @@ -285,13 +325,13 @@ setPath(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef entity) newEntity = newNode; } } - if (newEntity) { + if (newEntity != NULL) { CFRelease(newEntity); } done : - CFRelease(nodes); + if (nodes != NULL) CFRelease(nodes); CFRelease(elements); return ok; } @@ -416,7 +456,22 @@ SCPreferencesPathSetValue(SCPreferencesRef prefs, return FALSE; } - if (!value) { +#define NETPREF_NEEDS_REPAIR +#ifdef NETPREF_NEEDS_REPAIR + if (CFEqual(path, CFSTR("/CurrentSet")) && isA_CFString(value)) { +// static Boolean warned = FALSE; +// if (!warned) { +// SCPrint(TRUE, stderr, CFSTR("SCPreferencesPathSetValue(, %@, ) called with non-dictionary value\n"), path); +// warned = TRUE; +// } + return SCPreferencesSetValue(prefs, CFSTR("CurrentSet"), value); + } +#endif // NETPREF_NEEDS_REPAIR + + if (!isA_CFDictionary(value)) { +#ifdef NETPREF_NEEDS_REPAIR +SCPrint(TRUE, stderr, CFSTR("SCPreferencesPathSetValue(, %@, ) called with non-dictionary value\n"), path); +#endif // NETPREF_NEEDS_REPAIR _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } @@ -441,7 +496,7 @@ SCPreferencesPathSetLink(SCPreferencesRef prefs, return FALSE; } - if (!link) { + if (!isA_CFString(link)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } diff --git a/configd.xcode/project.pbxproj b/configd.xcode/project.pbxproj index 076f68b..4c5e1bf 100644 --- a/configd.xcode/project.pbxproj +++ b/configd.xcode/project.pbxproj @@ -245,7 +245,7 @@ buildRules = ( ); buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -609,7 +609,7 @@ buildRules = ( ); buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; INSTALL_MODE_FLAG = "a-w,a+rX,u+s"; @@ -1949,7 +1949,7 @@ buildRules = ( ); buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; INSTALL_MODE_FLAG = "a-w,a+rX"; @@ -3895,7 +3895,7 @@ }; 15CB6A7705C0722B0099E85F = { buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ""; INSTALL_GROUP = wheel; @@ -4132,7 +4132,7 @@ buildRules = ( ); buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; HEADER_SEARCH_PATHS = "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; @@ -5474,7 +5474,7 @@ buildRules = ( ); buildSettings = { - CURRENT_PROJECT_VERSION = 136.1; + CURRENT_PROJECT_VERSION = 136.2; HEADER_SEARCH_PATHS = "$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INFOPLIST_FILE = Plugins/ATconfig/Info.plist; INSTALL_MODE_FLAG = "a-w,a+rX";