]> git.saurik.com Git - apple/configd.git/commitdiff
configd-136.2.tar.gz mac-os-x-10410ppc mac-os-x-10411ppc mac-os-x-1047ppc mac-os-x-1048ppc mac-os-x-1049ppc v136.2
authorApple <opensource@apple.com>
Mon, 7 Aug 2006 22:37:29 +0000 (22:37 +0000)
committerApple <opensource@apple.com>
Mon, 7 Aug 2006 22:37:29 +0000 (22:37 +0000)
18 files changed:
Plugins/ATconfig/Info.plist
Plugins/IPMonitor/Info.plist
Plugins/IPMonitor/dns-configuration.c
Plugins/IPMonitor/ip_plugin.c
Plugins/InterfaceNamer/Info.plist
Plugins/KernelEventMonitor/Info.plist
Plugins/Kicker/Info.plist
Plugins/LinkConfiguration/Info.plist
Plugins/PreferencesMonitor/Info.plist
SystemConfiguration.fproj/Info.plist
SystemConfiguration.fproj/NetworkConfiguration.plist
SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
SystemConfiguration.fproj/SCNetworkInterface.c
SystemConfiguration.fproj/SCNetworkReachability.c
SystemConfiguration.fproj/SCNetworkService.c
SystemConfiguration.fproj/SCPPath.c
configd.xcode/project.pbxproj

index f0f3990b6b05579300f393e42a7255b7c1d4b20d..b7032f7f1e0949932feba2ccde323137ca45c5f0 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index ab418681e03bb49cd79e197b76fab0e853b78896..eacab67a7952434c4e4b543bdf5b22ecc4557ed6 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index bcbae5aa80cbdd71c0008c9a4bfb068075476c6b..d8ed3045607997fa6bf66c10a25aa8ea698dc042 100644 (file)
@@ -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);
index 8603a743781017ac9617606dbc3d446a3cb31800..daa906522d75186060545c19527d14a9f502ad89 100644 (file)
@@ -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);
index f7265859f0716ace73e7f49ca68b42eab764590c..a65b9928b866dc82bf2eb323afdeef91ade5ff52 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 46962c3708f968fc27a1ed137f22e4645536b5d0..d223f68809dc545e355d6168e7b0d3029634269b 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 7fcdde632e4fa32bf17e3e71bc962b5965383bdd..17bf9e386ff0677ae80406f51d58c9962c716002 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 37c3026913f2a730d28f9179a093f2f9d1da083d..f403d7df3fe195400ee3f82833fb82c67a936e31 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index a1ae55c7119fe8e5d12ee583337f99e81f68e66a..578b8262d9e1543197a5111987944d4097a85298 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index fdd2fa0fe7d1d185655e4856cdb68b1128834e2e..4f233ea8b6738bc7f1e745229e9f5de815b3ebf3 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.8.2</string>
+       <string>1.8.3</string>
 </dict>
 </plist>
index a56f10033c9faefd661a09701a1dad02c28243c5..46a3254a6b0d512c3868e85ea9cc1cb46a901c97 100644 (file)
@@ -23,7 +23,7 @@
                <key>Modem</key>
                <dict>
                        <key>ConnectionScript</key>
-                       <string>Apple Internal 56K Modem (v.92)</string>
+                       <string>Apple Internal 56K Modem (v.34)</string>
                        <key>DataCompression</key>
                        <integer>1</integer>
                        <key>DialMode</key>
                        <key>VerboseLogging</key>
                        <integer>0</integer>
                </dict>
+               <key>PPP-IEEE80211</key>
+               <dict>
+                       <key>ACSPEnabled</key>
+                       <integer>0</integer>
+                       <key>CommDisplayTerminalWindow</key>
+                       <integer>0</integer>
+                       <key>CommRedialCount</key>
+                       <integer>1</integer>
+                       <key>CommRedialEnabled</key>
+                       <integer>1</integer>
+                       <key>CommRedialInterval</key>
+                       <integer>5</integer>
+                       <key>CommUseTerminalScript</key>
+                       <integer>0</integer>
+                       <key>DialOnDemand</key>
+                       <integer>0</integer>
+                       <key>DisconnectOnIdle</key>
+                       <integer>0</integer>
+                       <key>DisconnectOnIdleTimer</key>
+                       <integer>1800</integer>
+                       <key>DisconnectOnLogout</key>
+                       <integer>1</integer>
+                       <key>DisconnectOnSleep</key>
+                       <integer>1</integer>
+                       <key>IPCPCompressionVJ</key>
+                       <integer>1</integer>
+                       <key>IdleReminder</key>
+                       <integer>0</integer>
+                       <key>IdleReminderTimer</key>
+                       <integer>1800</integer>
+                       <key>LCPEchoEnabled</key>
+                       <integer>1</integer>
+                       <key>LCPEchoFailure</key>
+                       <integer>4</integer>
+                       <key>LCPEchoInterval</key>
+                       <integer>10</integer>
+                       <key>Logfile</key>
+                       <string>/var/log/ppp.log</string>
+                       <key>VerboseLogging</key>
+                       <integer>0</integer>
+               </dict>
                <key>PPP-IrDA</key>
                <dict/>
                <key>PPP-L2TP</key>
                <key>IEEE80211</key>
                <dict>
                        <key>AppleTalk</key>
-                       <dict/>
+                       <dict>
+                               <key>ConfigMethod</key>
+                               <string>Node</string>
+                               <key>__INACTIVE__</key>
+                               <true/>
+                       </dict>
                        <key>DNS</key>
                        <dict/>
                        <key>IPv4</key>
                                <string>DHCP</string>
                        </dict>
                        <key>IPv6</key>
-                       <dict/>
+                       <dict>
+                               <key>ConfigMethod</key>
+                               <string>Automatic</string>
+                       </dict>
                        <key>Proxies</key>
                        <dict>
                                <key>FTPPassive</key>
index d9f157922068e4deafbef78fa06adcdbf7217ca2..14266e6beb4c88488c3b466e340fe8764085f6e7 100644 (file)
@@ -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) {
index e0c981b38862f214b948c88283e3f76c07afa28a..0a3f2dd39b1c418e18f889f1d1fa8a4e831f0777 100644 (file)
@@ -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,
index 058a032ecc491daa1fc4939eba2246dad02c5c68..9943ed13220554f81db689ffa65ea1b820cf6b5b 100644 (file)
 #include "SCNetworkConfiguration.h"
 #include "SCNetworkConfigurationInternal.h"
 
+#include <string.h>
 #include <mach/mach.h>
 #include <net/if.h>
 #include <net/if_types.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <pthread.h>
+#include <NSSystemDirectories.h>
 
 
 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("<SCNetworkInterface %p [%p]> { "), cf, allocator);
+       CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkInterface %p [%p]> {"), 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;
index a1c41ef7bdd09683c838e990d2a49db333344b9f..038c61be677aac40505e441b935404b97cc4b1c7 100644 (file)
@@ -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;
index db30ae7724e434a435e3eaedbce4325c176a6fdf..5a88d5399494e7cd13f5fe4091c16188ea27e3f5 100644 (file)
@@ -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);
index ef817dd7fe1fb9d88ad232582b1b246c42c60427..dce62a0b780dc97b4dc7903b226c360c9f23f597 100644 (file)
@@ -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;
        }
index 076f68b8e9e16b377ab4d4b134e6e44cae458a02..4c5e1bfd4842155ccb5b7cb981b415debf7c0524 100644 (file)
                        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";
                        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";
                        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";
                };
                15CB6A7705C0722B0099E85F = {
                        buildSettings = {
-                               CURRENT_PROJECT_VERSION = 136.1;
+                               CURRENT_PROJECT_VERSION = 136.2;
                                FRAMEWORK_SEARCH_PATHS = "";
                                HEADER_SEARCH_PATHS = "";
                                INSTALL_GROUP = wheel;
                        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";
                        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";