2  * Copyright (c) 2004-2019 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * Modification History 
  27  * May 13, 2004         Allan Nathanson <ajn@apple.com> 
  32 #include <CoreFoundation/CoreFoundation.h> 
  33 #include <CoreFoundation/CFRuntime.h> 
  34 #include "SCNetworkConfigurationInternal.h" 
  39 static CFStringRef      
__SCNetworkSetCopyDescription           (CFTypeRef cf
); 
  40 static void             __SCNetworkSetDeallocate                (CFTypeRef cf
); 
  41 static Boolean          
__SCNetworkSetEqual                     (CFTypeRef cf1
, CFTypeRef cf2
); 
  42 static CFHashCode       
__SCNetworkSetHash                      (CFTypeRef cf
); 
  45 static CFTypeID __kSCNetworkSetTypeID   
= _kCFRuntimeNotATypeID
; 
  48 static const CFRuntimeClass __SCNetworkSetClass 
= { 
  50         "SCNetworkSet",                 // className 
  53         __SCNetworkSetDeallocate
,       // dealloc 
  54         __SCNetworkSetEqual
,            // equal 
  55         __SCNetworkSetHash
,             // hash 
  56         NULL
,                           // copyFormattingDesc 
  57         __SCNetworkSetCopyDescription   
// copyDebugDesc 
  61 static pthread_once_t           initialized     
= PTHREAD_ONCE_INIT
; 
  65 __SCNetworkSetCopyDescription(CFTypeRef cf
) 
  67         CFAllocatorRef          allocator       
= CFGetAllocator(cf
); 
  68         CFMutableStringRef      result
; 
  69         SCNetworkSetRef         set             
= (SCNetworkSetRef
)cf
; 
  70         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
  72         result 
= CFStringCreateMutable(allocator
, 0); 
  73         CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkSet %p [%p]> {"), set
, allocator
); 
  74         CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), setPrivate
->setID
); 
  75         CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), setPrivate
->prefs
); 
  76         if (setPrivate
->name 
!= NULL
) { 
  77                 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), setPrivate
->name
); 
  79         if (!__SCNetworkSetExists(set
)) { 
  80                 CFStringAppendFormat(result
, NULL
, CFSTR(", REMOVED")); 
  82         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  89 __SCNetworkSetDeallocate(CFTypeRef cf
) 
  91         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)cf
; 
  93         /* release resources */ 
  95         CFRelease(setPrivate
->setID
); 
  96         CFRelease(setPrivate
->prefs
); 
  97         if (setPrivate
->name 
!= NULL
) 
  98                 CFRelease(setPrivate
->name
); 
 105 __SCNetworkSetEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 107         SCNetworkSetPrivateRef  s1      
= (SCNetworkSetPrivateRef
)cf1
; 
 108         SCNetworkSetPrivateRef  s2      
= (SCNetworkSetPrivateRef
)cf2
; 
 113         if (s1
->prefs 
!= s2
->prefs
) 
 114                 return FALSE
;   // if not the same prefs 
 116         if (!CFEqual(s1
->setID
, s2
->setID
)) 
 117                 return FALSE
;   // if not the same set identifier 
 124 __SCNetworkSetHash(CFTypeRef cf
) 
 126         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)cf
; 
 128         return CFHash(setPrivate
->setID
); 
 133 __SCNetworkSetInitialize(void) 
 135         __kSCNetworkSetTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkSetClass
); 
 140 static SCNetworkSetPrivateRef
 
 141 __SCNetworkSetCreatePrivate(CFAllocatorRef      allocator
, 
 142                             SCPreferencesRef    prefs
, 
 145         SCNetworkSetPrivateRef  setPrivate
; 
 148         /* initialize runtime */ 
 149         pthread_once(&initialized
, __SCNetworkSetInitialize
); 
 151         /* allocate target */ 
 152         size            
= sizeof(SCNetworkSetPrivate
) - sizeof(CFRuntimeBase
); 
 153         setPrivate 
= (SCNetworkSetPrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 154                                                                       __kSCNetworkSetTypeID
, 
 157         if (setPrivate 
== NULL
) { 
 161         /* initialize non-zero/NULL members */ 
 162         setPrivate
->setID       
= CFStringCreateCopy(NULL
, setID
); 
 163         setPrivate
->prefs       
= CFRetain(prefs
); 
 173 _serviceOrder(SCNetworkServiceRef service
) 
 175         SCNetworkInterfaceRef   interface
; 
 177         interface 
= SCNetworkServiceGetInterface(service
); 
 178         if ((interface 
== NULL
) || _SCNetworkServiceIsVPN(service
)) { 
 179                 return 100000;  // if unknown or VPN interface, sort last 
 182         return __SCNetworkInterfaceOrder(interface
); 
 187 _serviceOrder_clear(CFMutableArrayRef order
, CFStringRef serviceID
) 
 189         CFIndex f
;      // # of serviceID's found 
 195         n 
= CFArrayGetCount(order
); 
 197                 CFStringRef     thisServiceID   
= CFArrayGetValueAtIndex(order
, i
); 
 199                 if (CFEqual(thisServiceID
, serviceID
)) { 
 200                         // remove the serviceID 
 201                         CFArrayRemoveValueAtIndex(order
, i
); 
 207                 i
++;    // move to the next serviceID 
 215 _serviceOrder_add(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 218         CFMutableArrayRef       newOrder
; 
 220         CFStringRef             serviceID       
= SCNetworkServiceGetServiceID(service
); 
 221         CFIndex                 serviceOrder    
= _serviceOrder(service
); 
 222         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
 225         order 
= SCNetworkSetGetServiceOrder(set
); 
 227                 newOrder 
= CFArrayCreateMutableCopy(NULL
, 0, order
); 
 229                 newOrder 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 231         assert(newOrder 
!= NULL
); 
 233         n 
= _serviceOrder_clear(newOrder
, serviceID
); 
 235                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/service already in ServiceOrder\n  service = %@\n  matched = %ld", 
 238                 _SC_crash_once("SCNetworkSetAddService() w/service already in ServiceOrder", NULL
, NULL
); 
 242         n 
= CFArrayGetCount(newOrder
); 
 243         for (CFIndex i 
= 0; i 
< n
; i
++) { 
 245                 SCNetworkServiceRef     slotService
; 
 246                 CFStringRef             slotServiceID
; 
 248                 slotServiceID 
= CFArrayGetValueAtIndex(newOrder
, i
); 
 249                 if (!isA_CFString(slotServiceID
)) { 
 254                 slotService 
= SCNetworkServiceCopy(setPrivate
->prefs
, slotServiceID
); 
 255                 if (slotService 
== NULL
) { 
 256                         // if serviceID not valid 
 260                 slotOrder 
= _serviceOrder(slotService
); 
 261                 if (serviceOrder 
>= slotOrder
) { 
 262                         // add the service *after* this one 
 266                 CFRelease(slotService
); 
 269         CFArrayInsertValueAtIndex(newOrder
, slot
, serviceID
); 
 270         (void) SCNetworkSetSetServiceOrder(set
, newOrder
); 
 278 _serviceOrder_remove(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 281         CFMutableArrayRef       newOrder
; 
 283         CFStringRef             serviceID
; 
 285         order 
= SCNetworkSetGetServiceOrder(set
); 
 289         newOrder 
= CFArrayCreateMutableCopy(NULL
, 0, order
); 
 291         serviceID 
= SCNetworkServiceGetServiceID(service
); 
 293         n 
= _serviceOrder_clear(newOrder
, serviceID
); 
 295                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/multiple instances of service in ServiceOrder\n  service = %@\n  count = %ld", 
 300         (void) SCNetworkSetSetServiceOrder(set
, newOrder
); 
 308 #pragma mark SCNetworkSet APIs 
 311 #define DEFAULT_SET_NAME        CFSTR("Automatic") 
 316 copy_default_set_name(Boolean loc
) 
 319         static CFStringRef      non_localized   
= NULL
; 
 320         static CFStringRef      localized       
= NULL
; 
 323                 static dispatch_once_t  once
; 
 325                 dispatch_once(&once
, ^{ 
 328                         bundle 
= _SC_CFBundleGet(); 
 329                         if (bundle 
!= NULL
) { 
 330                                 non_localized 
= _SC_CFBundleCopyNonLocalizedString(bundle
, 
 331                                                                                    CFSTR("DEFAULT_SET_NAME"), 
 336                 name 
= non_localized
; 
 338                 static dispatch_once_t  once
; 
 340                 dispatch_once(&once
, ^{ 
 343                         bundle 
= _SC_CFBundleGet(); 
 344                         if (bundle 
!= NULL
) { 
 345                                 localized 
= CFBundleCopyLocalizedString(bundle
, 
 346                                                                         CFSTR("DEFAULT_SET_NAME"), 
 355                 // if bundle or localized names not available 
 356                 name 
= DEFAULT_SET_NAME
; 
 364 #define PREVENT_DUPLICATE_SERVICE_NAMES 
 365 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
 367 copy_next_name(CFStringRef name
) 
 369         CFArrayRef              components
; 
 371         CFMutableArrayRef       newComponents
; 
 378         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, name
, CFSTR(" ")); 
 379         if (components 
!= NULL
) { 
 380                 newComponents 
= CFArrayCreateMutableCopy(NULL
, 0, components
); 
 381                 CFRelease(components
); 
 383                 newComponents 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 384                 CFArrayAppendValue(newComponents
, name
); 
 387         n 
= CFArrayGetCount(newComponents
); 
 391                 str 
= CFArrayGetValueAtIndex(newComponents
, n 
- 1); 
 392                 suffix 
= CFStringGetIntValue(str
); 
 394                         CFArrayRemoveValueAtIndex(newComponents
, n 
- 1); 
 400         name 
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), (int)suffix
); 
 401         CFArrayAppendValue(newComponents
, name
); 
 404         name 
= CFStringCreateByCombiningStrings(NULL
, newComponents
, CFSTR(" ")); 
 405         CFRelease(newComponents
); 
 412 ensure_unique_service_name(SCNetworkServiceRef service
) 
 414         SCNetworkInterfaceRef   interface
; 
 418         interface 
= SCNetworkServiceGetInterface(service
); 
 420         name 
= SCNetworkServiceGetName(service
); 
 428                 ok 
= SCNetworkServiceSetName(service
, name
); 
 433                 if (SCError() != kSCStatusKeyExists
) { 
 434                         SC_log(LOG_INFO
, "could not update service name for \"%@\": %s", 
 435                               SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
 436                               SCErrorString(SCError())); 
 440                 newName 
= copy_next_name(name
); 
 441                 if (newName 
== NULL
) { 
 442                         SC_log(LOG_INFO
, "could not create unique name for \"%@\": %s", 
 443                               SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
 444                               SCErrorString(SCError())); 
 448                 // try again with the "new" name 
 461 #endif  // PREVENT_DUPLICATE_SERVICE_NAMES 
 465 SCNetworkSetAddService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 467         SCNetworkInterfaceRef           interface
; 
 468         CFArrayRef                      interface_config        
= NULL
; 
 472         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
 473         SCNetworkSetPrivateRef          setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
 475         if (!isA_SCNetworkSet(set
)) { 
 476                 _SCErrorSet(kSCStatusInvalidArgument
); 
 480         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 481                 _SCErrorSet(kSCStatusInvalidArgument
); 
 485         if (!__SCNetworkSetExists(set
)) { 
 486                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/removed set\n  set = %@\n  service = %@", 
 489                 _SC_crash_once("SCNetworkSetAddService() w/removed set", NULL
, NULL
); 
 490                 _SCErrorSet(kSCStatusInvalidArgument
); 
 493         if (!__SCNetworkServiceExists(service
)) { 
 494                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/removed service\n  set = %@\n  service =  %@", 
 497                 _SC_crash_once("SCNetworkSetAddService() w/removed service", NULL
, NULL
); 
 498                 _SCErrorSet(kSCStatusInvalidArgument
); 
 502         // make sure that we do not add an orphaned network service if its 
 503         // associated interface is a member of a bond or bridge. 
 504         interface 
= SCNetworkServiceGetInterface(service
); 
 505         if ((interface 
!= NULL
) && 
 506             __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) { 
 507                 _SCErrorSet(kSCStatusKeyExists
); 
 511 //#define PREVENT_DUPLICATE_SETS 
 512 #ifdef  PREVENT_DUPLICATE_SETS 
 515         // ensure that each service is only a member of ONE set 
 516         sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
 521                 n 
= CFArrayGetCount(sets
); 
 522                 for (i 
= 0; i 
< n
; i
++) { 
 527                         set 
= CFArrayGetValueAtIndex(sets
, i
); 
 528                         services 
= SCNetworkSetCopyServices(set
); 
 529                         found 
= CFArrayContainsValue(services
, 
 530                                                      CFRangeMake(0, CFArrayGetCount(services
)), 
 536                                 _SCErrorSet(kSCStatusKeyExists
); 
 542 #endif  /* PREVENT_DUPLICATE_SETS */ 
 544         // get the [deep] interface configuration settings 
 545         interface 
= SCNetworkServiceGetInterface(service
); 
 546         if (interface 
!= NULL
) { 
 547                 interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(set
, interface
); 
 550         // create the link between "set" and the "service" 
 551         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
 552                                                                  setPrivate
->setID
,             // set 
 553                                                                  servicePrivate
->serviceID
,     // service 
 555         link 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 556                                                               servicePrivate
->serviceID
,        // service 
 558         ok 
= SCPreferencesPathSetLink(setPrivate
->prefs
, path
, link
); 
 559 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
 561                 // We use the interface cache here to not reach into the 
 562                 // IORegistry for every service we go through 
 563                 _SCNetworkInterfaceCacheOpen(); 
 564                 ok 
= ensure_unique_service_name(service
); 
 565                 _SCNetworkInterfaceCacheClose(); 
 568                         // if we could not ensure a unique name, remove the (just added) 
 569                         // link between the "set" and the "service" 
 570                         (void) SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
 573 #endif  // PREVENT_DUPLICATE_SERVICE_NAMES 
 580         // push the [deep] interface configuration into all sets which contain this service. 
 581         if (interface 
!= NULL
) { 
 582                 __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, interface_config
); 
 585         // add service to ServiceOrder 
 586         _serviceOrder_add(set
, service
); 
 588         // mark set as no longer "new" 
 589         setPrivate
->established 
= TRUE
; 
 594                 SC_log(LOG_DEBUG
, "SCNetworkSetAddService(): %@, %@", set
, service
); 
 597         if (interface_config 
!= NULL
)   CFRelease(interface_config
); 
 603 SCNetworkSetCopy(SCPreferencesRef prefs
, CFStringRef setID
) 
 605         CFDictionaryRef         entity
; 
 607         SCNetworkSetPrivateRef  setPrivate
; 
 609         if (!isA_CFString(setID
)) { 
 610                 _SCErrorSet(kSCStatusInvalidArgument
); 
 614         path 
= SCPreferencesPathKeyCreateSet(NULL
, setID
); 
 615         entity 
= SCPreferencesPathGetValue(prefs
, path
); 
 618         if (!isA_CFDictionary(entity
)) { 
 619                 _SCErrorSet(kSCStatusNoKey
); 
 623         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 624         assert(setPrivate 
!= NULL
); 
 626         // mark set as "old" (already established) 
 627         setPrivate
->established 
= TRUE
; 
 629         return (SCNetworkSetRef
)setPrivate
; 
 634 SCNetworkSetContainsInterface(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
) 
 636         Boolean         found   
= FALSE
; 
 639         services 
= SCNetworkSetCopyServices(set
); 
 640         if (services 
!= NULL
) { 
 641                 found 
= __SCNetworkServiceExistsForInterface(services
, interface
); 
 649 CFArrayRef 
/* of SCNetworkSetRef's */ 
 650 SCNetworkSetCopyAll(SCPreferencesRef prefs
) 
 652         CFMutableArrayRef       array
; 
 655         CFDictionaryRef         sets
; 
 657         path 
= SCPreferencesPathKeyCreateSets(NULL
); 
 658         sets 
= SCPreferencesPathGetValue(prefs
, path
); 
 661         if ((sets 
!= NULL
) && !isA_CFDictionary(sets
)) { 
 665         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 667         n 
= (sets 
!= NULL
) ? CFDictionaryGetCount(sets
) : 0; 
 670                 const void *    keys_q
[N_QUICK
]; 
 671                 const void **   keys    
= keys_q
; 
 672                 const void *    vals_q
[N_QUICK
]; 
 673                 const void **   vals    
= vals_q
; 
 675                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 676                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 677                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 679                 CFDictionaryGetKeysAndValues(sets
, keys
, vals
); 
 680                 for (i 
= 0; i 
< n
; i
++) { 
 681                         SCNetworkSetPrivateRef  setPrivate
; 
 683                         if (!isA_CFDictionary(vals
[i
])) { 
 684                                 SC_log(LOG_INFO
, "error w/set \"%@\"", keys
[i
]); 
 688                         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, keys
[i
]); 
 689                         assert(setPrivate 
!= NULL
); 
 691                         // mark set as "old" (already established) 
 692                         setPrivate
->established 
= TRUE
; 
 694                         CFArrayAppendValue(array
, (SCNetworkSetRef
)setPrivate
); 
 695                         CFRelease(setPrivate
); 
 697                 if (keys 
!= keys_q
) { 
 698                         CFAllocatorDeallocate(NULL
, keys
); 
 699                         CFAllocatorDeallocate(NULL
, vals
); 
 707 CFArrayRef 
/* of SCNetworkInterfaceRef's */ 
 708 SCNetworkSetCopyAvailableInterfaces(SCNetworkSetRef set
) 
 710         CFMutableArrayRef       available
; 
 711         CFMutableSetRef         excluded        
= NULL
; 
 713         CFArrayRef              interfaces
; 
 714         CFIndex                 n_interfaces
; 
 715         CFIndex                 n_exclusions    
= 0; 
 716         SCPreferencesRef        prefs
; 
 717         SCNetworkSetPrivateRef  setPrivate
; 
 719         setPrivate 
= (SCNetworkSetPrivateRef
)set
; 
 720         prefs 
= setPrivate
->prefs
; 
 722         interfaces 
= _SCNetworkInterfaceCopyAllWithPreferences(prefs
); 
 723         n_interfaces 
= CFArrayGetCount(interfaces
); 
 724         if (n_interfaces 
== 0) { 
 729                 CFArrayRef      bridges 
= NULL
; 
 731                 excluded 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 733 #if     !TARGET_OS_IPHONE 
 734                 CFArrayRef      bonds   
= NULL
; 
 736                 bonds 
= SCBondInterfaceCopyAll(prefs
); 
 738                         __SCBondInterfaceListCollectMembers(bonds
, excluded
); 
 741 #endif  /* !TARGET_OS_IPHONE */ 
 743                 bridges 
= SCBridgeInterfaceCopyAll(prefs
); 
 744                 if (bridges 
!= NULL
) { 
 745                         __SCBridgeInterfaceListCollectMembers(bridges
, excluded
); 
 749                 n_exclusions 
= CFSetGetCount(excluded
); 
 752         if (n_exclusions 
== 0) { 
 753                 if (excluded 
!= NULL
) { 
 760         available 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 762         for (i 
= 0; i 
< n_interfaces
; i
++) { 
 763                 SCNetworkInterfaceRef   interface
; 
 765                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
 766                 if (CFSetContainsValue(excluded
, interface
)) { 
 771                 CFArrayAppendValue(available
, interface
); 
 774         CFRelease(interfaces
); 
 782 SCNetworkSetCopyCurrent(SCPreferencesRef prefs
) 
 784         CFArrayRef              components
; 
 785         CFStringRef             currentID
; 
 786         SCNetworkSetPrivateRef  setPrivate      
= NULL
; 
 788         currentID 
= SCPreferencesGetValue(prefs
, kSCPrefCurrentSet
); 
 789         if (!isA_CFString(currentID
)) { 
 793         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, currentID
, CFSTR("/")); 
 794         if (CFArrayGetCount(components
) == 3) { 
 798                 setID 
= CFArrayGetValueAtIndex(components
, 2); 
 799                 path 
= SCPreferencesPathKeyCreateSet(NULL
, setID
); 
 800                 if (CFEqual(path
, currentID
)) { 
 801                         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 802                         assert(setPrivate 
!= NULL
); 
 804                         // mark set as "old" (already established) 
 805                         setPrivate
->established 
= TRUE
; 
 807                         SC_log(LOG_NOTICE
, "SCNetworkSetCopyCurrent(): preferences are non-conformant"); 
 811         CFRelease(components
); 
 813         return (SCNetworkSetRef
)setPrivate
; 
 817 CFArrayRef 
/* of SCNetworkServiceRef's */ 
 818 SCNetworkSetCopyServices(SCNetworkSetRef set
) 
 820         CFMutableArrayRef       array
; 
 821         CFDictionaryRef         dict
; 
 824         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
 826         if (!isA_SCNetworkSet(set
)) { 
 827                 _SCErrorSet(kSCStatusInvalidArgument
); 
 831         path 
= SCPreferencesPathKeyCreateSetNetworkService(NULL
, setPrivate
->setID
, NULL
); 
 832         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
 834         if ((dict 
!= NULL
) && !isA_CFDictionary(dict
)) { 
 838         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 840         n 
= (dict 
!= NULL
) ? CFDictionaryGetCount(dict
) : 0; 
 843                 const void *    keys_q
[N_QUICK
]; 
 844                 const void **   keys    
= keys_q
; 
 846                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 847                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 849                 CFDictionaryGetKeysAndValues(dict
, keys
, NULL
); 
 850                 for (i 
= 0; i 
< n
; i
++) { 
 851                         CFArrayRef      components
; 
 854                         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, 
 856                                                                                  (CFStringRef
)keys
[i
], 
 858                         link 
= SCPreferencesPathGetLink(setPrivate
->prefs
, path
); 
 861                                 SC_log(LOG_INFO
, "service \"%@\" for set \"%@\" is not a link", 
 864                                 continue;        // if the service is not a link 
 867                         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, link
, CFSTR("/")); 
 868                         if (CFArrayGetCount(components
) == 3) { 
 869                                 CFStringRef serviceID
; 
 871                                 serviceID 
= CFArrayGetValueAtIndex(components
, 2); 
 872                                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,             // allocator 
 873                                                                                       serviceID
,        // service 
 875                                 if (CFEqual(path
, link
)) { 
 876                                         CFDictionaryRef entity
; 
 877                                         CFStringRef     interfacePath
; 
 878                                         Boolean         skip            
= FALSE
; 
 880                                         interfacePath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                    // allocator 
 881                                                                                                        serviceID
,               // service 
 882                                                                                                        kSCEntNetInterface
);     // entity 
 883                                         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, interfacePath
); 
 884                                         CFRelease(interfacePath
); 
 886                                         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 887                                                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 892                                                 SCNetworkServicePrivateRef      servicePrivate
; 
 894                                                 servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, 
 898                                                 CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
); 
 899                                                 CFRelease(servicePrivate
); 
 904                         CFRelease(components
); 
 906                 if (keys 
!= keys_q
) { 
 907                         CFAllocatorDeallocate(NULL
, keys
); 
 916 SCNetworkSetCreate(SCPreferencesRef prefs
) 
 918         CFArrayRef              components
; 
 919         CFDictionaryRef         entity
; 
 924         SCNetworkSetPrivateRef  setPrivate
; 
 926         prefix 
= SCPreferencesPathKeyCreateSets(NULL
); 
 927         path 
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
); 
 928         if (path 
== NULL
) path 
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
); 
 934         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/")); 
 935         setID 
= CFArrayGetValueAtIndex(components
, 2); 
 936         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 937         assert(setPrivate 
!= NULL
); 
 938         CFRelease(components
); 
 940         // mark set as "new" (not yet established) 
 941         setPrivate
->established 
= FALSE
; 
 943         // establish the set in the preferences 
 944         entity 
= CFDictionaryCreate(NULL
, 
 946                                     &kCFTypeDictionaryKeyCallBacks
, 
 947                                     &kCFTypeDictionaryValueCallBacks
); 
 948         ok 
= SCPreferencesPathSetValue(prefs
, path
, entity
); 
 952                 CFRelease(setPrivate
); 
 956         if (setPrivate 
!= NULL
) { 
 957                 SC_log(LOG_DEBUG
, "SCNetworkSetCreate(): %@", setPrivate
); 
 960         return (SCNetworkSetRef
)setPrivate
; 
 965 _SCNetworkSetCreateDefault(SCPreferencesRef prefs
) 
 970         CFStringRef     setName         
= NULL
; 
 972         set 
= SCNetworkSetCopyCurrent(prefs
); 
 974                 SC_log(LOG_NOTICE
, "creating default set w/already existing set"); 
 976                 _SCErrorSet(kSCStatusKeyExists
); 
 980         // create a new ("Automatic") set 
 981         set 
= SCNetworkSetCreate(prefs
); 
 983                 SC_log(LOG_NOTICE
, "could not create \"new\" set: %s", 
 984                        SCErrorString(SCError())); 
 988         setName 
= copy_default_set_name(TRUE
); 
 989         ok 
= SCNetworkSetSetName(set
, setName
); 
 992                 // if we could not save the new set's "name" 
 993                 SC_log(LOG_NOTICE
, "could not save the new set's name: %s", 
 994                        SCErrorString(SCError())); 
 998         ok 
= SCNetworkSetSetCurrent(set
); 
1000                 // if we could not make this the "current" set 
1001                 SC_log(LOG_NOTICE
, "could not establish new set as current: %s", 
1002                        SCErrorString(SCError())); 
1006         model 
= SCPreferencesGetValue(prefs
, MODEL
); 
1007         if (model 
== NULL
) { 
1008                 model 
= _SC_hw_model(FALSE
); 
1009                 SCPreferencesSetValue(prefs
, MODEL
, model
); 
1014         if (!ok 
&& (set 
!= NULL
)) { 
1015                 SCNetworkSetRemove(set
); 
1024 SCNetworkSetGetSetID(SCNetworkSetRef set
) 
1026         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1028         if (!isA_SCNetworkSet(set
)) { 
1029                 _SCErrorSet(kSCStatusInvalidArgument
); 
1033         return setPrivate
->setID
; 
1038 SCNetworkSetGetName(SCNetworkSetRef set
) 
1040         CFDictionaryRef         entity
; 
1042         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1044         if (!isA_SCNetworkSet(set
)) { 
1045                 _SCErrorSet(kSCStatusInvalidArgument
); 
1049         if (setPrivate
->name 
!= NULL
) { 
1050                 return setPrivate
->name
; 
1053         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1054         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1057         if (isA_CFDictionary(entity
)) { 
1060                 name 
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
); 
1061                 if (isA_CFString(name
)) { 
1062                         setPrivate
->name 
= CFRetain(name
); 
1066         if (setPrivate
->name 
!= NULL
) { 
1067                 CFStringRef     non_localized
; 
1069                 non_localized 
= copy_default_set_name(FALSE
); 
1070                 if (CFEqual(setPrivate
->name
, non_localized
)) { 
1071                         CFStringRef     localized
; 
1073                         // if "Automatic", return localized name 
1074                         localized 
= copy_default_set_name(TRUE
); 
1075                         CFRelease(setPrivate
->name
); 
1076                         setPrivate
->name 
= localized
; 
1079                 CFRelease(non_localized
); 
1082         return setPrivate
->name
; 
1086 CFArrayRef 
/* of serviceID CFStringRef's */ 
1087 SCNetworkSetGetServiceOrder(SCNetworkSetRef set
) 
1089         CFDictionaryRef         dict
; 
1091         CFArrayRef              serviceOrder
; 
1092         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1094         if (!isA_SCNetworkSet(set
)) { 
1095                 _SCErrorSet(kSCStatusInvalidArgument
); 
1099         path 
= SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL
, setPrivate
->setID
, kSCEntNetIPv4
); 
1104         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1106         if (!isA_CFDictionary(dict
)) { 
1110         serviceOrder 
= CFDictionaryGetValue(dict
, kSCPropNetServiceOrder
); 
1111         serviceOrder 
= isA_CFArray(serviceOrder
); 
1113         return serviceOrder
; 
1118 SCNetworkSetGetTypeID(void) 
1120         pthread_once(&initialized
, __SCNetworkSetInitialize
);   /* initialize runtime */ 
1121         return __kSCNetworkSetTypeID
; 
1125 #if     TARGET_OS_IPHONE 
1127 isDefaultSet(SCNetworkSetRef set
) 
1129         CFStringRef     defaultName
; 
1130         Boolean         isDefault       
= FALSE
; 
1131         CFStringRef     setName
; 
1133         defaultName 
= copy_default_set_name(TRUE
); 
1134         setName 
= SCNetworkSetGetName(set
); 
1135         isDefault 
= _SC_CFEqual(setName
, defaultName
); 
1136         CFRelease(defaultName
); 
1140 #endif  // TARGET_OS_IPHONE 
1144 SCNetworkSetRemove(SCNetworkSetRef set
) 
1146         CFStringRef             currentPath
; 
1149         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1151         if (!isA_SCNetworkSet(set
)) { 
1152                 _SCErrorSet(kSCStatusInvalidArgument
); 
1156         if (!__SCNetworkSetExists(set
)) { 
1157                 SC_log(LOG_ERR
, "SCNetworkSetRemove() w/removed set\n  set = %@", set
); 
1158                 _SC_crash_once("SCNetworkSetRemove() w/removed set", NULL
, NULL
); 
1159                 _SCErrorSet(kSCStatusInvalidArgument
); 
1162 #if     TARGET_OS_IPHONE 
1163         if (isDefaultSet(set
) && (geteuid() != 0)) { 
1164                 SC_log(LOG_ERR
, "SCNetworkSetRemove() failed, cannot remove set : %@", set
); 
1165                 _SC_crash("The \"Automatic\" network set cannot be removed", NULL
, NULL
); 
1166                 _SCErrorSet(kSCStatusInvalidArgument
); 
1169 #endif  // TARGET_OS_IPHONE 
1171         currentPath 
= SCPreferencesGetValue(setPrivate
->prefs
, kSCPrefCurrentSet
); 
1172         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1173         if (!isA_CFString(currentPath
) || !CFEqual(currentPath
, path
)) { 
1174                 ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
1176                 SC_log(LOG_DEBUG
, "SCNetworkSetRemove() failed, currently active: %@", setPrivate
->setID
); 
1177                 _SCErrorSet(kSCStatusInvalidArgument
); 
1182                 SC_log(LOG_DEBUG
, "SCNetworkSetRemove(): %@", set
); 
1190 SCNetworkSetRemoveService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
1192         SCNetworkInterfaceRef           interface
; 
1193         CFArrayRef                      interface_config        
= NULL
; 
1196         int                             sc_status               
= kSCStatusOK
; 
1197         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
1198         SCNetworkSetPrivateRef          setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
1200         if (!isA_SCNetworkSet(set
)) { 
1201                 _SCErrorSet(kSCStatusInvalidArgument
); 
1205         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1206                 _SCErrorSet(kSCStatusInvalidArgument
); 
1210         if (!__SCNetworkSetExists(set
)) { 
1211                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/removed set\n  set = %@\n  service = %@", 
1214                 _SC_crash_once("SCNetworkSetRemoveService() w/removed set", NULL
, NULL
); 
1215                 _SCErrorSet(kSCStatusInvalidArgument
); 
1218         if (!__SCNetworkServiceExists(service
)) { 
1219                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/removed service\n  set = %@\n  service = %@", 
1222                 _SC_crash_once("SCNetworkSetRemoveService() w/removed service", NULL
, NULL
); 
1223                 _SCErrorSet(kSCStatusInvalidArgument
); 
1227         // remove service from ServiceOrder 
1228         _serviceOrder_remove(set
, service
); 
1230         // get the [deep] interface configuration settings 
1231         interface 
= SCNetworkServiceGetInterface(service
); 
1232         if (interface 
!= NULL
) { 
1233                 interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(set
, interface
); 
1234                 if (interface_config 
!= NULL
) { 
1235                         // remove the interface configuration from all sets which contain this service. 
1236                         __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, NULL
); 
1240         // remove the link between "set" and the "service" 
1241         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, 
1243                                                                  servicePrivate
->serviceID
, 
1245         ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
1247                 sc_status 
= SCError();  // preserve the error 
1251         // push the [deep] interface configuration [back] into all sets which contain the service. 
1252         if (interface_config 
!= NULL
) { 
1253                 __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, interface_config
); 
1254                 CFRelease(interface_config
); 
1258                 SC_log(LOG_DEBUG
, "SCNetworkSetRemoveService(): %@, %@", set
, service
); 
1260                 _SCErrorSet(sc_status
); 
1268 SCNetworkSetSetCurrent(SCNetworkSetRef set
) 
1272         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1274         if (!isA_SCNetworkSet(set
)) { 
1275                 _SCErrorSet(kSCStatusInvalidArgument
); 
1279         if (!__SCNetworkSetExists(set
)) { 
1280                 SC_log(LOG_ERR
, "SCNetworkSetSetCurrent() w/removed set\n  set = %@", set
); 
1281                 _SC_crash_once("SCNetworkSetSetCurrent() w/removed set", NULL
, NULL
); 
1282                 _SCErrorSet(kSCStatusInvalidArgument
); 
1286         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1287         ok 
= SCPreferencesSetValue(setPrivate
->prefs
, kSCPrefCurrentSet
, path
); 
1291                 SC_log(LOG_DEBUG
, "SCNetworkSetSetCurrent(): %@", set
); 
1299 SCNetworkSetSetName(SCNetworkSetRef set
, CFStringRef name
) 
1301         CFDictionaryRef         entity
; 
1302 #if     TARGET_OS_IPHONE 
1303         Boolean                 isDefaultName   
= FALSE
; 
1304 #endif  // TARGET_OS_IPHONE 
1305         CFStringRef             localized       
= NULL
; 
1306         CFStringRef             non_localized   
= NULL
; 
1309         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1311         if (!isA_SCNetworkSet(set
)) { 
1312                 _SCErrorSet(kSCStatusInvalidArgument
); 
1316         if (!__SCNetworkSetExists(set
)) { 
1317                 SC_log(LOG_ERR
, "SCNetworkSetSetName() w/removed set\n  set = %@\n  name = %@", 
1319                        name 
!= NULL 
? name 
: CFSTR("<NULL>")); 
1320                 _SC_crash_once("SCNetworkSetSetName() w/removed set", NULL
, NULL
); 
1321                 _SCErrorSet(kSCStatusInvalidArgument
); 
1325         if ((name 
!= NULL
) && !isA_CFString(name
)) { 
1326                 _SCErrorSet(kSCStatusInvalidArgument
); 
1330         // if known, compare against localized name 
1333                 non_localized 
= copy_default_set_name(FALSE
); 
1334                 if (CFEqual(name
, non_localized
)) { 
1335                         localized 
= copy_default_set_name(TRUE
); 
1337 #if     TARGET_OS_IPHONE 
1338                         isDefaultName 
= TRUE
; 
1339 #endif  // TARGET_OS_IPHONE 
1341 #if     TARGET_OS_IPHONE 
1343                         localized 
= copy_default_set_name(TRUE
); 
1344                         isDefaultName 
= CFEqual(name
, non_localized
); 
1346 #endif  // TARGET_OS_IPHONE 
1349 #if     TARGET_OS_IPHONE 
1350         if (!isDefaultName 
&& isDefaultSet(set
) && (geteuid() != 0)) { 
1351                 // if we are trying to change the name of the "Automatic" set 
1352                 SC_log(LOG_ERR
, "SCNetworkSetSetName() failed, cannot rename : %@", set
); 
1353                 _SC_crash("The \"Automatic\" network set cannot be renamed", NULL
, NULL
); 
1354                 _SCErrorSet(kSCStatusInvalidArgument
); 
1357 #endif  // TARGET_OS_IPHONE 
1359 #define PREVENT_DUPLICATE_SET_NAMES 
1360 #ifdef  PREVENT_DUPLICATE_SET_NAMES 
1362 #if     TARGET_OS_IPHONE 
1363         if (!isDefaultName
) { 
1364                 // On iOS, only block naming multiple sets with the name 
1365                 // "Automatic".  Others names are OK. 
1367 #endif  // TARGET_OS_IPHONE 
1372                 // ensure that each set is uniquely named 
1374                 sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
1379                         n 
= CFArrayGetCount(sets
); 
1380                         for (i 
= 0; i 
< n
; i
++) { 
1381                                 CFStringRef     otherID
; 
1382                                 CFStringRef     otherName
; 
1383                                 SCNetworkSetRef set             
= CFArrayGetValueAtIndex(sets
, i
); 
1385                                 otherID 
= SCNetworkSetGetSetID(set
); 
1386                                 if (CFEqual(setPrivate
->setID
, otherID
)) { 
1387                                         continue;       // skip current set 
1390                                 otherName 
= SCNetworkSetGetName(set
); 
1391                                 if ((otherName 
!= NULL
) && CFEqual(name
, otherName
)) { 
1392                                         // if "name" not unique 
1394                                         _SCErrorSet(kSCStatusKeyExists
); 
1401 #endif  /* PREVENT_DUPLICATE_SET_NAMES */ 
1403         // if known, store non-localized name 
1405         if ((name 
!= NULL
) && (non_localized 
!= NULL
)) { 
1406                 if (localized 
== NULL
) { 
1407                         localized 
= copy_default_set_name(TRUE
); 
1409                 if (CFEqual(name
, localized
)) { 
1410                         name 
= non_localized
; 
1414         // update the "name" 
1416         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1417         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1418         if (isA_CFDictionary(entity
) || 
1419             ((entity 
== NULL
) && (name 
!= NULL
))) { 
1420                 CFMutableDictionaryRef  newEntity
; 
1422                 if (entity 
!= NULL
) { 
1423                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1425                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1427                                                               &kCFTypeDictionaryKeyCallBacks
, 
1428                                                               &kCFTypeDictionaryValueCallBacks
); 
1431                         CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, name
); 
1433                         CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
); 
1435                 ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, path
, newEntity
); 
1436                 CFRelease(newEntity
); 
1443                 SC_log(LOG_DEBUG
, "SCNetworkSetSetName(): %@", set
); 
1446         if (localized 
!= NULL
)          CFRelease(localized
); 
1447         if (non_localized 
!= NULL
)      CFRelease(non_localized
); 
1453 SCNetworkSetSetServiceOrder(SCNetworkSetRef set
, CFArrayRef newOrder
) 
1455         CFMutableArrayRef       cleanOrder
; 
1456         CFDictionaryRef         dict
; 
1459         CFMutableDictionaryRef  newDict
; 
1462         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1464         if (!isA_SCNetworkSet(set
)) { 
1465                 _SCErrorSet(kSCStatusInvalidArgument
); 
1469         if (!__SCNetworkSetExists(set
)) { 
1470                 SC_log(LOG_ERR
, "SCNetworkSetSetServiceOrder() w/removed set\n  set = %@", set
); 
1471                 _SC_crash_once("SCNetworkSetSetServiceOrder() w/removed set", NULL
, NULL
); 
1472                 _SCErrorSet(kSCStatusInvalidArgument
); 
1476         if (isA_CFArray(newOrder
)) { 
1477                 n 
= CFArrayGetCount(newOrder
); 
1478                 for (i 
= 0; i 
< n
; i
++) { 
1479                         CFStringRef     serviceID
; 
1481                         serviceID 
= CFArrayGetValueAtIndex(newOrder
, i
); 
1482                         if (!isA_CFString(serviceID
)) { 
1483                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1488                 _SCErrorSet(kSCStatusInvalidArgument
); 
1492         path 
= SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL
, setPrivate
->setID
, kSCEntNetIPv4
); 
1497         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1499                 newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
); 
1501                 newDict 
= CFDictionaryCreateMutable(NULL
, 
1503                                                     &kCFTypeDictionaryKeyCallBacks
, 
1504                                                     &kCFTypeDictionaryValueCallBacks
); 
1507         cleanOrder 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1508         n 
= CFArrayGetCount(newOrder
); 
1509         for (i 
= 0; i 
< n
; i
++) { 
1510                 CFIndex         nClean          
= CFArrayGetCount(cleanOrder
); 
1511                 CFStringRef     serviceID       
= CFArrayGetValueAtIndex(newOrder
, i
); 
1513                 if ((nClean 
== 0) || 
1514                     !CFArrayContainsValue(cleanOrder
, CFRangeMake(0, nClean
), serviceID
)) { 
1515                         // if first reference to this serviceID 
1516                         CFArrayAppendValue(cleanOrder
, serviceID
); 
1518                         // skip duplicate serviceID 
1519                         SC_log(LOG_ERR
, "SCNetworkSetSetServiceOrder() found duplicate serviceID: removed %@\n", serviceID
); 
1522         CFDictionarySetValue(newDict
, kSCPropNetServiceOrder
, cleanOrder
); 
1523         CFRelease(cleanOrder
); 
1525         ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, path
, newDict
); 
1534 #pragma mark SCNetworkSet SPIs 
1539 __SCNetworkSetExists(SCNetworkSetRef set
) 
1541         CFDictionaryRef                 entity
; 
1543         SCNetworkSetPrivateRef          setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1545         if (setPrivate
->prefs 
== NULL
) { 
1549         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1550         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1553         if (!isA_CFDictionary(entity
)) { 
1563 add_supported_interfaces(CFMutableArrayRef interface_list
, SCNetworkInterfaceRef interface
) 
1566         CFArrayRef      interface_types
; 
1569         interface_types 
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
); 
1570         n 
= (interface_types 
!= NULL
) ? CFArrayGetCount(interface_types
) : 0; 
1571         for (i 
= 0; i 
< n
; i
++) { 
1572                 SCNetworkInterfaceRef   parent
; 
1573                 CFStringRef             interface_type
; 
1575                 interface_type 
= CFArrayGetValueAtIndex(interface_types
, i
); 
1576                 parent 
= SCNetworkInterfaceCreateWithInterface(interface
, interface_type
); 
1577                 if (parent 
!= NULL
) { 
1578                         CFArrayAppendValue(interface_list
, parent
); 
1587 static CFSetRef 
/* of SCNetworkInterfaceRef's */ 
1588 copyExcludedInterfaces(SCPreferencesRef prefs
) 
1590         CFMutableSetRef excluded
; 
1591         CFArrayRef      interfaces
; 
1593         excluded 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
1595 #if     !TARGET_OS_IPHONE 
1596         // exclude Bond [member] interfaces 
1597         interfaces 
= SCBondInterfaceCopyAll(prefs
); 
1598         if (interfaces 
!= NULL
) { 
1599                 __SCBondInterfaceListCollectMembers(interfaces
, excluded
); 
1600                 CFRelease(interfaces
); 
1602 #endif  // !TARGET_OS_IPHONE 
1604         // exclude Bridge [member] interfaces 
1605         interfaces 
= SCBridgeInterfaceCopyAll(prefs
); 
1606         if (interfaces 
!= NULL
) { 
1607                 __SCBridgeInterfaceListCollectMembers(interfaces
, excluded
); 
1608                 CFRelease(interfaces
); 
1615 #if     !TARGET_OS_IPHONE 
1616 static SCBridgeInterfaceRef
 
1617 copyAutoBridgeInterface(SCPreferencesRef prefs
, CFStringRef bridgeName
) 
1619         SCBridgeInterfaceRef    bridge          
= NULL
; 
1620         CFArrayRef              interfaces
; 
1622         // exclude Bridge [member] interfaces 
1623         interfaces 
= SCBridgeInterfaceCopyAll(prefs
); 
1624         if (interfaces 
!= NULL
) { 
1628                 n 
= CFArrayGetCount(interfaces
); 
1629                 for (i 
= 0; i 
< n
; i
++) { 
1630                         SCBridgeInterfaceRef    interface
; 
1631                         CFStringRef             name    
= NULL
; 
1632                         CFDictionaryRef         options
; 
1634                         interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1635                         options 
= SCBridgeInterfaceGetOptions(interface
); 
1636                         if ((options 
!= NULL
) && 
1637                             CFDictionaryGetValueIfPresent(options
, 
1639                                                           (const void **)&name
) && 
1640                             _SC_CFEqual(name
, bridgeName
)) { 
1647                 CFRelease(interfaces
); 
1650         if (bridge 
== NULL
) { 
1651                 bridge 
= SCBridgeInterfaceCreate(prefs
); 
1652                 if (bridge 
!= NULL
) { 
1653                         CFMutableDictionaryRef  newOptions
; 
1656                         newOptions 
= CFDictionaryCreateMutable(NULL
, 0, 
1657                                                                &kCFTypeDictionaryKeyCallBacks
, 
1658                                                                &kCFTypeDictionaryValueCallBacks
); 
1659                         CFDictionarySetValue(newOptions
, CFSTR("__AUTO__"), bridgeName
); 
1660                         ok 
= SCBridgeInterfaceSetOptions(bridge
, newOptions
); 
1661                         CFRelease(newOptions
); 
1671 #endif  // !TARGET_OS_IPHONE 
1675 copyServices(SCNetworkSetRef set
) 
1677         CFArrayRef              services
; 
1678         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1680         // first, assume that we only want to add new services 
1681         // for those interfaces that are not represented in the 
1683         services 
= SCNetworkSetCopyServices(set
); 
1684         if ((services 
!= NULL
) && setPrivate
->established
) { 
1685                 // but, if we are given an existing (or "established") set 
1686                 // than we only want to add new services for those interfaces 
1687                 // that are not represented in *any* set. 
1688                 CFRelease(services
); 
1689                 services 
= SCNetworkServiceCopyAll(setPrivate
->prefs
); 
1696 #if     !TARGET_OS_IPHONE 
1697 static CF_RETURNS_RETAINED CFArrayRef
 
1698 updateServices(CFArrayRef services
, SCNetworkInterfaceRef interface
) 
1700         CFStringRef             bsdName
; 
1703         CFMutableArrayRef       newServices
; 
1705         if (services 
== NULL
) { 
1709         bsdName 
= SCNetworkInterfaceGetBSDName(interface
); 
1711         newServices 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1713         n 
= CFArrayGetCount(services
); 
1714         for (i 
= 0; i 
< n
; i
++) { 
1715                 SCNetworkInterfaceRef           interface
; 
1716                 CFStringRef                     interfaceName
; 
1717                 SCNetworkServiceRef             newService
; 
1718                 SCNetworkServiceRef             service
; 
1719                 CFStringRef                     serviceID
; 
1720                 SCNetworkServicePrivateRef      servicePrivate
; 
1722                 service 
= CFArrayGetValueAtIndex(services
, i
); 
1723                 interface 
= SCNetworkServiceGetInterface(service
); 
1724                 interfaceName 
= SCNetworkInterfaceGetBSDName(interface
); 
1725                 if (!_SC_CFEqual(interfaceName
, bsdName
)) { 
1726                         // if not a match, retain 
1727                         CFArrayAppendValue(newServices
, service
); 
1731                 // if a match, update 
1732                 serviceID 
= SCNetworkServiceGetServiceID(service
); 
1733                 servicePrivate 
= (SCNetworkServicePrivateRef
)service
; 
1734                 newService 
= SCNetworkServiceCopy(servicePrivate
->prefs
, serviceID
); 
1735                 if (newService 
!= NULL
) { 
1736                         CFArrayAppendValue(newServices
, newService
); 
1737                         CFRelease(newService
); 
1743 #endif  // !TARGET_OS_IPHONE 
1746 static __inline__ Boolean
 
1747 skipInterface(SCNetworkInterfaceRef interface
) 
1751         action 
= _SCNetworkInterfaceGetConfigurationAction(interface
); 
1752         if (isA_CFString(action
) && 
1753             CFEqual(action
, kSCNetworkInterfaceConfigurationActionValueNone
)) { 
1762 _SCNetworkSetCompare(const void *val1
, const void *val2
, void *context
) 
1764 #pragma unused(context) 
1769         SCNetworkSetRef s1      
= (SCNetworkSetRef
)val1
; 
1770         SCNetworkSetRef s2      
= (SCNetworkSetRef
)val2
; 
1772         name1 
= SCNetworkSetGetName(s1
); 
1773         name2 
= SCNetworkSetGetName(s2
); 
1775         if (name1 
!= NULL
) { 
1776                 if (name2 
!= NULL
) { 
1777                         return CFStringCompare(name1
, name2
, 0); 
1779                         return kCFCompareLessThan
; 
1783         if (name2 
!= NULL
) { 
1784                 return kCFCompareGreaterThan
; 
1787         id1 
= SCNetworkSetGetSetID(s1
); 
1788         id2 
= SCNetworkSetGetSetID(s2
); 
1789         return CFStringCompare(id1
, id2
, 0); 
1794 __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set
, CFArrayRef interfaces
, Boolean excludeHidden
) 
1800         CFArrayRef              services
; 
1801         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1802         Boolean                 updated         
= FALSE
; 
1803 #if     !TARGET_OS_IPHONE 
1804         Boolean                 updatedIFs      
= FALSE
; 
1805 #endif  // !TARGET_OS_IPHONE 
1807 #if     TARGET_OS_IPHONE 
1808         CFArrayRef              orphans         
= NULL
; 
1811         sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
1813                 if (CFArrayGetCount(sets
) == 1) { 
1814                         services 
= SCNetworkSetCopyServices(set
); 
1815                         if (services 
!= NULL
) { 
1816                                 n 
= CFArrayGetCount(services
); 
1817                                 CFRelease(services
); 
1820                         if ((n 
== 0) && CFEqual(set
, CFArrayGetValueAtIndex(sets
, 0))) { 
1821                                 // after a "Reset Network Settings" we need to find (and 
1822                                 // add back) any VPN services that were orphaned. 
1823                                 orphans 
= SCNetworkServiceCopyAll(setPrivate
->prefs
); 
1829 #endif  // TARGET_OS_IPHONE 
1831         // copy network services 
1832         services 
= copyServices(set
); 
1834         // copy network interfaces to be excluded 
1835         excluded 
= copyExcludedInterfaces(setPrivate
->prefs
); 
1837 #if     !TARGET_OS_IPHONE 
1838         // look for interfaces that should auto-magically be added 
1839         // to an Ethernet bridge 
1840         n 
= ((services 
!= NULL
) && (interfaces 
!= NULL
)) ? CFArrayGetCount(interfaces
) : 0; 
1841         for (i 
= 0; i 
< n
; i
++) { 
1842                 SCBridgeInterfaceRef    bridge          
= NULL
; 
1843                 SCNetworkInterfaceRef   interface
; 
1845                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1847                 if (excludeHidden 
&& skipInterface(interface
)) { 
1848                         // if not auto-configure 
1852                 if (CFSetContainsValue(excluded
, interface
)) { 
1853                         // if this interface is a member of a Bond or Bridge 
1857                 if (__SCNetworkServiceExistsForInterface(services
, interface
)) { 
1858                         // if this is not a new interface 
1862                 if (_SCNetworkInterfaceIsBuiltin(interface
) && 
1863                     _SCNetworkInterfaceIsThunderbolt(interface
) && 
1864                     !isA_SCBridgeInterface(interface
)) { 
1865                         // add built-in Thunderbolt interfaces to bridge 
1866                         bridge 
= copyAutoBridgeInterface(setPrivate
->prefs
, CFSTR("thunderbolt-bridge")); 
1869                 if (bridge 
!= NULL
) { 
1870                         CFIndex                 bridgeIndex
; 
1872                         CFMutableArrayRef       newMembers
; 
1873                         CFMutableSetRef         newExcluded
; 
1874                         CFMutableArrayRef       newInterfaces
; 
1875                         CFArrayRef              newServices
; 
1877                         // track the bridge interface (if it's in our list) 
1878                         bridgeIndex 
= CFArrayGetFirstIndexOfValue(interfaces
, 
1879                                                                   CFRangeMake(0, CFArrayGetCount(interfaces
)), 
1882                         // add new member interface 
1883                         members 
= SCBridgeInterfaceGetMemberInterfaces(bridge
); 
1884                         if ((members 
!= NULL
) && (CFArrayGetCount(members
) > 0)) { 
1885                                 newMembers 
= CFArrayCreateMutableCopy(NULL
, 0, members
); 
1886                                 updated 
= TRUE
;         // if we're updating an existing bridge 
1888                                 newMembers 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1890                         CFArrayAppendValue(newMembers
, interface
); 
1891                         ok 
= SCBridgeInterfaceSetMemberInterfaces(bridge
, newMembers
); 
1892                         CFRelease(newMembers
); 
1894                                 SC_log(LOG_INFO
, "could not update bridge with \"%@\": %s", 
1895                                        SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1896                                        SCErrorString(SCError())); 
1901                         // exclude the new member interface 
1902                         newExcluded 
= CFSetCreateMutableCopy(NULL
, 0, excluded
); 
1903                         CFRelease(excluded
); 
1904                         CFSetAddValue(newExcluded
, interface
); 
1905                         excluded 
= newExcluded
; 
1907                         // update the list of interfaces to include the [new or updated] bridge 
1908                         newInterfaces 
= CFArrayCreateMutableCopy(NULL
, 0, interfaces
); 
1909                         if (bridgeIndex 
!= kCFNotFound
) { 
1910                                 CFArraySetValueAtIndex(newInterfaces
, bridgeIndex
, bridge
); 
1912                                 CFArrayAppendValue(newInterfaces
, bridge
); 
1915                                 CFRelease(interfaces
); 
1917                         interfaces 
= newInterfaces
; 
1920                         // refresh [existing] services 
1921                         newServices 
= updateServices(services
, bridge
); 
1922                         if (newServices 
!= NULL
) { 
1923                                 CFRelease(services
); 
1924                                 services 
= newServices
; 
1930 #endif  // !TARGET_OS_IPHONE 
1932         n 
= ((services 
!= NULL
) && (interfaces 
!= NULL
)) ? CFArrayGetCount(interfaces
) : 0; 
1933         for (i 
= 0; i 
< n
; i
++) { 
1934                 SCNetworkInterfaceRef   interface
; 
1935                 CFMutableArrayRef       interface_list
; 
1937                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1939                 if (excludeHidden 
&& skipInterface(interface
)) { 
1940                         // if not auto-configure 
1944                 if (CFSetContainsValue(excluded
, interface
)) { 
1945                         // if this interface is a member of a Bond or Bridge 
1949                 if (__SCNetworkServiceExistsForInterface(services
, interface
)) { 
1950                         // if this is not a new interface 
1954                 interface_list 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1955                 CFArrayAppendValue(interface_list
, interface
); 
1957                 while (ok 
&& (CFArrayGetCount(interface_list
) > 0)) { 
1958                         CFArrayRef              protocol_types
; 
1960                         interface 
= CFArrayGetValueAtIndex(interface_list
, 0); 
1962                         protocol_types 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
1963                         if ((protocol_types 
!= NULL
) && (CFArrayGetCount(protocol_types
) > 0)) { 
1964                                 SCNetworkServiceRef     service
; 
1966                                 service 
= SCNetworkServiceCreate(setPrivate
->prefs
, interface
); 
1967                                 if (service 
== NULL
) { 
1968                                         SC_log(LOG_ERR
, "could not create service for \"%@\": %s", 
1969                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1970                                                SCErrorString(SCError())); 
1975                                 ok 
= SCNetworkServiceEstablishDefaultConfiguration(service
); 
1977                                         SC_log(LOG_ERR
, "could not estabish default configuration for \"%@\": %s", 
1978                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1979                                                SCErrorString(SCError())); 
1980                                         SCNetworkServiceRemove(service
); 
1985                                 ok 
= SCNetworkSetAddService(set
, service
); 
1987                                         SC_log(LOG_ERR
, "could not add service for \"%@\": %s", 
1988                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1989                                                SCErrorString(SCError())); 
1990                                         SCNetworkServiceRemove(service
); 
1998                                 add_supported_interfaces(interface_list
, interface
); 
2003                         CFArrayRemoveValueAtIndex(interface_list
, 0); 
2005                 CFRelease(interface_list
); 
2007 #if     !TARGET_OS_IPHONE 
2008         if (updatedIFs 
&& (interfaces 
!= NULL
)) { 
2009                 CFRelease(interfaces
); 
2011 #endif  // !TARGET_OS_IPHONE 
2012         if (services 
!= NULL
)   CFRelease(services
); 
2013         CFRelease(excluded
); 
2015 #if     TARGET_OS_IPHONE 
2016         if (orphans 
!= NULL
) { 
2017                 if (ok 
&& updated
) { 
2019                         CFIndex n       
= CFArrayGetCount(orphans
); 
2021                         for (i 
= 0; i 
< n
; i
++) { 
2022                                 SCNetworkServiceRef     service
; 
2024                                 service 
= CFArrayGetValueAtIndex(orphans
, i
); 
2025                                 if (_SCNetworkServiceIsVPN(service
)) { 
2026                                         ok 
= SCNetworkSetAddService(set
, service
); 
2036 #endif  // TARGET_OS_IPHONE 
2042                         model 
= SCPreferencesGetValue(setPrivate
->prefs
, MODEL
); 
2043                         if (model 
== NULL
) { 
2044                                 model 
= _SC_hw_model(FALSE
); 
2045                                 SCPreferencesSetValue(setPrivate
->prefs
, MODEL
, model
); 
2048                         // if no changes were made 
2049                         _SCErrorSet(kSCStatusOK
); 
2058 SCNetworkSetEstablishDefaultConfiguration(SCNetworkSetRef set
) 
2060         CFArrayRef              interfaces
; 
2061         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
2062         Boolean                 updated         
= FALSE
; 
2064         if (!isA_SCNetworkSet(set
)) { 
2065                 _SCErrorSet(kSCStatusInvalidArgument
); 
2069         interfaces 
= _SCNetworkInterfaceCopyAllWithPreferences(setPrivate
->prefs
); 
2070         if (interfaces 
!= NULL
) { 
2071                 updated 
= __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set
, interfaces
, TRUE
); 
2072                 CFRelease(interfaces
); 
2080 SCNetworkSetEstablishDefaultInterfaceConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
) 
2082         CFArrayRef      interfaces
; 
2085         if (!isA_SCNetworkSet(set
)) { 
2086                 _SCErrorSet(kSCStatusInvalidArgument
); 
2090         if (!isA_SCNetworkInterface(interface
)) { 
2091                 _SCErrorSet(kSCStatusInvalidArgument
); 
2095         interfaces 
= CFArrayCreate(NULL
, (const void **)&interface
, 1, &kCFTypeArrayCallBacks
); 
2096         assert(interfaces 
!= NULL
); 
2097         updated 
= __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set
, interfaces
, FALSE
); 
2098         CFRelease(interfaces
); 
2105 SCNetworkSetCopySelectedVPNService(SCNetworkSetRef set
) 
2109         SCNetworkServiceRef     selected        
= NULL
; 
2110         CFArrayRef              services
; 
2111         CFMutableArrayRef       services_vpn    
= NULL
; 
2113         if (!isA_SCNetworkSet(set
)) { 
2114                 _SCErrorSet(kSCStatusInvalidArgument
); 
2118         services 
= SCNetworkSetCopyServices(set
); 
2119         if (services 
!= NULL
) { 
2120                 n 
= CFArrayGetCount(services
); 
2121                 for (i 
= 0; i 
< n
; i
++) { 
2122                         SCNetworkServiceRef     service
; 
2124                         service 
= CFArrayGetValueAtIndex(services
, i
); 
2125                         if (!SCNetworkServiceGetEnabled(service
)) { 
2130                         if (!_SCNetworkServiceIsVPN(service
)) { 
2131                                 // if not VPN service 
2135                         if (services_vpn 
== NULL
) { 
2136                                 services_vpn 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
2138                         CFArrayAppendValue(services_vpn
, service
); 
2141                 CFRelease(services
); 
2144         if (services_vpn 
== NULL
) { 
2145                 // if no VPN services 
2149         n 
= CFArrayGetCount(services_vpn
); 
2152                 CFMutableArrayRef       sorted
; 
2154                 order 
= SCNetworkSetGetServiceOrder(set
); 
2155                 sorted 
= CFArrayCreateMutableCopy(NULL
, 0, services_vpn
); 
2156                 CFArraySortValues(sorted
, 
2157                                   CFRangeMake(0, CFArrayGetCount(sorted
)), 
2158                                   _SCNetworkServiceCompare
, 
2160                 CFRelease(services_vpn
); 
2161                 services_vpn 
= sorted
; 
2164 #if     TARGET_OS_IPHONE 
2166                 CFStringRef     serviceID_prefs
; 
2168 #define VPN_PREFERENCES CFSTR("com.apple.mobilevpn") 
2169 #define VPN_SERVICE_ID  CFSTR("activeVPNID") 
2171                 CFPreferencesAppSynchronize(VPN_PREFERENCES
); 
2172                 serviceID_prefs 
= CFPreferencesCopyAppValue(VPN_SERVICE_ID
, VPN_PREFERENCES
); 
2173                 if (serviceID_prefs 
!= NULL
) { 
2174                         for (i 
= 0; i 
< n
; i
++) { 
2175                                 SCNetworkServiceRef     service
; 
2176                                 CFStringRef             serviceID
; 
2178                                 service 
= CFArrayGetValueAtIndex(services_vpn
, i
); 
2179                                 serviceID 
= SCNetworkServiceGetServiceID(service
); 
2180                                 if (CFEqual(serviceID
, serviceID_prefs
)) { 
2188                         CFRelease(serviceID_prefs
); 
2191 #endif  // TARGET_OS_IPHONE 
2193         if (selected 
== NULL
) { 
2194                 selected 
= CFArrayGetValueAtIndex(services_vpn
, 0); 
2198         CFRelease(services_vpn
); 
2204 SCNetworkSetSetSelectedVPNService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
2207         CFArrayRef      services
; 
2209         if (!isA_SCNetworkSet(set
)) { 
2210                 _SCErrorSet(kSCStatusInvalidArgument
); 
2214         if (!isA_SCNetworkService(service
) || !_SCNetworkServiceIsVPN(service
)) { 
2215                 _SCErrorSet(kSCStatusInvalidArgument
); 
2219         services 
= SCNetworkSetCopyServices(set
); 
2220         if (services 
!= NULL
) { 
2222                 CFIndex n       
= CFArrayGetCount(services
); 
2224                 if (!CFArrayContainsValue(services
, CFRangeMake(0, n
), service
)) { 
2225                         // if selected service not a member of the current set 
2226                         _SCErrorSet(kSCStatusInvalidArgument
); 
2231                 for (i 
= 0; ok 
&& (i 
< n
); i
++) { 
2232                         SCNetworkServiceRef     vpn
; 
2234                         vpn 
= CFArrayGetValueAtIndex(services
, i
); 
2235                         if (!_SCNetworkServiceIsVPN(vpn
)) { 
2236                                 // if not VPN service 
2240                         ok 
= SCNetworkServiceSetEnabled(vpn
, CFEqual(service
, vpn
)); 
2246         if (services 
!= NULL
) CFRelease(services
); 
2252 _SCNetworkSetSetSetID(SCNetworkSetRef set
, CFStringRef newSetID
) 
2254         SCNetworkSetRef         currentSet              
= NULL
; 
2255         SCNetworkSetPrivateRef  currentSetPrivate       
= NULL
; 
2256         CFDictionaryRef         entity
; 
2257         CFStringRef             newPath
; 
2259         CFStringRef             oldPath                 
= NULL
; 
2260         SCNetworkSetPrivateRef  setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
2261         Boolean                 updateCurrentSet        
= FALSE
; 
2263         if (!isA_SCNetworkSet(set
)) { 
2264                 _SCErrorSet(kSCStatusInvalidArgument
); 
2268         if (!isA_CFString(newSetID
)) { 
2269                 _SCErrorSet(kSCStatusInvalidArgument
); 
2273         if (!__SCNetworkSetExists(set
)) { 
2274                 SC_log(LOG_ERR
, "_SCNetworkSetSetSetID() w/removed set\n  set = %@\n  setID = %@", 
2277                 _SC_crash_once("_SCNetworkSetSetSetID() w/removed set", NULL
, NULL
); 
2278                 _SCErrorSet(kSCStatusInvalidArgument
); 
2282         // If newSetID is equal to current setID, our work is done 
2283         if (CFEqual(newSetID
, setPrivate
->setID
)) { 
2287         newPath 
= SCPreferencesPathKeyCreateSet(NULL
, newSetID
); 
2288         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, newPath
); 
2289         if (isA_CFDictionary(entity
)) { 
2290                 // if the new set already exists 
2291                 _SCErrorSet(kSCStatusKeyExists
); 
2295         oldPath 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
2296         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, oldPath
); 
2297         if (!isA_CFDictionary(entity
)) { 
2298                 // if the set has already been removed 
2299                 _SCErrorSet(kSCStatusNoKey
); 
2303         ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, newPath
, entity
); 
2308         ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, oldPath
); 
2313         // update current set (if needed) 
2314         currentSet 
= SCNetworkSetCopyCurrent(setPrivate
->prefs
); 
2315         if (currentSet 
!= NULL
) { 
2316                 currentSetPrivate 
= (SCNetworkSetPrivateRef
)currentSet
; 
2317                 if (CFEqual(currentSetPrivate
->setID
, setPrivate
->setID
)) { 
2318                         updateCurrentSet 
= TRUE
; 
2320                 CFRelease(currentSet
); 
2323         SC_log(LOG_DEBUG
, "_SCNetworkSetSetID(): %@ --> %@", set
, newSetID
); 
2325         // replace setID with new one 
2327         CFRelease(setPrivate
->setID
); 
2328         setPrivate
->setID 
= newSetID
; 
2330         if (updateCurrentSet
) { 
2331                 SCNetworkSetSetCurrent(set
); 
2336         if (oldPath 
!= NULL
) { 
2339         if (newPath 
!= NULL
) {