2  * Copyright (c) 2004-2020 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 (setPrivate
->established
) { 
  80                 CFStringAppendFormat(result
, NULL
, CFSTR(", new")); 
  82         if (!__SCNetworkSetExists(set
)) { 
  83                 CFStringAppendFormat(result
, NULL
, CFSTR(", REMOVED")); 
  85         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  92 __SCNetworkSetDeallocate(CFTypeRef cf
) 
  94         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)cf
; 
  96         /* release resources */ 
  98         CFRelease(setPrivate
->setID
); 
  99         CFRelease(setPrivate
->prefs
); 
 100         if (setPrivate
->name 
!= NULL
) 
 101                 CFRelease(setPrivate
->name
); 
 108 __SCNetworkSetEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 110         SCNetworkSetPrivateRef  s1      
= (SCNetworkSetPrivateRef
)cf1
; 
 111         SCNetworkSetPrivateRef  s2      
= (SCNetworkSetPrivateRef
)cf2
; 
 116         if (s1
->prefs 
!= s2
->prefs
) 
 117                 return FALSE
;   // if not the same prefs 
 119         if (!CFEqual(s1
->setID
, s2
->setID
)) 
 120                 return FALSE
;   // if not the same set identifier 
 127 __SCNetworkSetHash(CFTypeRef cf
) 
 129         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)cf
; 
 131         return CFHash(setPrivate
->setID
); 
 136 __SCNetworkSetInitialize(void) 
 138         __kSCNetworkSetTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkSetClass
); 
 143 static SCNetworkSetPrivateRef
 
 144 __SCNetworkSetCreatePrivate(CFAllocatorRef      allocator
, 
 145                             SCPreferencesRef    prefs
, 
 148         SCNetworkSetPrivateRef  setPrivate
; 
 151         /* initialize runtime */ 
 152         pthread_once(&initialized
, __SCNetworkSetInitialize
); 
 154         /* allocate target */ 
 155         size            
= sizeof(SCNetworkSetPrivate
) - sizeof(CFRuntimeBase
); 
 156         setPrivate 
= (SCNetworkSetPrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 157                                                                       __kSCNetworkSetTypeID
, 
 160         if (setPrivate 
== NULL
) { 
 164         /* initialize non-zero/NULL members */ 
 165         setPrivate
->setID       
= CFStringCreateCopy(NULL
, setID
); 
 166         setPrivate
->prefs       
= CFRetain(prefs
); 
 176 _serviceOrder(SCNetworkServiceRef service
) 
 178         SCNetworkInterfaceRef   interface
; 
 180         interface 
= SCNetworkServiceGetInterface(service
); 
 181         if ((interface 
== NULL
) || _SCNetworkServiceIsVPN(service
)) { 
 182                 return 100000;  // if unknown or VPN interface, sort last 
 185         return __SCNetworkInterfaceOrder(interface
); 
 190 _serviceOrder_clear(CFMutableArrayRef order
, CFStringRef serviceID
) 
 192         CFIndex f
;      // # of serviceID's found 
 198         n 
= CFArrayGetCount(order
); 
 200                 CFStringRef     thisServiceID   
= CFArrayGetValueAtIndex(order
, i
); 
 202                 if (CFEqual(thisServiceID
, serviceID
)) { 
 203                         // remove the serviceID 
 204                         CFArrayRemoveValueAtIndex(order
, i
); 
 210                 i
++;    // move to the next serviceID 
 218 _serviceOrder_add(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 221         CFMutableArrayRef       newOrder
; 
 224         CFStringRef             serviceID       
= SCNetworkServiceGetServiceID(service
); 
 225         CFIndex                 serviceOrder    
= _serviceOrder(service
); 
 226         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
 228         order 
= SCNetworkSetGetServiceOrder(set
); 
 230                 newOrder 
= CFArrayCreateMutableCopy(NULL
, 0, order
); 
 232                 newOrder 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 234         assert(newOrder 
!= NULL
); 
 236         n 
= _serviceOrder_clear(newOrder
, serviceID
); 
 238                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/service already in ServiceOrder\n  service = %@\n  matched = %ld", 
 241                 _SC_crash_once("SCNetworkSetAddService() w/service already in ServiceOrder", NULL
, NULL
); 
 245         n 
= CFArrayGetCount(newOrder
); 
 246         for (CFIndex i 
= 0; i 
< n
; i
++) { 
 248                 SCNetworkServiceRef     slotService
; 
 249                 CFStringRef             slotServiceID
; 
 251                 slotServiceID 
= CFArrayGetValueAtIndex(newOrder
, i
); 
 252                 if (!isA_CFString(slotServiceID
)) { 
 257                 slotService 
= SCNetworkServiceCopy(setPrivate
->prefs
, slotServiceID
); 
 258                 if (slotService 
== NULL
) { 
 259                         // if serviceID not valid 
 263                 slotOrder 
= _serviceOrder(slotService
); 
 264                 if (serviceOrder 
>= slotOrder
) { 
 265                         // add the service *after* this one 
 269                 CFRelease(slotService
); 
 272         CFArrayInsertValueAtIndex(newOrder
, newSlot
, serviceID
); 
 273         (void) SCNetworkSetSetServiceOrder(set
, newOrder
); 
 281 _serviceOrder_remove(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 284         CFMutableArrayRef       newOrder
; 
 286         CFStringRef             serviceID
; 
 288         order 
= SCNetworkSetGetServiceOrder(set
); 
 292         newOrder 
= CFArrayCreateMutableCopy(NULL
, 0, order
); 
 294         serviceID 
= SCNetworkServiceGetServiceID(service
); 
 296         n 
= _serviceOrder_clear(newOrder
, serviceID
); 
 298                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/multiple instances of service in ServiceOrder\n  service = %@\n  count = %ld", 
 303         (void) SCNetworkSetSetServiceOrder(set
, newOrder
); 
 311 #pragma mark SCNetworkSet APIs 
 314 #define DEFAULT_SET_NAME        CFSTR("Automatic") 
 319 copy_default_set_name(Boolean loc
) 
 322         static CFStringRef      non_localized   
= NULL
; 
 323         static CFStringRef      localized       
= NULL
; 
 326                 static dispatch_once_t  once
; 
 328                 dispatch_once(&once
, ^{ 
 331                         bundle 
= _SC_CFBundleGet(); 
 332                         if (bundle 
!= NULL
) { 
 333                                 non_localized 
= _SC_CFBundleCopyNonLocalizedString(bundle
, 
 334                                                                                    CFSTR("DEFAULT_SET_NAME"), 
 339                 name 
= non_localized
; 
 341                 static dispatch_once_t  once
; 
 343                 dispatch_once(&once
, ^{ 
 346                         bundle 
= _SC_CFBundleGet(); 
 347                         if (bundle 
!= NULL
) { 
 348                                 localized 
= CFBundleCopyLocalizedString(bundle
, 
 349                                                                         CFSTR("DEFAULT_SET_NAME"), 
 358                 // if bundle or localized names not available 
 359                 name 
= DEFAULT_SET_NAME
; 
 367 #define PREVENT_DUPLICATE_SERVICE_NAMES 
 368 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
 370 copy_next_name(CFStringRef name
) 
 372         CFArrayRef              components
; 
 374         CFMutableArrayRef       newComponents
; 
 381         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, name
, CFSTR(" ")); 
 382         if (components 
!= NULL
) { 
 383                 newComponents 
= CFArrayCreateMutableCopy(NULL
, 0, components
); 
 384                 CFRelease(components
); 
 386                 newComponents 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 387                 CFArrayAppendValue(newComponents
, name
); 
 390         n 
= CFArrayGetCount(newComponents
); 
 394                 str 
= CFArrayGetValueAtIndex(newComponents
, n 
- 1); 
 395                 suffix 
= CFStringGetIntValue(str
); 
 397                         CFArrayRemoveValueAtIndex(newComponents
, n 
- 1); 
 403         name 
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), (int)suffix
); 
 404         CFArrayAppendValue(newComponents
, name
); 
 407         name 
= CFStringCreateByCombiningStrings(NULL
, newComponents
, CFSTR(" ")); 
 408         CFRelease(newComponents
); 
 415 ensure_unique_service_name(SCNetworkServiceRef service
) 
 417         SCNetworkInterfaceRef   interface
; 
 421         interface 
= SCNetworkServiceGetInterface(service
); 
 423         name 
= SCNetworkServiceGetName(service
); 
 431                 ok 
= SCNetworkServiceSetName(service
, name
); 
 436                 if (SCError() != kSCStatusKeyExists
) { 
 437                         SC_log(LOG_INFO
, "could not update service name for \"%@\": %s", 
 438                               SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
 439                               SCErrorString(SCError())); 
 443                 newName 
= copy_next_name(name
); 
 444                 if (newName 
== NULL
) { 
 445                         SC_log(LOG_INFO
, "could not create unique name for \"%@\": %s", 
 446                               SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
 447                               SCErrorString(SCError())); 
 451                 // try again with the "new" name 
 464 #endif  // PREVENT_DUPLICATE_SERVICE_NAMES 
 468 SCNetworkSetAddService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
 470         SCNetworkInterfaceRef           interface
; 
 471         CFArrayRef                      interface_config        
= NULL
; 
 475         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
 476         SCNetworkSetPrivateRef          setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
 478         if (!isA_SCNetworkSet(set
)) { 
 479                 _SCErrorSet(kSCStatusInvalidArgument
); 
 483         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 484                 _SCErrorSet(kSCStatusInvalidArgument
); 
 488         if (!__SCNetworkSetExists(set
)) { 
 489                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/removed set\n  set = %@\n  service = %@", 
 492                 _SC_crash_once("SCNetworkSetAddService() w/removed set", NULL
, NULL
); 
 493                 _SCErrorSet(kSCStatusInvalidArgument
); 
 497         if (!__SCNetworkServiceExists(service
)) { 
 498                 SC_log(LOG_ERR
, "SCNetworkSetAddService() w/removed service\n  set = %@\n  service =  %@", 
 501                 _SC_crash_once("SCNetworkSetAddService() w/removed service", NULL
, NULL
); 
 502                 _SCErrorSet(kSCStatusInvalidArgument
); 
 506         // make sure that we do not add an orphaned network service if its 
 507         // associated interface is a member of a bond or bridge. 
 508         interface 
= SCNetworkServiceGetInterface(service
); 
 509         if ((interface 
!= NULL
) && 
 510             __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) { 
 511                 _SCErrorSet(kSCStatusKeyExists
); 
 515 //#define PREVENT_DUPLICATE_SETS 
 516 #ifdef  PREVENT_DUPLICATE_SETS 
 519         // ensure that each service is only a member of ONE set 
 520         sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
 525                 n 
= CFArrayGetCount(sets
); 
 526                 for (i 
= 0; i 
< n
; i
++) { 
 531                         set 
= CFArrayGetValueAtIndex(sets
, i
); 
 532                         services 
= SCNetworkSetCopyServices(set
); 
 533                         found 
= CFArrayContainsValue(services
, 
 534                                                      CFRangeMake(0, CFArrayGetCount(services
)), 
 540                                 _SCErrorSet(kSCStatusKeyExists
); 
 546 #endif  /* PREVENT_DUPLICATE_SETS */ 
 548         // get the [deep] interface configuration settings 
 549         interface 
= SCNetworkServiceGetInterface(service
); 
 550         if (interface 
!= NULL
) { 
 551                 interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(set
, interface
); 
 554         // create the link between "set" and the "service" 
 555         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
 556                                                                  setPrivate
->setID
,             // set 
 557                                                                  servicePrivate
->serviceID
,     // service 
 559         link 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 560                                                               servicePrivate
->serviceID
,        // service 
 562         ok 
= SCPreferencesPathSetLink(setPrivate
->prefs
, path
, link
); 
 563 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
 565                 // We use the interface cache here to not reach into the 
 566                 // IORegistry for every service we go through 
 567                 _SCNetworkInterfaceCacheOpen(); 
 568                 ok 
= ensure_unique_service_name(service
); 
 569                 _SCNetworkInterfaceCacheClose(); 
 572                         // if we could not ensure a unique name, remove the (just added) 
 573                         // link between the "set" and the "service" 
 574                         (void) SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
 577 #endif  // PREVENT_DUPLICATE_SERVICE_NAMES 
 584         // push the [deep] interface configuration into all sets which contain this service. 
 585         if (interface 
!= NULL
) { 
 586                 __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, interface_config
); 
 589         // add service to ServiceOrder 
 590         _serviceOrder_add(set
, service
); 
 592         // mark set as no longer "new" 
 593         setPrivate
->established 
= TRUE
; 
 598                 SC_log(LOG_DEBUG
, "SCNetworkSetAddService(): %@, %@", set
, service
); 
 601         if (interface_config 
!= NULL
)   CFRelease(interface_config
); 
 607 SCNetworkSetCopy(SCPreferencesRef prefs
, CFStringRef setID
) 
 609         CFDictionaryRef         entity
; 
 611         SCNetworkSetPrivateRef  setPrivate
; 
 613         if (!isA_CFString(setID
)) { 
 614                 _SCErrorSet(kSCStatusInvalidArgument
); 
 618         path 
= SCPreferencesPathKeyCreateSet(NULL
, setID
); 
 619         entity 
= SCPreferencesPathGetValue(prefs
, path
); 
 622         if (!isA_CFDictionary(entity
)) { 
 623                 _SCErrorSet(kSCStatusNoKey
); 
 627         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 628         assert(setPrivate 
!= NULL
); 
 630         // mark set as "old" (already established) 
 631         setPrivate
->established 
= TRUE
; 
 633         return (SCNetworkSetRef
)setPrivate
; 
 638 SCNetworkSetContainsInterface(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
) 
 640         Boolean         found   
= FALSE
; 
 643         services 
= SCNetworkSetCopyServices(set
); 
 644         if (services 
!= NULL
) { 
 645                 found 
= __SCNetworkServiceExistsForInterface(services
, interface
); 
 653 CFArrayRef 
/* of SCNetworkSetRef's */ 
 654 SCNetworkSetCopyAll(SCPreferencesRef prefs
) 
 656         CFMutableArrayRef       array
; 
 659         CFDictionaryRef         sets
; 
 661         path 
= SCPreferencesPathKeyCreateSets(NULL
); 
 662         sets 
= SCPreferencesPathGetValue(prefs
, path
); 
 665         if ((sets 
!= NULL
) && !isA_CFDictionary(sets
)) { 
 669         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 671         n 
= (sets 
!= NULL
) ? CFDictionaryGetCount(sets
) : 0; 
 674                 const void *    keys_q
[N_QUICK
]; 
 675                 const void **   keys    
= keys_q
; 
 676                 const void *    vals_q
[N_QUICK
]; 
 677                 const void **   vals    
= vals_q
; 
 679                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 680                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 681                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 683                 CFDictionaryGetKeysAndValues(sets
, keys
, vals
); 
 684                 for (i 
= 0; i 
< n
; i
++) { 
 685                         SCNetworkSetPrivateRef  setPrivate
; 
 687                         if (!isA_CFDictionary(vals
[i
])) { 
 688                                 SC_log(LOG_INFO
, "error w/set \"%@\"", keys
[i
]); 
 692                         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, keys
[i
]); 
 693                         assert(setPrivate 
!= NULL
); 
 695                         // mark set as "old" (already established) 
 696                         setPrivate
->established 
= TRUE
; 
 698                         CFArrayAppendValue(array
, (SCNetworkSetRef
)setPrivate
); 
 699                         CFRelease(setPrivate
); 
 701                 if (keys 
!= keys_q
) { 
 702                         CFAllocatorDeallocate(NULL
, keys
); 
 703                         CFAllocatorDeallocate(NULL
, vals
); 
 711 CFArrayRef 
/* of SCNetworkInterfaceRef's */ 
 712 SCNetworkSetCopyAvailableInterfaces(SCNetworkSetRef set
) 
 714         CFMutableArrayRef       available
; 
 715         CFMutableSetRef         excluded        
= NULL
; 
 717         CFArrayRef              interfaces
; 
 718         CFIndex                 n_interfaces
; 
 719         CFIndex                 n_exclusions    
= 0; 
 720         SCPreferencesRef        prefs
; 
 721         SCNetworkSetPrivateRef  setPrivate
; 
 723         setPrivate 
= (SCNetworkSetPrivateRef
)set
; 
 724         prefs 
= setPrivate
->prefs
; 
 726         interfaces 
= _SCNetworkInterfaceCopyAllWithPreferences(prefs
); 
 727         n_interfaces 
= CFArrayGetCount(interfaces
); 
 728         if (n_interfaces 
== 0) { 
 733                 CFArrayRef      bridges 
= NULL
; 
 735                 excluded 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 737 #if     !TARGET_OS_IPHONE 
 738                 CFArrayRef      bonds   
= NULL
; 
 740                 bonds 
= SCBondInterfaceCopyAll(prefs
); 
 742                         __SCBondInterfaceListCollectMembers(bonds
, excluded
); 
 745 #endif  /* !TARGET_OS_IPHONE */ 
 747                 bridges 
= SCBridgeInterfaceCopyAll(prefs
); 
 748                 if (bridges 
!= NULL
) { 
 749                         __SCBridgeInterfaceListCollectMembers(bridges
, excluded
); 
 753                 n_exclusions 
= CFSetGetCount(excluded
); 
 756         if (n_exclusions 
== 0) { 
 757                 if (excluded 
!= NULL
) { 
 764         available 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 766         for (i 
= 0; i 
< n_interfaces
; i
++) { 
 767                 SCNetworkInterfaceRef   interface
; 
 769                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
 770                 if (CFSetContainsValue(excluded
, interface
)) { 
 775                 CFArrayAppendValue(available
, interface
); 
 778         CFRelease(interfaces
); 
 786 SCNetworkSetCopyCurrent(SCPreferencesRef prefs
) 
 788         CFArrayRef              components
; 
 789         CFStringRef             currentID
; 
 790         SCNetworkSetPrivateRef  setPrivate      
= NULL
; 
 792         currentID 
= SCPreferencesGetValue(prefs
, kSCPrefCurrentSet
); 
 793         if (!isA_CFString(currentID
)) { 
 797         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, currentID
, CFSTR("/")); 
 798         if (CFArrayGetCount(components
) == 3) { 
 802                 setID 
= CFArrayGetValueAtIndex(components
, 2); 
 803                 path 
= SCPreferencesPathKeyCreateSet(NULL
, setID
); 
 804                 if (CFEqual(path
, currentID
)) { 
 805                         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 806                         assert(setPrivate 
!= NULL
); 
 808                         // mark set as "old" (already established) 
 809                         setPrivate
->established 
= TRUE
; 
 811                         SC_log(LOG_NOTICE
, "SCNetworkSetCopyCurrent(): preferences are non-conformant"); 
 815         CFRelease(components
); 
 817         return (SCNetworkSetRef
)setPrivate
; 
 821 CFArrayRef 
/* of SCNetworkServiceRef's */ 
 822 SCNetworkSetCopyServices(SCNetworkSetRef set
) 
 824         CFMutableArrayRef       array
; 
 825         CFDictionaryRef         dict
; 
 828         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
 830         if (!isA_SCNetworkSet(set
)) { 
 831                 _SCErrorSet(kSCStatusInvalidArgument
); 
 836         path 
= SCPreferencesPathKeyCreateSetNetworkService(NULL
, setPrivate
->setID
, NULL
); 
 837         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
 839         if ((dict 
!= NULL
) && !isA_CFDictionary(dict
)) { 
 843         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 845         n 
= (dict 
!= NULL
) ? CFDictionaryGetCount(dict
) : 0; 
 848                 const void *    keys_q
[N_QUICK
]; 
 849                 const void **   keys    
= keys_q
; 
 851                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 852                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 854                 CFDictionaryGetKeysAndValues(dict
, keys
, NULL
); 
 855                 for (i 
= 0; i 
< n
; i
++) { 
 856                         CFArrayRef      components
; 
 859                         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, 
 861                                                                                  (CFStringRef
)keys
[i
], 
 863                         link 
= SCPreferencesPathGetLink(setPrivate
->prefs
, path
); 
 866                                 SC_log(LOG_INFO
, "service \"%@\" for set \"%@\" is not a link", 
 869                                 continue;        // if the service is not a link 
 872                         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, link
, CFSTR("/")); 
 873                         if (CFArrayGetCount(components
) == 3) { 
 874                                 CFStringRef serviceID
; 
 876                                 serviceID 
= CFArrayGetValueAtIndex(components
, 2); 
 877                                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,             // allocator 
 878                                                                                       serviceID
,        // service 
 880                                 if (CFEqual(path
, link
)) { 
 881                                         CFDictionaryRef entity
; 
 882                                         CFStringRef     interfacePath
; 
 883                                         Boolean         skip            
= FALSE
; 
 885                                         interfacePath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                    // allocator 
 886                                                                                                        serviceID
,               // service 
 887                                                                                                        kSCEntNetInterface
);     // entity 
 888                                         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, interfacePath
); 
 889                                         CFRelease(interfacePath
); 
 891                                         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 892                                                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 897                                                 SCNetworkServicePrivateRef      servicePrivate
; 
 899                                                 servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, 
 903                                                 CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
); 
 904                                                 CFRelease(servicePrivate
); 
 909                         CFRelease(components
); 
 911                 if (keys 
!= keys_q
) { 
 912                         CFAllocatorDeallocate(NULL
, keys
); 
 921 SCNetworkSetCreate(SCPreferencesRef prefs
) 
 923         CFArrayRef              components
; 
 924         CFDictionaryRef         entity
; 
 929         SCNetworkSetPrivateRef  setPrivate
; 
 931         prefix 
= SCPreferencesPathKeyCreateSets(NULL
); 
 932         path 
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
); 
 933         if (path 
== NULL
) path 
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
); 
 939         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/")); 
 940         setID 
= CFArrayGetValueAtIndex(components
, 2); 
 941         setPrivate 
= __SCNetworkSetCreatePrivate(NULL
, prefs
, setID
); 
 942         assert(setPrivate 
!= NULL
); 
 943         CFRelease(components
); 
 945         // mark set as "new" (not yet established) 
 946         setPrivate
->established 
= FALSE
; 
 948         // establish the set in the preferences 
 949         entity 
= CFDictionaryCreate(NULL
, 
 951                                     &kCFTypeDictionaryKeyCallBacks
, 
 952                                     &kCFTypeDictionaryValueCallBacks
); 
 953         ok 
= SCPreferencesPathSetValue(prefs
, path
, entity
); 
 957                 CFRelease(setPrivate
); 
 961         if (setPrivate 
!= NULL
) { 
 962                 SC_log(LOG_DEBUG
, "SCNetworkSetCreate(): %@", setPrivate
); 
 965         return (SCNetworkSetRef
)setPrivate
; 
 970 _SCNetworkSetCreateDefault(SCPreferencesRef prefs
) 
 975         CFStringRef     setName         
= NULL
; 
 978         set 
= SCNetworkSetCopyCurrent(prefs
); 
 980                 SC_log(LOG_NOTICE
, "creating default set w/already existing set"); 
 982                 _SCErrorSet(kSCStatusKeyExists
); 
 986         // create a new ("Automatic") set 
 987         set 
= SCNetworkSetCreate(prefs
); 
 989                 SC_log(LOG_NOTICE
, "could not create \"new\" set: %s", 
 990                        SCErrorString(SCError())); 
 994         setName 
= copy_default_set_name(TRUE
); 
 995         ok 
= SCNetworkSetSetName(set
, setName
); 
 998                 // if we could not save the new set's "name" 
 999                 SC_log(LOG_NOTICE
, "could not save the new set's name: %s", 
1000                        SCErrorString(SCError())); 
1004         ok 
= SCNetworkSetSetCurrent(set
); 
1006                 // if we could not make this the "current" set 
1007                 SC_log(LOG_NOTICE
, "could not establish new set as current: %s", 
1008                        SCErrorString(SCError())); 
1012         model 
= SCPreferencesGetValue(prefs
, MODEL
); 
1013         if (model 
== NULL
) { 
1014                 model 
= _SC_hw_model(FALSE
); 
1015                 SCPreferencesSetValue(prefs
, MODEL
, model
); 
1018         version 
= SCPreferencesGetValue(prefs
, kSCPrefVersion
); 
1019         if (version 
== NULL
) { 
1020                 const int       new_version     
= NETWORK_CONFIGURATION_VERSION
; 
1022                 version 
= CFNumberCreate(NULL
, kCFNumberIntType
, &new_version
); 
1023                 SCPreferencesSetValue(prefs
, kSCPrefVersion
, version
); 
1029         if (!ok 
&& (set 
!= NULL
)) { 
1030                 SCNetworkSetRemove(set
); 
1039 SCNetworkSetGetSetID(SCNetworkSetRef set
) 
1041         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1043         if (!isA_SCNetworkSet(set
)) { 
1044                 _SCErrorSet(kSCStatusInvalidArgument
); 
1048         return setPrivate
->setID
; 
1053 SCNetworkSetGetName(SCNetworkSetRef set
) 
1055         CFDictionaryRef         entity
; 
1057         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1059         if (!isA_SCNetworkSet(set
)) { 
1060                 _SCErrorSet(kSCStatusInvalidArgument
); 
1064         if (setPrivate
->name 
!= NULL
) { 
1065                 return setPrivate
->name
; 
1068         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1069         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1072         if (isA_CFDictionary(entity
)) { 
1075                 name 
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
); 
1076                 if (isA_CFString(name
)) { 
1077                         setPrivate
->name 
= CFRetain(name
); 
1081         if (setPrivate
->name 
!= NULL
) { 
1082                 CFStringRef     non_localized
; 
1084                 non_localized 
= copy_default_set_name(FALSE
); 
1085                 if (CFEqual(setPrivate
->name
, non_localized
)) { 
1086                         CFStringRef     localized
; 
1088                         // if "Automatic", return localized name 
1089                         localized 
= copy_default_set_name(TRUE
); 
1090                         CFRelease(setPrivate
->name
); 
1091                         setPrivate
->name 
= localized
; 
1094                 CFRelease(non_localized
); 
1097         return setPrivate
->name
; 
1101 CFArrayRef 
/* of serviceID CFStringRef's */ 
1102 SCNetworkSetGetServiceOrder(SCNetworkSetRef set
) 
1104         CFDictionaryRef         dict
; 
1106         CFArrayRef              serviceOrder
; 
1107         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1109         if (!isA_SCNetworkSet(set
)) { 
1110                 _SCErrorSet(kSCStatusInvalidArgument
); 
1114         path 
= SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL
, setPrivate
->setID
, kSCEntNetIPv4
); 
1119         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1121         if (!isA_CFDictionary(dict
)) { 
1125         serviceOrder 
= CFDictionaryGetValue(dict
, kSCPropNetServiceOrder
); 
1126         serviceOrder 
= isA_CFArray(serviceOrder
); 
1128         return serviceOrder
; 
1133 SCNetworkSetGetTypeID(void) 
1135         pthread_once(&initialized
, __SCNetworkSetInitialize
);   /* initialize runtime */ 
1136         return __kSCNetworkSetTypeID
; 
1140 #if     TARGET_OS_IPHONE 
1142 isDefaultSet(SCNetworkSetRef set
) 
1144         CFStringRef     defaultName
; 
1145         Boolean         isDefault       
= FALSE
; 
1146         CFStringRef     setName
; 
1148         defaultName 
= copy_default_set_name(TRUE
); 
1149         setName 
= SCNetworkSetGetName(set
); 
1150         isDefault 
= _SC_CFEqual(setName
, defaultName
); 
1151         CFRelease(defaultName
); 
1155 #endif  // TARGET_OS_IPHONE 
1159 SCNetworkSetRemove(SCNetworkSetRef set
) 
1161         CFStringRef             currentPath
; 
1164         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1166         if (!isA_SCNetworkSet(set
)) { 
1167                 _SCErrorSet(kSCStatusInvalidArgument
); 
1171         if (!__SCNetworkSetExists(set
)) { 
1172                 SC_log(LOG_ERR
, "SCNetworkSetRemove() w/removed set\n  set = %@", set
); 
1173                 _SC_crash_once("SCNetworkSetRemove() w/removed set", NULL
, NULL
); 
1174                 _SCErrorSet(kSCStatusInvalidArgument
); 
1178 #if     TARGET_OS_IPHONE 
1179         if (isDefaultSet(set
) && (geteuid() != 0)) { 
1180                 SC_log(LOG_ERR
, "SCNetworkSetRemove() failed, cannot remove set : %@", set
); 
1181                 _SC_crash("The \"Automatic\" network set cannot be removed", NULL
, NULL
); 
1182                 _SCErrorSet(kSCStatusInvalidArgument
); 
1185 #endif  // TARGET_OS_IPHONE 
1187         currentPath 
= SCPreferencesGetValue(setPrivate
->prefs
, kSCPrefCurrentSet
); 
1188         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1189         if (!isA_CFString(currentPath
) || !CFEqual(currentPath
, path
)) { 
1190                 ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
1192                 SC_log(LOG_DEBUG
, "SCNetworkSetRemove() failed, currently active: %@", setPrivate
->setID
); 
1193                 _SCErrorSet(kSCStatusInvalidArgument
); 
1198                 SC_log(LOG_DEBUG
, "SCNetworkSetRemove(): %@", set
); 
1206 SCNetworkSetRemoveService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
1208         SCNetworkInterfaceRef           interface
; 
1209         CFArrayRef                      interface_config        
= NULL
; 
1212         int                             sc_status               
= kSCStatusOK
; 
1213         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
1214         SCNetworkSetPrivateRef          setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
1216         if (!isA_SCNetworkSet(set
)) { 
1217                 _SCErrorSet(kSCStatusInvalidArgument
); 
1221         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1222                 _SCErrorSet(kSCStatusInvalidArgument
); 
1226         if (!__SCNetworkSetExists(set
)) { 
1227                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/removed set\n  set = %@\n  service = %@", 
1230                 _SC_crash_once("SCNetworkSetRemoveService() w/removed set", NULL
, NULL
); 
1231                 _SCErrorSet(kSCStatusInvalidArgument
); 
1235         if (!__SCNetworkServiceExists(service
)) { 
1236                 SC_log(LOG_ERR
, "SCNetworkSetRemoveService() w/removed service\n  set = %@\n  service = %@", 
1239                 _SC_crash_once("SCNetworkSetRemoveService() w/removed service", NULL
, NULL
); 
1240                 _SCErrorSet(kSCStatusInvalidArgument
); 
1244         // remove service from ServiceOrder 
1245         _serviceOrder_remove(set
, service
); 
1247         // get the [deep] interface configuration settings 
1248         interface 
= SCNetworkServiceGetInterface(service
); 
1249         if (interface 
!= NULL
) { 
1250                 interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(set
, interface
); 
1251                 if (interface_config 
!= NULL
) { 
1252                         // remove the interface configuration from all sets which contain this service. 
1253                         __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, NULL
); 
1257         // remove the link between "set" and the "service" 
1258         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, 
1260                                                                  servicePrivate
->serviceID
, 
1262         ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
1264                 sc_status 
= SCError();  // preserve the error 
1268         // push the [deep] interface configuration [back] into all sets which contain the service. 
1269         if (interface_config 
!= NULL
) { 
1270                 __SCNetworkInterfaceSetDeepConfiguration(set
, interface
, interface_config
); 
1271                 CFRelease(interface_config
); 
1275                 SC_log(LOG_DEBUG
, "SCNetworkSetRemoveService(): %@, %@", set
, service
); 
1277                 _SCErrorSet(sc_status
); 
1285 SCNetworkSetSetCurrent(SCNetworkSetRef set
) 
1289         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1291         if (!isA_SCNetworkSet(set
)) { 
1292                 _SCErrorSet(kSCStatusInvalidArgument
); 
1296         if (!__SCNetworkSetExists(set
)) { 
1297                 SC_log(LOG_ERR
, "SCNetworkSetSetCurrent() w/removed set\n  set = %@", set
); 
1298                 _SC_crash_once("SCNetworkSetSetCurrent() w/removed set", NULL
, NULL
); 
1299                 _SCErrorSet(kSCStatusInvalidArgument
); 
1303         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1304         ok 
= SCPreferencesSetValue(setPrivate
->prefs
, kSCPrefCurrentSet
, path
); 
1308                 SC_log(LOG_DEBUG
, "SCNetworkSetSetCurrent(): %@", set
); 
1316 SCNetworkSetSetName(SCNetworkSetRef set
, CFStringRef name
) 
1318         CFDictionaryRef         entity
; 
1319 #if     TARGET_OS_IPHONE 
1320         Boolean                 isDefaultName   
= FALSE
; 
1321 #endif  // TARGET_OS_IPHONE 
1322         CFStringRef             localized       
= NULL
; 
1323         CFStringRef             non_localized   
= NULL
; 
1326         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1328         if (!isA_SCNetworkSet(set
)) { 
1329                 _SCErrorSet(kSCStatusInvalidArgument
); 
1333         if (!__SCNetworkSetExists(set
)) { 
1334                 SC_log(LOG_ERR
, "SCNetworkSetSetName() w/removed set\n  set = %@\n  name = %@", 
1336                        name 
!= NULL 
? name 
: CFSTR("<NULL>")); 
1337                 _SC_crash_once("SCNetworkSetSetName() w/removed set", NULL
, NULL
); 
1338                 _SCErrorSet(kSCStatusInvalidArgument
); 
1342         if ((name 
!= NULL
) && !isA_CFString(name
)) { 
1343                 _SCErrorSet(kSCStatusInvalidArgument
); 
1347         // if known, compare against localized name 
1350                 non_localized 
= copy_default_set_name(FALSE
); 
1351                 if (CFEqual(name
, non_localized
)) { 
1352                         localized 
= copy_default_set_name(TRUE
); 
1354 #if     TARGET_OS_IPHONE 
1355                         isDefaultName 
= TRUE
; 
1356 #endif  // TARGET_OS_IPHONE 
1358 #if     TARGET_OS_IPHONE 
1360                         localized 
= copy_default_set_name(TRUE
); 
1361                         isDefaultName 
= CFEqual(name
, non_localized
); 
1363 #endif  // TARGET_OS_IPHONE 
1366 #if     TARGET_OS_IPHONE 
1367         if (!isDefaultName 
&& isDefaultSet(set
) && (geteuid() != 0)) { 
1368                 // if we are trying to change the name of the "Automatic" set 
1369                 SC_log(LOG_ERR
, "SCNetworkSetSetName() failed, cannot rename : %@", set
); 
1370                 _SC_crash("The \"Automatic\" network set cannot be renamed", NULL
, NULL
); 
1371                 _SCErrorSet(kSCStatusInvalidArgument
); 
1374 #endif  // TARGET_OS_IPHONE 
1376 #define PREVENT_DUPLICATE_SET_NAMES 
1377 #ifdef  PREVENT_DUPLICATE_SET_NAMES 
1379 #if     TARGET_OS_IPHONE 
1380         if (!isDefaultName
) { 
1381                 // On iOS, only block naming multiple sets with the name 
1382                 // "Automatic".  Others names are OK. 
1384 #endif  // TARGET_OS_IPHONE 
1389                 // ensure that each set is uniquely named 
1391                 sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
1396                         n 
= CFArrayGetCount(sets
); 
1397                         for (i 
= 0; i 
< n
; i
++) { 
1398                                 CFStringRef     otherID
; 
1399                                 CFStringRef     otherName
; 
1400                                 SCNetworkSetRef set             
= CFArrayGetValueAtIndex(sets
, i
); 
1402                                 otherID 
= SCNetworkSetGetSetID(set
); 
1403                                 if (CFEqual(setPrivate
->setID
, otherID
)) { 
1404                                         continue;       // skip current set 
1407                                 otherName 
= SCNetworkSetGetName(set
); 
1408                                 if ((otherName 
!= NULL
) && CFEqual(name
, otherName
)) { 
1409                                         // if "name" not unique 
1411                                         _SCErrorSet(kSCStatusKeyExists
); 
1418 #endif  /* PREVENT_DUPLICATE_SET_NAMES */ 
1420         // if known, store non-localized name 
1422         if ((name 
!= NULL
) && (non_localized 
!= NULL
)) { 
1423                 if (localized 
== NULL
) { 
1424                         localized 
= copy_default_set_name(TRUE
); 
1426                 if (CFEqual(name
, localized
)) { 
1427                         name 
= non_localized
; 
1431         // update the "name" 
1433         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1434         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1435         if (isA_CFDictionary(entity
) || 
1436             ((entity 
== NULL
) && (name 
!= NULL
))) { 
1437                 CFMutableDictionaryRef  newEntity
; 
1439                 if (entity 
!= NULL
) { 
1440                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1442                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1444                                                               &kCFTypeDictionaryKeyCallBacks
, 
1445                                                               &kCFTypeDictionaryValueCallBacks
); 
1448                         CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, name
); 
1450                         CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
); 
1452                 ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, path
, newEntity
); 
1453                 CFRelease(newEntity
); 
1460                 SC_log(LOG_DEBUG
, "SCNetworkSetSetName(): %@", set
); 
1463         if (localized 
!= NULL
)          CFRelease(localized
); 
1464         if (non_localized 
!= NULL
)      CFRelease(non_localized
); 
1470 SCNetworkSetSetServiceOrder(SCNetworkSetRef set
, CFArrayRef newOrder
) 
1472         CFMutableArrayRef       cleanOrder
; 
1473         CFDictionaryRef         dict
; 
1476         CFMutableDictionaryRef  newDict
; 
1479         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1481         if (!isA_SCNetworkSet(set
)) { 
1482                 _SCErrorSet(kSCStatusInvalidArgument
); 
1486         if (!__SCNetworkSetExists(set
)) { 
1487                 SC_log(LOG_ERR
, "SCNetworkSetSetServiceOrder() w/removed set\n  set = %@", set
); 
1488                 _SC_crash_once("SCNetworkSetSetServiceOrder() w/removed set", NULL
, NULL
); 
1489                 _SCErrorSet(kSCStatusInvalidArgument
); 
1493         if (isA_CFArray(newOrder
)) { 
1494                 n 
= CFArrayGetCount(newOrder
); 
1495                 for (i 
= 0; i 
< n
; i
++) { 
1496                         CFStringRef     serviceID
; 
1498                         serviceID 
= CFArrayGetValueAtIndex(newOrder
, i
); 
1499                         if (!isA_CFString(serviceID
)) { 
1500                                 _SCErrorSet(kSCStatusInvalidArgument
); 
1505                 _SCErrorSet(kSCStatusInvalidArgument
); 
1509         path 
= SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL
, setPrivate
->setID
, kSCEntNetIPv4
); 
1514         dict 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1516                 newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
); 
1518                 newDict 
= CFDictionaryCreateMutable(NULL
, 
1520                                                     &kCFTypeDictionaryKeyCallBacks
, 
1521                                                     &kCFTypeDictionaryValueCallBacks
); 
1524         cleanOrder 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1525         n 
= CFArrayGetCount(newOrder
); 
1526         for (i 
= 0; i 
< n
; i
++) { 
1527                 CFIndex         nClean          
= CFArrayGetCount(cleanOrder
); 
1528                 CFStringRef     serviceID       
= CFArrayGetValueAtIndex(newOrder
, i
); 
1530                 if ((nClean 
== 0) || 
1531                     !CFArrayContainsValue(cleanOrder
, CFRangeMake(0, nClean
), serviceID
)) { 
1532                         // if first reference to this serviceID 
1533                         CFArrayAppendValue(cleanOrder
, serviceID
); 
1535                         // skip duplicate serviceID 
1536                         SC_log(LOG_ERR
, "SCNetworkSetSetServiceOrder() found duplicate serviceID: removed %@\n", serviceID
); 
1539         CFDictionarySetValue(newDict
, kSCPropNetServiceOrder
, cleanOrder
); 
1540         CFRelease(cleanOrder
); 
1542         ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, path
, newDict
); 
1551 #pragma mark SCNetworkSet SPIs 
1556 __SCNetworkSetExists(SCNetworkSetRef set
) 
1558         CFDictionaryRef                 entity
; 
1560         SCNetworkSetPrivateRef          setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1562         if (setPrivate
->prefs 
== NULL
) { 
1566         path 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
1567         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, path
); 
1570         if (!isA_CFDictionary(entity
)) { 
1580 add_supported_interfaces(CFMutableArrayRef interface_list
, SCNetworkInterfaceRef interface
) 
1583         CFArrayRef      interface_types
; 
1586         interface_types 
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
); 
1587         n 
= (interface_types 
!= NULL
) ? CFArrayGetCount(interface_types
) : 0; 
1588         for (i 
= 0; i 
< n
; i
++) { 
1589                 SCNetworkInterfaceRef   parent
; 
1590                 CFStringRef             interface_type
; 
1592                 interface_type 
= CFArrayGetValueAtIndex(interface_types
, i
); 
1593                 parent 
= SCNetworkInterfaceCreateWithInterface(interface
, interface_type
); 
1594                 if (parent 
!= NULL
) { 
1595                         CFArrayAppendValue(interface_list
, parent
); 
1604 static CFSetRef 
/* of SCNetworkInterfaceRef's */ 
1605 copyExcludedInterfaces(SCPreferencesRef prefs
) 
1607         CFMutableSetRef excluded
; 
1608         CFArrayRef      interfaces
; 
1610         excluded 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
1612 #if     !TARGET_OS_IPHONE 
1613         // exclude Bond [member] interfaces 
1614         interfaces 
= SCBondInterfaceCopyAll(prefs
); 
1615         if (interfaces 
!= NULL
) { 
1616                 __SCBondInterfaceListCollectMembers(interfaces
, excluded
); 
1617                 CFRelease(interfaces
); 
1619 #endif  // !TARGET_OS_IPHONE 
1621         // exclude Bridge [member] interfaces 
1622         interfaces 
= SCBridgeInterfaceCopyAll(prefs
); 
1623         if (interfaces 
!= NULL
) { 
1624                 __SCBridgeInterfaceListCollectMembers(interfaces
, excluded
); 
1625                 CFRelease(interfaces
); 
1632 #if     !TARGET_OS_IPHONE 
1633 static SCBridgeInterfaceRef
 
1634 copyAutoBridgeInterface(SCPreferencesRef prefs
, CFStringRef bridgeName
) 
1636         SCBridgeInterfaceRef    bridge          
= NULL
; 
1637         CFArrayRef              interfaces
; 
1639         // exclude Bridge [member] interfaces 
1640         interfaces 
= SCBridgeInterfaceCopyAll(prefs
); 
1641         if (interfaces 
!= NULL
) { 
1645                 n 
= CFArrayGetCount(interfaces
); 
1646                 for (i 
= 0; i 
< n
; i
++) { 
1647                         SCBridgeInterfaceRef    interface
; 
1648                         CFStringRef             name    
= NULL
; 
1649                         CFDictionaryRef         options
; 
1651                         interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1652                         options 
= SCBridgeInterfaceGetOptions(interface
); 
1653                         if ((options 
!= NULL
) && 
1654                             CFDictionaryGetValueIfPresent(options
, 
1656                                                           (const void **)&name
) && 
1657                             _SC_CFEqual(name
, bridgeName
)) { 
1664                 CFRelease(interfaces
); 
1667         if (bridge 
== NULL
) { 
1668                 bridge 
= SCBridgeInterfaceCreate(prefs
); 
1669                 if (bridge 
!= NULL
) { 
1670                         CFMutableDictionaryRef  newOptions
; 
1673                         newOptions 
= CFDictionaryCreateMutable(NULL
, 0, 
1674                                                                &kCFTypeDictionaryKeyCallBacks
, 
1675                                                                &kCFTypeDictionaryValueCallBacks
); 
1676                         CFDictionarySetValue(newOptions
, CFSTR("__AUTO__"), bridgeName
); 
1677                         ok 
= SCBridgeInterfaceSetOptions(bridge
, newOptions
); 
1678                         CFRelease(newOptions
); 
1688 #endif  // !TARGET_OS_IPHONE 
1692 copyServices(SCNetworkSetRef set
) 
1694         CFArrayRef              services
; 
1695         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1697         // first, assume that we only want to add new services 
1698         // for those interfaces that are not represented in the 
1700         services 
= SCNetworkSetCopyServices(set
); 
1701         if ((services 
!= NULL
) && setPrivate
->established
) { 
1702                 // but, if we are given an existing (or "established") set 
1703                 // than we only want to add new services for those interfaces 
1704                 // that are not represented in *any* set. 
1705                 CFRelease(services
); 
1706                 services 
= SCNetworkServiceCopyAll(setPrivate
->prefs
); 
1713 #if     !TARGET_OS_IPHONE 
1714 static CF_RETURNS_RETAINED CFArrayRef
 
1715 updateServices(CFArrayRef services
, SCNetworkInterfaceRef interface
) 
1717         CFStringRef             bsdName
; 
1720         CFMutableArrayRef       newServices
; 
1722         if (services 
== NULL
) { 
1726         bsdName 
= SCNetworkInterfaceGetBSDName(interface
); 
1728         newServices 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1730         n 
= CFArrayGetCount(services
); 
1731         for (i 
= 0; i 
< n
; i
++) { 
1732                 SCNetworkInterfaceRef           interface
; 
1733                 CFStringRef                     interfaceName
; 
1734                 SCNetworkServiceRef             newService
; 
1735                 SCNetworkServiceRef             service
; 
1736                 CFStringRef                     serviceID
; 
1737                 SCNetworkServicePrivateRef      servicePrivate
; 
1739                 service 
= CFArrayGetValueAtIndex(services
, i
); 
1740                 interface 
= SCNetworkServiceGetInterface(service
); 
1741                 interfaceName 
= SCNetworkInterfaceGetBSDName(interface
); 
1742                 if (!_SC_CFEqual(interfaceName
, bsdName
)) { 
1743                         // if not a match, retain 
1744                         CFArrayAppendValue(newServices
, service
); 
1748                 // if a match, update 
1749                 serviceID 
= SCNetworkServiceGetServiceID(service
); 
1750                 servicePrivate 
= (SCNetworkServicePrivateRef
)service
; 
1751                 newService 
= SCNetworkServiceCopy(servicePrivate
->prefs
, serviceID
); 
1752                 if (newService 
!= NULL
) { 
1753                         CFArrayAppendValue(newServices
, newService
); 
1754                         CFRelease(newService
); 
1760 #endif  // !TARGET_OS_IPHONE 
1763 static __inline__ Boolean
 
1764 skipInterface(SCNetworkInterfaceRef interface
) 
1768         action 
= _SCNetworkInterfaceGetConfigurationAction(interface
); 
1769         if (isA_CFString(action
) && 
1770             CFEqual(action
, kSCNetworkInterfaceConfigurationActionValueNone
)) { 
1779 _SCNetworkSetCompare(const void *val1
, const void *val2
, void *context
) 
1781 #pragma unused(context) 
1786         SCNetworkSetRef s1      
= (SCNetworkSetRef
)val1
; 
1787         SCNetworkSetRef s2      
= (SCNetworkSetRef
)val2
; 
1789         name1 
= SCNetworkSetGetName(s1
); 
1790         name2 
= SCNetworkSetGetName(s2
); 
1792         if (name1 
!= NULL
) { 
1793                 if (name2 
!= NULL
) { 
1794                         return CFStringCompare(name1
, name2
, 0); 
1796                         return kCFCompareLessThan
; 
1800         if (name2 
!= NULL
) { 
1801                 return kCFCompareGreaterThan
; 
1804         id1 
= SCNetworkSetGetSetID(s1
); 
1805         id2 
= SCNetworkSetGetSetID(s2
); 
1806         return CFStringCompare(id1
, id2
, 0); 
1811 __SCNetworkSetEstablishDefaultConfigurationForInterfaces(SCNetworkSetRef set
, CFArrayRef interfaces
, Boolean excludeHidden
) 
1817         CFArrayRef              services
; 
1818         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
1819         Boolean                 updated         
= FALSE
; 
1820 #if     !TARGET_OS_IPHONE 
1821         Boolean                 updatedIFs      
= FALSE
; 
1822 #endif  // !TARGET_OS_IPHONE 
1824 #if     TARGET_OS_IPHONE 
1825         CFArrayRef              orphans         
= NULL
; 
1828         sets 
= SCNetworkSetCopyAll(setPrivate
->prefs
); 
1830                 if (CFArrayGetCount(sets
) == 1) { 
1831                         services 
= SCNetworkSetCopyServices(set
); 
1832                         if (services 
!= NULL
) { 
1833                                 n 
= CFArrayGetCount(services
); 
1834                                 CFRelease(services
); 
1837                         if ((n 
== 0) && CFEqual(set
, CFArrayGetValueAtIndex(sets
, 0))) { 
1838                                 // after a "Reset Network Settings" we need to find (and 
1839                                 // add back) any VPN services that were orphaned. 
1840                                 orphans 
= SCNetworkServiceCopyAll(setPrivate
->prefs
); 
1846 #endif  // TARGET_OS_IPHONE 
1848         // copy network services 
1849         services 
= copyServices(set
); 
1851         // copy network interfaces to be excluded 
1852         excluded 
= copyExcludedInterfaces(setPrivate
->prefs
); 
1854 #if     !TARGET_OS_IPHONE 
1855         // look for interfaces that should auto-magically be added 
1856         // to an Ethernet bridge 
1857         n 
= ((services 
!= NULL
) && (interfaces 
!= NULL
)) ? CFArrayGetCount(interfaces
) : 0; 
1858         for (i 
= 0; i 
< n
; i
++) { 
1859                 SCBridgeInterfaceRef    bridge          
= NULL
; 
1860                 SCNetworkInterfaceRef   interface
; 
1862                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1864                 if (excludeHidden 
&& skipInterface(interface
)) { 
1865                         // if not auto-configure 
1869                 if (CFSetContainsValue(excluded
, interface
)) { 
1870                         // if this interface is a member of a Bond or Bridge 
1874                 if (__SCNetworkServiceExistsForInterface(services
, interface
)) { 
1875                         // if this is not a new interface 
1879                 if (_SCNetworkInterfaceIsBuiltin(interface
) && 
1880                     _SCNetworkInterfaceIsThunderbolt(interface
) && 
1881                     !isA_SCBridgeInterface(interface
)) { 
1882                         // add built-in Thunderbolt interfaces to bridge 
1883                         bridge 
= copyAutoBridgeInterface(setPrivate
->prefs
, CFSTR("thunderbolt-bridge")); 
1886                 if (bridge 
!= NULL
) { 
1887                         CFIndex                 bridgeIndex
; 
1889                         CFMutableArrayRef       newMembers
; 
1890                         CFMutableSetRef         newExcluded
; 
1891                         CFMutableArrayRef       newInterfaces
; 
1892                         CFArrayRef              newServices
; 
1894                         // track the bridge interface (if it's in our list) 
1895                         bridgeIndex 
= CFArrayGetFirstIndexOfValue(interfaces
, 
1896                                                                   CFRangeMake(0, CFArrayGetCount(interfaces
)), 
1899                         // add new member interface 
1900                         members 
= SCBridgeInterfaceGetMemberInterfaces(bridge
); 
1901                         if ((members 
!= NULL
) && (CFArrayGetCount(members
) > 0)) { 
1902                                 newMembers 
= CFArrayCreateMutableCopy(NULL
, 0, members
); 
1903                                 updated 
= TRUE
;         // if we're updating an existing bridge 
1905                                 newMembers 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1907                         CFArrayAppendValue(newMembers
, interface
); 
1908                         ok 
= SCBridgeInterfaceSetMemberInterfaces(bridge
, newMembers
); 
1909                         CFRelease(newMembers
); 
1911                                 SC_log(LOG_INFO
, "could not update bridge with \"%@\": %s", 
1912                                        SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1913                                        SCErrorString(SCError())); 
1918                         // exclude the new member interface 
1919                         newExcluded 
= CFSetCreateMutableCopy(NULL
, 0, excluded
); 
1920                         CFRelease(excluded
); 
1921                         CFSetAddValue(newExcluded
, interface
); 
1922                         excluded 
= newExcluded
; 
1924                         // update the list of interfaces to include the [new or updated] bridge 
1925                         newInterfaces 
= CFArrayCreateMutableCopy(NULL
, 0, interfaces
); 
1926                         if (bridgeIndex 
!= kCFNotFound
) { 
1927                                 CFArraySetValueAtIndex(newInterfaces
, bridgeIndex
, bridge
); 
1929                                 CFArrayAppendValue(newInterfaces
, bridge
); 
1932                                 CFRelease(interfaces
); 
1934                         interfaces 
= newInterfaces
; 
1937                         // refresh [existing] services 
1938                         newServices 
= updateServices(services
, bridge
); 
1939                         if (newServices 
!= NULL
) { 
1940                                 CFRelease(services
); 
1941                                 services 
= newServices
; 
1947 #endif  // !TARGET_OS_IPHONE 
1949         n 
= ((services 
!= NULL
) && (interfaces 
!= NULL
)) ? CFArrayGetCount(interfaces
) : 0; 
1950         for (i 
= 0; i 
< n
; i
++) { 
1951                 SCNetworkInterfaceRef   interface
; 
1952                 CFMutableArrayRef       interface_list
; 
1954                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
1956                 if (excludeHidden 
&& skipInterface(interface
)) { 
1957                         // if not auto-configure 
1961                 if (CFSetContainsValue(excluded
, interface
)) { 
1962                         // if this interface is a member of a Bond or Bridge 
1966                 if (__SCNetworkServiceExistsForInterface(services
, interface
)) { 
1967                         // if this is not a new interface 
1971                 interface_list 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1972                 CFArrayAppendValue(interface_list
, interface
); 
1974                 while (ok 
&& (CFArrayGetCount(interface_list
) > 0)) { 
1975                         CFArrayRef              protocol_types
; 
1977                         interface 
= CFArrayGetValueAtIndex(interface_list
, 0); 
1979                         protocol_types 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
1980                         if ((protocol_types 
!= NULL
) && (CFArrayGetCount(protocol_types
) > 0)) { 
1981                                 SCNetworkServiceRef     service
; 
1983                                 service 
= SCNetworkServiceCreate(setPrivate
->prefs
, interface
); 
1984                                 if (service 
== NULL
) { 
1985                                         SC_log(LOG_ERR
, "could not create service for \"%@\": %s", 
1986                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1987                                                SCErrorString(SCError())); 
1992                                 ok 
= SCNetworkServiceEstablishDefaultConfiguration(service
); 
1994                                         SC_log(LOG_ERR
, "could not estabish default configuration for \"%@\": %s", 
1995                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
1996                                                SCErrorString(SCError())); 
1997                                         SCNetworkServiceRemove(service
); 
2002                                 ok 
= SCNetworkSetAddService(set
, service
); 
2004                                         SC_log(LOG_ERR
, "could not add service for \"%@\": %s", 
2005                                                SCNetworkInterfaceGetLocalizedDisplayName(interface
), 
2006                                                SCErrorString(SCError())); 
2007                                         SCNetworkServiceRemove(service
); 
2015                                 add_supported_interfaces(interface_list
, interface
); 
2020                         CFArrayRemoveValueAtIndex(interface_list
, 0); 
2022                 CFRelease(interface_list
); 
2024 #if     !TARGET_OS_IPHONE 
2025         if (updatedIFs 
&& (interfaces 
!= NULL
)) { 
2026                 CFRelease(interfaces
); 
2028 #endif  // !TARGET_OS_IPHONE 
2029         if (services 
!= NULL
)   CFRelease(services
); 
2030         CFRelease(excluded
); 
2032 #if     TARGET_OS_IPHONE 
2033         if (orphans 
!= NULL
) { 
2034                 if (ok 
&& updated
) { 
2036                         CFIndex n       
= CFArrayGetCount(orphans
); 
2038                         for (i 
= 0; i 
< n
; i
++) { 
2039                                 SCNetworkServiceRef     service
; 
2041                                 service 
= CFArrayGetValueAtIndex(orphans
, i
); 
2042                                 if (_SCNetworkServiceIsVPN(service
)) { 
2043                                         ok 
= SCNetworkSetAddService(set
, service
); 
2053 #endif  // TARGET_OS_IPHONE 
2059                         model 
= SCPreferencesGetValue(setPrivate
->prefs
, MODEL
); 
2060                         if (model 
== NULL
) { 
2061                                 model 
= _SC_hw_model(FALSE
); 
2062                                 SCPreferencesSetValue(setPrivate
->prefs
, MODEL
, model
); 
2065                         // if no changes were made 
2066                         _SCErrorSet(kSCStatusOK
); 
2075 SCNetworkSetEstablishDefaultConfiguration(SCNetworkSetRef set
) 
2077         CFArrayRef              interfaces
; 
2078         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
2079         Boolean                 updated         
= FALSE
; 
2081         if (!isA_SCNetworkSet(set
)) { 
2082                 _SCErrorSet(kSCStatusInvalidArgument
); 
2086         interfaces 
= _SCNetworkInterfaceCopyAllWithPreferences(setPrivate
->prefs
); 
2087         if (interfaces 
!= NULL
) { 
2088                 updated 
= __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set
, interfaces
, TRUE
); 
2089                 CFRelease(interfaces
); 
2097 SCNetworkSetEstablishDefaultInterfaceConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
) 
2099         CFArrayRef      interfaces
; 
2102         if (!isA_SCNetworkSet(set
)) { 
2103                 _SCErrorSet(kSCStatusInvalidArgument
); 
2107         if (!isA_SCNetworkInterface(interface
)) { 
2108                 _SCErrorSet(kSCStatusInvalidArgument
); 
2112         interfaces 
= CFArrayCreate(NULL
, (const void **)&interface
, 1, &kCFTypeArrayCallBacks
); 
2113         assert(interfaces 
!= NULL
); 
2114         updated 
= __SCNetworkSetEstablishDefaultConfigurationForInterfaces(set
, interfaces
, FALSE
); 
2115         CFRelease(interfaces
); 
2122 SCNetworkSetCopySelectedVPNService(SCNetworkSetRef set
) 
2126         SCNetworkServiceRef     selected        
= NULL
; 
2127         CFArrayRef              services
; 
2128         CFMutableArrayRef       services_vpn    
= NULL
; 
2130         if (!isA_SCNetworkSet(set
)) { 
2131                 _SCErrorSet(kSCStatusInvalidArgument
); 
2135         services 
= SCNetworkSetCopyServices(set
); 
2136         if (services 
!= NULL
) { 
2137                 n 
= CFArrayGetCount(services
); 
2138                 for (i 
= 0; i 
< n
; i
++) { 
2139                         SCNetworkServiceRef     service
; 
2141                         service 
= CFArrayGetValueAtIndex(services
, i
); 
2142                         if (!SCNetworkServiceGetEnabled(service
)) { 
2147                         if (!_SCNetworkServiceIsVPN(service
)) { 
2148                                 // if not VPN service 
2152                         if (services_vpn 
== NULL
) { 
2153                                 services_vpn 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
2155                         CFArrayAppendValue(services_vpn
, service
); 
2158                 CFRelease(services
); 
2161         if (services_vpn 
== NULL
) { 
2162                 // if no VPN services 
2166         n 
= CFArrayGetCount(services_vpn
); 
2169                 CFMutableArrayRef       sorted
; 
2171                 order 
= SCNetworkSetGetServiceOrder(set
); 
2172                 sorted 
= CFArrayCreateMutableCopy(NULL
, 0, services_vpn
); 
2173                 CFArraySortValues(sorted
, 
2174                                   CFRangeMake(0, CFArrayGetCount(sorted
)), 
2175                                   _SCNetworkServiceCompare
, 
2177                 CFRelease(services_vpn
); 
2178                 services_vpn 
= sorted
; 
2181 #if     TARGET_OS_IPHONE 
2183                 CFStringRef     serviceID_prefs
; 
2185 #define VPN_PREFERENCES CFSTR("com.apple.mobilevpn") 
2186 #define VPN_SERVICE_ID  CFSTR("activeVPNID") 
2188                 CFPreferencesAppSynchronize(VPN_PREFERENCES
); 
2189                 serviceID_prefs 
= CFPreferencesCopyAppValue(VPN_SERVICE_ID
, VPN_PREFERENCES
); 
2190                 if (serviceID_prefs 
!= NULL
) { 
2191                         for (i 
= 0; i 
< n
; i
++) { 
2192                                 SCNetworkServiceRef     service
; 
2193                                 CFStringRef             serviceID
; 
2195                                 service 
= CFArrayGetValueAtIndex(services_vpn
, i
); 
2196                                 serviceID 
= SCNetworkServiceGetServiceID(service
); 
2197                                 if (CFEqual(serviceID
, serviceID_prefs
)) { 
2205                         CFRelease(serviceID_prefs
); 
2208 #endif  // TARGET_OS_IPHONE 
2210         if (selected 
== NULL
) { 
2211                 selected 
= CFArrayGetValueAtIndex(services_vpn
, 0); 
2215         CFRelease(services_vpn
); 
2221 SCNetworkSetSetSelectedVPNService(SCNetworkSetRef set
, SCNetworkServiceRef service
) 
2224         CFArrayRef      services
; 
2226         if (!isA_SCNetworkSet(set
)) { 
2227                 _SCErrorSet(kSCStatusInvalidArgument
); 
2231         if (!isA_SCNetworkService(service
) || !_SCNetworkServiceIsVPN(service
)) { 
2232                 _SCErrorSet(kSCStatusInvalidArgument
); 
2236         services 
= SCNetworkSetCopyServices(set
); 
2237         if (services 
!= NULL
) { 
2239                 CFIndex n       
= CFArrayGetCount(services
); 
2241                 if (!CFArrayContainsValue(services
, CFRangeMake(0, n
), service
)) { 
2242                         // if selected service not a member of the current set 
2243                         _SCErrorSet(kSCStatusInvalidArgument
); 
2248                 for (i 
= 0; ok 
&& (i 
< n
); i
++) { 
2249                         SCNetworkServiceRef     vpn
; 
2251                         vpn 
= CFArrayGetValueAtIndex(services
, i
); 
2252                         if (!_SCNetworkServiceIsVPN(vpn
)) { 
2253                                 // if not VPN service 
2257                         ok 
= SCNetworkServiceSetEnabled(vpn
, CFEqual(service
, vpn
)); 
2263         if (services 
!= NULL
) CFRelease(services
); 
2269 _SCNetworkSetSetSetID(SCNetworkSetRef set
, CFStringRef newSetID
) 
2271         SCNetworkSetRef         currentSet              
= NULL
; 
2272         SCNetworkSetPrivateRef  currentSetPrivate       
= NULL
; 
2273         CFDictionaryRef         entity
; 
2274         CFStringRef             newPath
; 
2276         CFStringRef             oldPath                 
= NULL
; 
2277         SCNetworkSetPrivateRef  setPrivate              
= (SCNetworkSetPrivateRef
)set
; 
2278         Boolean                 updateCurrentSet        
= FALSE
; 
2280         if (!isA_SCNetworkSet(set
)) { 
2281                 _SCErrorSet(kSCStatusInvalidArgument
); 
2285         if (!isA_CFString(newSetID
)) { 
2286                 _SCErrorSet(kSCStatusInvalidArgument
); 
2290         if (!__SCNetworkSetExists(set
)) { 
2291                 SC_log(LOG_ERR
, "_SCNetworkSetSetSetID() w/removed set\n  set = %@\n  setID = %@", 
2294                 _SC_crash_once("_SCNetworkSetSetSetID() w/removed set", NULL
, NULL
); 
2295                 _SCErrorSet(kSCStatusInvalidArgument
); 
2299         // If newSetID is equal to current setID, our work is done 
2300         if (CFEqual(newSetID
, setPrivate
->setID
)) { 
2304         newPath 
= SCPreferencesPathKeyCreateSet(NULL
, newSetID
); 
2305         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, newPath
); 
2306         if (isA_CFDictionary(entity
)) { 
2307                 // if the new set already exists 
2308                 _SCErrorSet(kSCStatusKeyExists
); 
2312         oldPath 
= SCPreferencesPathKeyCreateSet(NULL
, setPrivate
->setID
); 
2313         entity 
= SCPreferencesPathGetValue(setPrivate
->prefs
, oldPath
); 
2314         if (!isA_CFDictionary(entity
)) { 
2315                 // if the set has already been removed 
2316                 _SCErrorSet(kSCStatusNoKey
); 
2320         ok 
= SCPreferencesPathSetValue(setPrivate
->prefs
, newPath
, entity
); 
2325         ok 
= SCPreferencesPathRemoveValue(setPrivate
->prefs
, oldPath
); 
2330         // update current set (if needed) 
2331         currentSet 
= SCNetworkSetCopyCurrent(setPrivate
->prefs
); 
2332         if (currentSet 
!= NULL
) { 
2333                 currentSetPrivate 
= (SCNetworkSetPrivateRef
)currentSet
; 
2334                 if (CFEqual(currentSetPrivate
->setID
, setPrivate
->setID
)) { 
2335                         updateCurrentSet 
= TRUE
; 
2337                 CFRelease(currentSet
); 
2340         SC_log(LOG_DEBUG
, "_SCNetworkSetSetID(): %@ --> %@", set
, newSetID
); 
2342         // replace setID with new one 
2344         CFRelease(setPrivate
->setID
); 
2345         setPrivate
->setID 
= newSetID
; 
2347         if (updateCurrentSet
) { 
2348                 SCNetworkSetSetCurrent(set
); 
2353         if (oldPath 
!= NULL
) { 
2356         if (newPath 
!= NULL
) {