2  * Copyright (c) 2004-2018 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" 
  35 #include "SCPreferencesInternal.h" 
  39 #define EXTERNAL_ID_DOMAIN_PREFIX       "_" 
  41 static CFStringRef      
__SCNetworkServiceCopyDescription       (CFTypeRef cf
); 
  42 static void             __SCNetworkServiceDeallocate            (CFTypeRef cf
); 
  43 static Boolean          
__SCNetworkServiceEqual                 (CFTypeRef cf1
, CFTypeRef cf2
); 
  44 static CFHashCode       
__SCNetworkServiceHash                  (CFTypeRef cf
); 
  47 static CFTypeID __kSCNetworkServiceTypeID               
= _kCFRuntimeNotATypeID
; 
  50 static const CFRuntimeClass __SCNetworkServiceClass 
= { 
  52         "SCNetworkService",                     // className 
  55         __SCNetworkServiceDeallocate
,           // dealloc 
  56         __SCNetworkServiceEqual
,                // equal 
  57         __SCNetworkServiceHash
,                 // hash 
  58         NULL
,                                   // copyFormattingDesc 
  59         __SCNetworkServiceCopyDescription       
// copyDebugDesc 
  63 static pthread_once_t           initialized             
= PTHREAD_ONCE_INIT
; 
  67 __SCNetworkServiceCopyDescription(CFTypeRef cf
) 
  69         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
  70         CFMutableStringRef              result
; 
  71         SCNetworkServiceRef             service         
= (SCNetworkServiceRef
)cf
; 
  72         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
  74         result 
= CFStringCreateMutable(allocator
, 0); 
  75         CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkService %p [%p]> {"), service
, allocator
); 
  76         CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), servicePrivate
->serviceID
); 
  77         if (servicePrivate
->prefs 
!= NULL
) { 
  78                 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), servicePrivate
->prefs
); 
  79         } else if (servicePrivate
->store 
!= NULL
) { 
  80                 CFStringAppendFormat(result
, NULL
, CFSTR(", store = %p"), servicePrivate
->store
); 
  82         if (servicePrivate
->name 
!= NULL
) { 
  83                 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), servicePrivate
->name
); 
  85         if (!__SCNetworkServiceExists(service
)) { 
  86                 CFStringAppendFormat(result
, NULL
, CFSTR(", REMOVED")); 
  88         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  95 __SCNetworkServiceDeallocate(CFTypeRef cf
) 
  97         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
  99         /* release resources */ 
 101         CFRelease(servicePrivate
->serviceID
); 
 102         if (servicePrivate
->interface 
!= NULL
) CFRelease(servicePrivate
->interface
); 
 103         if (servicePrivate
->prefs 
!= NULL
) CFRelease(servicePrivate
->prefs
); 
 104         if (servicePrivate
->store 
!= NULL
) CFRelease(servicePrivate
->store
); 
 105         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
 106         if (servicePrivate
->externalIDs 
!= NULL
) CFRelease(servicePrivate
->externalIDs
); 
 113 __SCNetworkServiceEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 115         SCNetworkServicePrivateRef      s1      
= (SCNetworkServicePrivateRef
)cf1
; 
 116         SCNetworkServicePrivateRef      s2      
= (SCNetworkServicePrivateRef
)cf2
; 
 121         if (s1
->prefs 
!= s2
->prefs
) 
 122                 return FALSE
;   // if not the same prefs 
 124         if (!CFEqual(s1
->serviceID
, s2
->serviceID
)) 
 125                 return FALSE
;   // if not the same service identifier 
 132 __SCNetworkServiceHash(CFTypeRef cf
) 
 134         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
 136         return CFHash(servicePrivate
->serviceID
); 
 141 __SCNetworkServiceInitialize(void) 
 143         __kSCNetworkServiceTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkServiceClass
); 
 148 __private_extern__ SCNetworkServicePrivateRef
 
 149 __SCNetworkServiceCreatePrivate(CFAllocatorRef          allocator
, 
 150                                 SCPreferencesRef        prefs
, 
 151                                 CFStringRef             serviceID
, 
 152                                 SCNetworkInterfaceRef   interface
) 
 154         SCNetworkServicePrivateRef              servicePrivate
; 
 157         /* initialize runtime */ 
 158         pthread_once(&initialized
, __SCNetworkServiceInitialize
); 
 160         /* allocate target */ 
 161         size           
= sizeof(SCNetworkServicePrivate
) - sizeof(CFRuntimeBase
); 
 162         servicePrivate 
= (SCNetworkServicePrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 163                                                                               __kSCNetworkServiceTypeID
, 
 166         if (servicePrivate 
== NULL
) { 
 170         /* initialize non-zero/NULL members */ 
 171         servicePrivate
->prefs           
= (prefs 
!= NULL
) ? CFRetain(prefs
): NULL
; 
 172         servicePrivate
->serviceID       
= CFStringCreateCopy(NULL
, serviceID
); 
 173         servicePrivate
->interface       
= (interface 
!= NULL
) ? CFRetain(interface
) : NULL
; 
 175         return servicePrivate
; 
 180 #pragma mark Service ordering 
 184 _SCNetworkServiceCompare(const void *val1
, const void *val2
, void *context
) 
 188         CFArrayRef              order   
= (CFArrayRef
)context
; 
 189         SCNetworkServiceRef     s1      
= (SCNetworkServiceRef
)val1
; 
 190         SCNetworkServiceRef     s2      
= (SCNetworkServiceRef
)val2
; 
 192         id1 
= SCNetworkServiceGetServiceID(s1
); 
 193         id2 
= SCNetworkServiceGetServiceID(s2
); 
 200                 range 
= CFRangeMake(0, CFArrayGetCount(order
)); 
 201                 o1 
= CFArrayGetFirstIndexOfValue(order
, range
, id1
); 
 202                 o2 
= CFArrayGetFirstIndexOfValue(order
, range
, id2
); 
 205                         return (o2 
!= kCFNotFound
) ? kCFCompareGreaterThan 
: kCFCompareLessThan
; 
 206                 } else if (o1 
< o2
) { 
 207                         return (o1 
!= kCFNotFound
) ? kCFCompareLessThan    
: kCFCompareGreaterThan
; 
 211         return CFStringCompare(id1
, id2
, 0); 
 216 #pragma mark SCNetworkService APIs 
 222 __private_extern__ CFArrayRef 
/* of SCNetworkServiceRef's */ 
 223 __SCNetworkServiceCopyAllEnabled(SCPreferencesRef prefs
) 
 225         CFMutableArrayRef       array   
= NULL
; 
 230         sets 
= SCNetworkSetCopyAll(prefs
); 
 235         n_sets 
= CFArrayGetCount(sets
); 
 236         for (i_sets 
= 0; i_sets 
< n_sets
; i_sets
++) { 
 242                 set 
= CFArrayGetValueAtIndex(sets
, i_sets
); 
 243                 services 
= SCNetworkSetCopyServices(set
); 
 244                 if (services 
== NULL
) { 
 248                 n_services 
= CFArrayGetCount(services
); 
 249                 for (i_services 
= 0; i_services 
< n_services
; i_services
++) { 
 250                         SCNetworkServiceRef service
; 
 252                         service 
= CFArrayGetValueAtIndex(services
, i_services
); 
 253                         if (!SCNetworkServiceGetEnabled(service
)) { 
 258                         if ((array 
== NULL
) || 
 259                             !CFArrayContainsValue(array
, 
 260                                                   CFRangeMake(0, CFArrayGetCount(array
)), 
 263                                         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 265                                 CFArrayAppendValue(array
, service
); 
 276 __private_extern__ Boolean
 
 277 __SCNetworkServiceExistsForInterface(CFArrayRef services
, SCNetworkInterfaceRef interface
) 
 282         n 
= isA_CFArray(services
) ? CFArrayGetCount(services
) : 0; 
 283         for (i 
= 0; i 
< n
; i
++) { 
 284                 SCNetworkServiceRef     service
; 
 285                 SCNetworkInterfaceRef   service_interface
; 
 287                 service 
= CFArrayGetValueAtIndex(services
, i
); 
 289                 service_interface 
= SCNetworkServiceGetInterface(service
); 
 290                 while (service_interface 
!= NULL
) { 
 291                         if (CFEqual(interface
, service_interface
)) { 
 295                         service_interface 
= SCNetworkInterfaceGetInterface(service_interface
); 
 304 mergeDict(const void *key
, const void *value
, void *context
) 
 306         CFMutableDictionaryRef  newDict 
= (CFMutableDictionaryRef
)context
; 
 308         CFDictionarySetValue(newDict
, key
, value
); 
 313 static CF_RETURNS_RETAINED CFDictionaryRef
 
 314 _protocolTemplate(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 316         SCNetworkInterfaceRef           interface
; 
 317         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 318         CFDictionaryRef                 
template        = NULL
; 
 320         interface 
= servicePrivate
->interface
; 
 321         if (interface 
!= NULL
) { 
 322                 SCNetworkInterfaceRef   childInterface
; 
 323                 CFStringRef             childInterfaceType      
= NULL
; 
 324                 CFStringRef             interfaceType
; 
 327                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(servicePrivate
->interface
); 
 328                 childInterface 
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
); 
 329                 if (childInterface 
!= NULL
) { 
 330                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 333                 template = __copyProtocolTemplate(interfaceType
, childInterfaceType
, protocolType
); 
 334                 if (template != NULL
) { 
 335                         CFDictionaryRef         overrides
; 
 337                         // move to the interface at the lowest layer 
 338                         while (childInterface 
!= NULL
) { 
 339                                 interface 
= childInterface
; 
 340                                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 343                         overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, protocolType
); 
 344                         if (isA_CFDictionary(overrides
)) { 
 345                                 CFMutableDictionaryRef  newTemplate
; 
 347                                 newTemplate 
= CFDictionaryCreateMutableCopy(NULL
, 0, template); 
 348                                 CFDictionaryApplyFunction(overrides
, mergeDict
, newTemplate
); 
 350                                 template = newTemplate
; 
 355         if (template == NULL
) { 
 356                 template = CFDictionaryCreate(NULL
, 
 360                                               &kCFTypeDictionaryKeyCallBacks
, 
 361                                               &kCFTypeDictionaryValueCallBacks
); 
 369 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 371         CFDictionaryRef                 entity
; 
 373         CFDictionaryRef                 newEntity       
= NULL
; 
 376         SCNetworkProtocolRef            protocol        
= NULL
; 
 377         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 379         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 380                 _SCErrorSet(kSCStatusInvalidArgument
); 
 384         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
 385                 _SCErrorSet(kSCStatusInvalidArgument
); 
 389         if (!__SCNetworkServiceExists(service
)) { 
 390                 SC_log(LOG_ERR
, "SCNetworkServiceAddProtocolType() w/removed service\n  service = %@\n  protocol = %@", 
 393                 _SC_crash_once("SCNetworkServiceAddProtocolType() w/removed service", NULL
, NULL
); 
 394                 _SCErrorSet(kSCStatusInvalidArgument
); 
 398         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 399                                                               servicePrivate
->serviceID
,        // service 
 400                                                               protocolType
);                    // entity 
 402         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 403         if (entity 
!= NULL
) { 
 404                 // if "protocol" already exists 
 405                 _SCErrorSet(kSCStatusKeyExists
); 
 409         newEntity 
= CFDictionaryCreate(NULL
, 
 413                                        &kCFTypeDictionaryKeyCallBacks
, 
 414                                        &kCFTypeDictionaryValueCallBacks
); 
 415         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
 416         CFRelease(newEntity
); 
 422         protocol  
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
 423         assert(protocol 
!= NULL
); 
 425         newEntity 
= _protocolTemplate(service
, protocolType
); 
 426         assert(newEntity 
!= NULL
); 
 428         ok 
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
); 
 430                 // could not set default configuration 
 434         newEnabled 
= !CFDictionaryContainsKey(newEntity
, kSCResvInactive
); 
 435         ok 
= SCNetworkProtocolSetEnabled(protocol
, newEnabled
); 
 437                 // could not enable/disable protocol 
 443         if (newEntity 
!= NULL
) CFRelease(newEntity
); 
 444         if (protocol 
!= NULL
) CFRelease(protocol
); 
 447                 SC_log(LOG_DEBUG
, "SCNetworkServiceAddProtocolType(): %@, %@", service
, protocolType
); 
 455 CFArrayRef 
/* of SCNetworkServiceRef's */ 
 456 SCNetworkServiceCopyAll(SCPreferencesRef prefs
) 
 458         CFMutableArrayRef       array
; 
 461         CFDictionaryRef         services
; 
 463         path 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 464         services 
= SCPreferencesPathGetValue(prefs
, path
); 
 467         if ((services 
!= NULL
) && !isA_CFDictionary(services
)) { 
 471         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 473         n 
= (services 
!= NULL
) ? CFDictionaryGetCount(services
) : 0; 
 476                 const void *    keys_q
[N_QUICK
]; 
 477                 const void **   keys    
= keys_q
; 
 478                 const void *    vals_q
[N_QUICK
]; 
 479                 const void **   vals    
= vals_q
; 
 481                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 482                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 483                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 485                 CFDictionaryGetKeysAndValues(services
, keys
, vals
); 
 486                 for (i 
= 0; i 
< n
; i
++) { 
 487                         CFDictionaryRef                 entity
; 
 488                         SCNetworkServicePrivateRef      servicePrivate
; 
 490                         if (!isA_CFDictionary(vals
[i
])) { 
 491                                 SC_log(LOG_INFO
, "error w/service \"%@\"", keys
[i
]); 
 495                         entity 
= CFDictionaryGetValue(vals
[i
], kSCEntNetInterface
); 
 496                         if (!isA_CFDictionary(entity
)) { 
 498                                 SC_log(LOG_INFO
, "no \"%@\" entity for service \"%@\"", 
 504                         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 505                                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 509                         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, keys
[i
], NULL
); 
 510                         assert(servicePrivate 
!= NULL
); 
 511                         CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
); 
 512                         CFRelease(servicePrivate
); 
 514                 if (keys 
!= keys_q
) { 
 515                         CFAllocatorDeallocate(NULL
, keys
); 
 516                         CFAllocatorDeallocate(NULL
, vals
); 
 525 CFArrayRef 
/* of SCNetworkInterfaceRef's */ 
 526 __SCNetworkServiceCopyAllInterfaces(SCPreferencesRef prefs
) 
 528         CFMutableArrayRef interfaces 
= NULL
; 
 529         CFArrayRef services 
= NULL
; 
 530         CFIndex servicesCount 
= 0; 
 531         SCNetworkServiceRef service 
= NULL
; 
 532         SCNetworkInterfaceRef interface 
= NULL
; 
 534         services 
= SCNetworkServiceCopyAll(prefs
); 
 535         if (services 
== NULL
) { 
 539         servicesCount 
= CFArrayGetCount(services
); 
 540         if (servicesCount 
== 0) { 
 544         interfaces 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 546         for (CFIndex idx 
= 0; idx 
< servicesCount
; idx
++) { 
 547                 service 
= CFArrayGetValueAtIndex(services
, idx
); 
 548                 interface 
= SCNetworkServiceGetInterface(service
); 
 550                 if (isA_SCNetworkInterface(interface
) == NULL
) { 
 553                 CFArrayAppendValue(interfaces
, interface
); 
 556         if (CFArrayGetCount(interfaces
) == 0) { 
 557                 // Do not return an empty array 
 558                 CFRelease(interfaces
); 
 564         if (services 
!= NULL
) { 
 572  * build a list of all of a services entity types that are associated 
 573  * with the services interface.  The list will include : 
 575  * - entity types associated with the interface type (Ethernet, FireWire, PPP, ...) 
 576  * - entity types associated with the interface sub-type (PPPSerial, PPPoE, L2TP, PPTP, ...) 
 577  * - entity types associated with the hardware device (Ethernet, AirPort, FireWire, Modem, ...) 
 580 _copyInterfaceEntityTypes(CFDictionaryRef protocols
) 
 582         CFDictionaryRef interface
; 
 583         CFMutableSetRef interface_entity_types
; 
 585         interface_entity_types 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 587         interface 
= CFDictionaryGetValue(protocols
, kSCEntNetInterface
); 
 588         if (isA_CFDictionary(interface
)) { 
 589                 CFStringRef     entities
[]      = { kSCPropNetInterfaceType
, 
 590                                                     kSCPropNetInterfaceSubType
, 
 591                                                     kSCPropNetInterfaceHardware 
}; 
 593                 // include the "Interface" entity itself 
 594                 CFSetAddValue(interface_entity_types
, kSCEntNetInterface
); 
 596                 // include the entities associated with the interface 
 597                 for (size_t i 
= 0; i 
< sizeof(entities
)/sizeof(entities
[0]); i
++) { 
 600                         entity 
= CFDictionaryGetValue(interface
, entities
[i
]); 
 601                         if (isA_CFString(entity
)) { 
 602                                 CFSetAddValue(interface_entity_types
, entity
); 
 607                  * and, because we've found some misguided network preference code 
 608                  * developers leaving [PPP] entity dictionaries around even though 
 609                  * they are unused and/or unneeded... 
 611                 CFSetAddValue(interface_entity_types
, kSCEntNetPPP
); 
 614         return interface_entity_types
; 
 619 SCNetworkServiceCopy(SCPreferencesRef prefs
, CFStringRef serviceID
) 
 621         CFDictionaryRef                 entity
; 
 623         SCNetworkServicePrivateRef      servicePrivate
; 
 625         if (!isA_CFString(serviceID
)) { 
 626                 _SCErrorSet(kSCStatusInvalidArgument
); 
 630         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                     // allocator 
 631                                                               serviceID
,                // service 
 632                                                               kSCEntNetInterface
);      // entity 
 633         entity 
= SCPreferencesPathGetValue(prefs
, path
); 
 636         if (!isA_CFDictionary(entity
)) { 
 637                 // a "service" must have an "interface" 
 638                 _SCErrorSet(kSCStatusNoKey
); 
 642         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 643                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 644                 _SCErrorSet(kSCStatusNoKey
); 
 648         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 649         return (SCNetworkServiceRef
)servicePrivate
; 
 654 _SCNetworkServiceCopyActive(SCDynamicStoreRef store
, CFStringRef serviceID
) 
 656         SCNetworkServicePrivateRef      servicePrivate
; 
 658         if (!isA_CFString(serviceID
)) { 
 659                 _SCErrorSet(kSCStatusInvalidArgument
); 
 663         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, NULL
, serviceID
, NULL
); 
 664         assert(servicePrivate 
!= NULL
); 
 666                 servicePrivate
->store 
= CFRetain(store
); 
 668         return (SCNetworkServiceRef
)servicePrivate
; 
 673 SCNetworkServiceCopyProtocol(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 675         CFSetRef                        non_protocol_entities
; 
 677         CFDictionaryRef                 protocols
; 
 678         SCNetworkProtocolPrivateRef     protocolPrivate 
= NULL
; 
 679         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 681         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 682                 _SCErrorSet(kSCStatusInvalidArgument
); 
 686         if (!isA_CFString(protocolType
)) { 
 687                 _SCErrorSet(kSCStatusInvalidArgument
); 
 691         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 692                                                               servicePrivate
->serviceID
,        // service 
 694         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 697         if (!isA_CFDictionary(protocols
)) { 
 699                 _SCErrorSet(kSCStatusFailed
); 
 703         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 704         if (CFSetContainsValue(non_protocol_entities
, protocolType
)) { 
 705                 // if the "protocolType" matches an interface entity type 
 706                 _SCErrorSet(kSCStatusInvalidArgument
); 
 710         if (!CFDictionaryContainsKey(protocols
, protocolType
)) { 
 711                 // if the "protocolType" entity does not exist 
 712                 _SCErrorSet(kSCStatusNoKey
); 
 716         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, protocolType
, service
); 
 720         CFRelease(non_protocol_entities
); 
 722         return (SCNetworkProtocolRef
)protocolPrivate
; 
 726 CFArrayRef 
/* of SCNetworkProtocolRef's */ 
 727 SCNetworkServiceCopyProtocols(SCNetworkServiceRef service
) 
 729         CFMutableArrayRef               array
; 
 731         CFSetRef                        non_protocol_entities
; 
 733         CFDictionaryRef                 protocols
; 
 734         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 736         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 737                 _SCErrorSet(kSCStatusInvalidArgument
); 
 741         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 742                                                               servicePrivate
->serviceID
,        // service 
 744         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 747         if (!isA_CFDictionary(protocols
)) { 
 749                 _SCErrorSet(kSCStatusFailed
); 
 753         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 755         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 757         n 
= CFDictionaryGetCount(protocols
); 
 760                 const void *                    keys_q
[N_QUICK
]; 
 761                 const void **                   keys            
= keys_q
; 
 762                 const void *                    vals_q
[N_QUICK
]; 
 763                 const void **                   vals            
= vals_q
; 
 765                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 766                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 767                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 769                 CFDictionaryGetKeysAndValues(protocols
, keys
, vals
); 
 770                 for (i 
= 0; i 
< n
; i
++) { 
 771                         SCNetworkProtocolPrivateRef     protocolPrivate
; 
 773                         if (!isA_CFDictionary(vals
[i
])) { 
 774                                 // if it's not a dictionary then it can't be a protocol entity 
 778                         if (CFSetContainsValue(non_protocol_entities
, keys
[i
])) { 
 779                                 // skip any non-protocol (interface) entities 
 783                         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, keys
[i
], service
); 
 784                         CFArrayAppendValue(array
, (SCNetworkProtocolRef
)protocolPrivate
); 
 786                         CFRelease(protocolPrivate
); 
 788                 if (keys 
!= keys_q
) { 
 789                         CFAllocatorDeallocate(NULL
, keys
); 
 790                         CFAllocatorDeallocate(NULL
, vals
); 
 794         CFRelease(non_protocol_entities
); 
 801 __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef     service
, 
 802                                      SCNetworkInterfaceRef   interface
) 
 804         CFDictionaryRef                 entity
; 
 807         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
 809         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 810                                                               servicePrivate
->serviceID
,        // service 
 811                                                               kSCEntNetInterface
);              // entity 
 812         entity 
= __SCNetworkInterfaceCopyInterfaceEntity(interface
); 
 813         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, entity
); 
 822 SCNetworkServiceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
) 
 824         CFArrayRef                      components
; 
 825         CFArrayRef                      interface_config
; 
 826         CFStringRef                     interface_name
; 
 827         SCNetworkInterfaceRef           newInterface
; 
 830         CFStringRef                     serviceID
; 
 831         SCNetworkServicePrivateRef      servicePrivate
; 
 832         CFArrayRef                      supported_protocols
; 
 834         if (!isA_SCNetworkInterface(interface
)) { 
 835                 _SCErrorSet(kSCStatusInvalidArgument
); 
 839         // only allow network interfaces which support one or more protocols 
 840         // to be added to a service.  The one exception is that we allow 
 841         // third-party interface types to be configured. 
 842         supported_protocols 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
 843         if (supported_protocols 
== NULL
) { 
 844                 CFStringRef     interface_type
; 
 846                 interface_type 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 847                 if (CFStringFind(interface_type
, CFSTR("."), 0).location 
== kCFNotFound
) { 
 848                         _SCErrorSet(kSCStatusInvalidArgument
); 
 853         // do not allow creation of a network service if the interface is a 
 854         // member of a bond or bridge 
 855         if (__SCNetworkInterfaceIsMember(prefs
, interface
)) { 
 856                 _SCErrorSet(kSCStatusKeyExists
); 
 860         // establish the service 
 861         prefix 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 862         path 
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
); 
 863         if (path 
== NULL
) path 
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
); 
 869         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/")); 
 872         serviceID 
= CFArrayGetValueAtIndex(components
, 2); 
 873         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 874         CFRelease(components
); 
 876         // duplicate the interface and associate the copy with the new service 
 877         newInterface 
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, 
 881         servicePrivate
->interface 
= newInterface
; 
 883         // establish "default" configuration(s) for the interface 
 884         for (interface 
= newInterface
; 
 886              interface 
= SCNetworkInterfaceGetInterface(interface
)) { 
 887                 SCNetworkInterfaceRef   childInterface
; 
 888                 CFStringRef             childInterfaceType      
= NULL
; 
 889                 CFDictionaryRef         config
; 
 890                 CFStringRef             interfaceType
; 
 892                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 893                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 894                 if (childInterface 
!= NULL
) { 
 895                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 898                 config 
= __copyInterfaceTemplate(interfaceType
, childInterfaceType
); 
 899                 if (config 
!= NULL
) { 
 900                         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBluetooth
) || 
 901                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeIrDA     
) || 
 902                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem    
) || 
 903                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeSerial   
) || 
 904                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeWWAN     
)) { 
 905                                 CFDictionaryRef         overrides
; 
 907                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypeModem
); 
 909                                 // a ConnectionScript (and related keys) from the interface 
 910                                 // should trump the settings from the configuration template. 
 911                                 if (isA_CFDictionary(overrides
)) { 
 912                                         CFMutableDictionaryRef  newConfig
; 
 914                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 915                                         if (CFDictionaryContainsKey(overrides
, kSCPropNetModemConnectionScript
)) { 
 916                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionPersonality
); 
 917                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionScript
); 
 918                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceVendor
); 
 919                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceModel
); 
 921                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 925                         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
) || 
 926                                    CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
 927                                 CFDictionaryRef         overrides
; 
 929                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypePPP
); 
 930                                 if (isA_CFDictionary(overrides
)) { 
 931                                         CFMutableDictionaryRef  newConfig
; 
 933                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 934                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 940                         if (!__SCNetworkInterfaceSetConfiguration(interface
, NULL
, config
, TRUE
)) { 
 941                                 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL", 
 948         // add the interface [entity] to the service 
 949         (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef
)servicePrivate
, 
 950                                                     servicePrivate
->interface
); 
 952         // push the [deep] interface configuration into the service. 
 953         interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(NULL
, servicePrivate
->interface
); 
 954         __SCNetworkInterfaceSetDeepConfiguration(NULL
, servicePrivate
->interface
, interface_config
); 
 955         if (interface_config 
!= NULL
) CFRelease(interface_config
); 
 957         // set the service name to match that of the associated interface 
 959         // Note: It might seem a bit odd to call SCNetworkServiceGetName 
 960         // followed by an immediate call to SCNetworkServiceSetName.  The 
 961         // trick here is that if no name has previously been set, the 
 962         // "get" function will return the name of the associated interface. 
 964         // ... and we "set" a name to ensure that applications that do 
 965         // not use the APIs will still find a UserDefinedName property 
 966         // in the SCDynamicStore. 
 968         interface_name 
= SCNetworkServiceGetName((SCNetworkServiceRef
)servicePrivate
); 
 969         if (interface_name 
!= NULL
) { 
 970                 (void) SCNetworkServiceSetName((SCNetworkServiceRef
)servicePrivate
, 
 974         SC_log(LOG_DEBUG
, "SCNetworkServiceCreate(): %@", servicePrivate
); 
 976         return (SCNetworkServiceRef
)servicePrivate
; 
 981 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service
) 
 984         SCNetworkInterfaceRef           interface
; 
 987         CFArrayRef                      protocolTypes
; 
 989         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 991         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 992                 _SCErrorSet(kSCStatusInvalidArgument
); 
 996         interface 
= SCNetworkServiceGetInterface(service
); 
 997         if (interface 
== NULL
) { 
1001         protocolTypes 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
1002         n 
= (protocolTypes 
!= NULL
) ? CFArrayGetCount(protocolTypes
) : 0; 
1003         for (i 
= 0; i 
< n
; i
++) { 
1004                 CFStringRef     protocolType
; 
1006                 protocolType 
= CFArrayGetValueAtIndex(protocolTypes
, i
); 
1007                 ok 
= SCNetworkServiceAddProtocolType(service
, protocolType
); 
1010                                "SCNetworkServiceEstablishDefaultConfiguration(): could not add protocol \"%@\"", 
1015         rankStr 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCPropNetServicePrimaryRank
); 
1016         if (isA_CFString(rankStr
)) { 
1017                 SCNetworkServicePrimaryRank     rank
; 
1019                 ok 
= __str_to_rank(rankStr
, &rank
); 
1022                                "SCNetworkServiceEstablishDefaultConfiguration(): unknown rank \"%@\"", 
1027                 ok 
= SCNetworkServiceSetPrimaryRank(service
, rank
); 
1030                                "SCNetworkServiceEstablishDefaultConfiguration(): could not set rank \"%@\"", 
1043 SCNetworkServiceGetEnabled(SCNetworkServiceRef service
) 
1047         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1049         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1050                 _SCErrorSet(kSCStatusInvalidArgument
); 
1054         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1055                                                               servicePrivate
->serviceID
,        // service 
1057         enabled 
= __getPrefsEnabled(servicePrivate
->prefs
, path
); 
1064 SCNetworkInterfaceRef
 
1065 SCNetworkServiceGetInterface(SCNetworkServiceRef service
) 
1067         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1069         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1070                 _SCErrorSet(kSCStatusInvalidArgument
); 
1074         if (servicePrivate
->interface 
== NULL
) { 
1075                 CFDictionaryRef entity
; 
1078                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1079                                                                       servicePrivate
->serviceID
,        // service 
1080                                                                       kSCEntNetInterface
);              // entity 
1081                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1084                 if (isA_CFDictionary(entity
)) { 
1085                         servicePrivate
->interface 
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, service
); 
1089         return servicePrivate
->interface
; 
1094 SCNetworkServiceGetName(SCNetworkServiceRef service
) 
1096         CFDictionaryRef                 entity
; 
1097         SCNetworkInterfaceRef           interface
; 
1098         CFStringRef                     name            
= NULL
; 
1100         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1101         Boolean                         useSystemInterfaces 
= TRUE
; 
1103         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1104                 _SCErrorSet(kSCStatusInvalidArgument
); 
1108         if (servicePrivate
->name 
!= NULL
) { 
1109                 return servicePrivate
->name
; 
1112         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1113                                                               servicePrivate
->serviceID
,        // service 
1115         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1118         useSystemInterfaces 
= ((__SCPreferencesUsingDefaultPrefs(servicePrivate
->prefs
)) && 
1119                                !__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate
->prefs
)); 
1121         if (isA_CFDictionary(entity
)) { 
1122                 name 
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
); 
1123                 if (isA_CFString(name
)) { 
1124                         servicePrivate
->name 
= CFRetain(name
); 
1125                         if (!useSystemInterfaces
) { 
1126                                 return servicePrivate
->name
; 
1131         interface 
= SCNetworkServiceGetInterface(service
); 
1132         while (interface 
!= NULL
) { 
1133                 SCNetworkInterfaceRef   childInterface
; 
1134                 CFStringRef             interfaceType
; 
1136                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1137                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1141                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1142                 if ((childInterface 
== NULL
) || 
1143                     CFEqual(childInterface
, kSCNetworkInterfaceIPv4
)) { 
1147                 interface 
= childInterface
; 
1150         if (interface 
!= NULL
) { 
1152                 CFStringRef     interface_name  
= NULL
; 
1153                 CFStringRef     suffix          
= NULL
; 
1156                 // check if the [stored] service name matches the non-localized interface 
1157                 // name.  If so, return the localized name. 
1159                 // Also, the older "Built-in XXX" interface names are too long for the 
1160                 // current UI. If we find that the [stored] service name matches the older 
1161                 // name, return the newer (and shorter) localized name. 
1163                 // Note: the user/admin will no longer be able to set the service name 
1164                 //       to "Built-in Ethernet". 
1166                 for (i 
= 0; i 
< 3; i
++) { 
1167                         if (servicePrivate
->name 
== NULL
) { 
1168                                 // if no [stored] service name to compare 
1174                                         // compare the non-localized interface name 
1175                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1176                                         if (interface_name 
!= NULL
) { 
1177                                                 CFRetain(interface_name
); 
1180 #if     !TARGET_OS_IPHONE 
1182                                         // compare the older "Built-in XXX" localized name 
1183                                         interface_name 
= __SCNetworkInterfaceCopyXLocalizedDisplayName(interface
); 
1186                                         // compare the older "Built-in XXX" non-localized name 
1187                                         interface_name 
= __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface
); 
1189 #else   // !TARGET_OS_IPHONE 
1192 #endif  // !TARGET_OS_IPHONE 
1195                         if (interface_name 
!= NULL
) { 
1196                                 Boolean match   
= FALSE
; 
1198                                 if (CFEqual(name
, interface_name
)) { 
1199                                         // if service name matches the OLD localized 
1202                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1203                                         CFIndex prefixLen       
= CFStringGetLength(interface_name
); 
1204                                         CFIndex suffixLen       
= CFStringGetLength(name
); 
1206                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1208                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1211                                 CFRelease(interface_name
); 
1214                                         CFRelease(servicePrivate
->name
); 
1215                                         servicePrivate
->name 
= NULL
; 
1222                 // if the service name has not been set, use the localized interface name 
1224                 if (servicePrivate
->name 
== NULL
) { 
1225                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1226                         if (interface_name 
!= NULL
) { 
1227                                 if (suffix 
!= NULL
) { 
1228                                         servicePrivate
->name 
= CFStringCreateWithFormat(NULL
, 
1234                                         servicePrivate
->name 
= CFRetain(interface_name
); 
1238                 if (suffix 
!= NULL
) CFRelease(suffix
); 
1241         return servicePrivate
->name
; 
1246 SCNetworkServiceGetServiceID(SCNetworkServiceRef service
) 
1248         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1250         if (!isA_SCNetworkService(service
)) { 
1251                 _SCErrorSet(kSCStatusInvalidArgument
); 
1255         return servicePrivate
->serviceID
; 
1260 SCNetworkServiceGetTypeID(void) 
1262         pthread_once(&initialized
, __SCNetworkServiceInitialize
);       /* initialize runtime */ 
1263         return __kSCNetworkServiceTypeID
; 
1268 SCNetworkServiceRemove(SCNetworkServiceRef service
) 
1272         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1275         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1276                 _SCErrorSet(kSCStatusInvalidArgument
); 
1280         if (!__SCNetworkServiceExists(service
)) { 
1281                 SC_log(LOG_ERR
, "SCNetworkServiceRemove() w/removed service\n  service = %@", service
); 
1282                 _SC_crash_once("SCNetworkServiceRemove() w/removed service", NULL
, NULL
); 
1283                 _SCErrorSet(kSCStatusInvalidArgument
); 
1287         // remove service from all sets 
1289         sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1293                 n 
= CFArrayGetCount(sets
); 
1294                 for (CFIndex i 
= 0; i 
< n
; i
++) { 
1295                         SCNetworkSetRef set
; 
1297                         set 
= CFArrayGetValueAtIndex(sets
, i
); 
1298                         ok 
= SCNetworkSetRemoveService(set
, service
); 
1299                         if (!ok 
&& (SCError() != kSCStatusNoKey
)) { 
1309         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1310                                                               servicePrivate
->serviceID
,        // service 
1312         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1316                 SC_log(LOG_DEBUG
, "SCNetworkServiceRemove(): %@", service
); 
1324 SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
1326         CFDictionaryRef                 entity
; 
1329         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1331         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1332                 _SCErrorSet(kSCStatusInvalidArgument
); 
1336         if (!__SCNetworkServiceExists(service
)) { 
1337                 SC_log(LOG_ERR
, "SCNetworkServiceRemoveProtocolType() w/removed service\n  service = %@\n  protocol = %@", 
1340                 _SC_crash_once("SCNetworkServiceRemoveProtocolType() w/removed service", NULL
, NULL
); 
1341                 _SCErrorSet(kSCStatusInvalidArgument
); 
1345         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
1346                 _SCErrorSet(kSCStatusInvalidArgument
); 
1350         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1351                                                               servicePrivate
->serviceID
,        // service 
1352                                                               protocolType
);                    // entity 
1354         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1355         if (entity 
== NULL
) { 
1356                 // if "protocol" does not exist 
1357                 _SCErrorSet(kSCStatusNoKey
); 
1361         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1366                 SC_log(LOG_DEBUG
, "SCNetworkServiceRemoveProtocolType(): %@, %@", service
, protocolType
); 
1375 SCNetworkServiceSetEnabled(SCNetworkServiceRef service
, Boolean enabled
) 
1379         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1381         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1382                 _SCErrorSet(kSCStatusInvalidArgument
); 
1386         if (!__SCNetworkServiceExists(service
)) { 
1387                 SC_log(LOG_ERR
, "SCNetworkServiceSetEnabled() w/removed service\n  service = %@", service
); 
1388                 _SC_crash_once("SCNetworkProtocolSetEnabled() w/removed service", NULL
, NULL
); 
1389                 _SCErrorSet(kSCStatusInvalidArgument
); 
1393         // make sure that we do not enable a network service if the 
1394         // associated interface is a member of a bond or bridge. 
1396                 SCNetworkInterfaceRef   interface
; 
1398                 interface 
= SCNetworkServiceGetInterface(service
); 
1399                 if ((interface 
!= NULL
) && 
1400                     __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) { 
1401                         _SCErrorSet(kSCStatusKeyExists
); 
1406         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1407                                                               servicePrivate
->serviceID
,        // service 
1409         ok 
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
); 
1413                 SC_log(LOG_DEBUG
, "SCNetworkServiceSetEnabled(): %@ -> %s", 
1415                        enabled 
? "Enabled" : "Disabled"); 
1423 SCNetworkServiceSetName(SCNetworkServiceRef service
, CFStringRef name
) 
1425         CFDictionaryRef                 entity
; 
1428         CFStringRef                     saveName        
= NULL
; 
1429         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1431         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1432                 _SCErrorSet(kSCStatusInvalidArgument
); 
1436         if (!__SCNetworkServiceExists(service
)) { 
1437                 SC_log(LOG_ERR
, "SCNetworkServiceSetName() w/removed service\n  service = %@\n  name = %@", 
1439                        name 
!= NULL 
? name 
: CFSTR("<NULL>")); 
1440                 _SC_crash_once("SCNetworkServiceSetName() w/removed service", NULL
, NULL
); 
1441                 _SCErrorSet(kSCStatusInvalidArgument
); 
1446                 if (!isA_CFString(name
)) { 
1447                         _SCErrorSet(kSCStatusInvalidArgument
); 
1450                 saveName 
= CFRetain(name
); 
1454                 SCNetworkInterfaceRef   interface
; 
1456                 interface 
= SCNetworkServiceGetInterface(service
); 
1457                 while (interface 
!= NULL
) { 
1458                         SCNetworkInterfaceRef   childInterface
; 
1460                         childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1461                         if (childInterface 
== NULL
) { 
1465                         interface 
= childInterface
; 
1468                 if (interface 
!= NULL
) { 
1469                         CFStringRef     interface_name
; 
1471                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1472                         if (interface_name 
!= NULL
) { 
1473                                 if (CFEqual(name
, interface_name
)) { 
1474                                         // if service name matches the localized interface name 
1475                                         // then store the non-localized name. 
1476                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1477                                         if (interface_name 
!= NULL
) { 
1478                                                 CFRelease(saveName
); 
1479                                                 saveName 
= CFRetain(interface_name
); 
1481                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1482                                         CFIndex         prefixLen       
= CFStringGetLength(interface_name
); 
1484                                         CFIndex         suffixLen       
= CFStringGetLength(name
); 
1486                                         // if service name matches the localized interface name plus 
1487                                         // a few extra characters) then store the non-localized name with 
1489                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1491                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1492                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1493                                         if (interface_name 
!= NULL
) { 
1494                                                 CFRelease(saveName
); 
1495                                                 saveName 
= CFStringCreateWithFormat(NULL
, 
1507 #define PREVENT_DUPLICATE_SERVICE_NAMES 
1508 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
1512                 // ensure that each service is uniquely named within its sets 
1514                 sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1519                         set_count 
= CFArrayGetCount(sets
); 
1520                         for (set_index 
= 0; set_index 
< set_count
; set_index
++) { 
1521                                 CFIndex         service_index
; 
1522                                 Boolean         isDup           
= FALSE
; 
1523                                 Boolean         isMember        
= FALSE
; 
1524                                 CFIndex         service_count
; 
1525                                 CFArrayRef      services
; 
1526                                 SCNetworkSetRef set             
= CFArrayGetValueAtIndex(sets
, set_index
); 
1528                                 services 
= SCNetworkSetCopyServices(set
); 
1530                                 service_count 
= CFArrayGetCount(services
); 
1531                                 for (service_index 
= 0; service_index 
< service_count
; service_index
++) { 
1532                                         CFStringRef             otherID
; 
1533                                         CFStringRef             otherName
; 
1534                                         SCNetworkServiceRef     otherService
; 
1536                                         otherService 
= CFArrayGetValueAtIndex(services
, service_index
); 
1538                                         otherID 
= SCNetworkServiceGetServiceID(otherService
); 
1539                                         if (CFEqual(servicePrivate
->serviceID
, otherID
)) { 
1540                                                 // if the service is a member of this set 
1545                                         otherName 
= SCNetworkServiceGetName(otherService
); 
1546                                         if ((otherName 
!= NULL
) && CFEqual(name
, otherName
)) { 
1552                                 CFRelease(services
); 
1554                                 if (isMember 
&& isDup
) { 
1556                                          * if this service is a member of the set and 
1557                                          * the "name" is not unique. 
1560                                         if (saveName 
!= NULL
) CFRelease(saveName
); 
1561                                         _SCErrorSet(kSCStatusKeyExists
); 
1569 #endif  /* PREVENT_DUPLICATE_SERVICE_NAMES */ 
1571         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1572                                                               servicePrivate
->serviceID
,        // service 
1574         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1575         if (isA_CFDictionary(entity
) || 
1576             ((entity 
== NULL
) && (name 
!= NULL
))) { 
1577                 CFMutableDictionaryRef  newEntity
; 
1579                 if (entity 
!= NULL
) { 
1580                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1582                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1584                                                               &kCFTypeDictionaryKeyCallBacks
, 
1585                                                               &kCFTypeDictionaryValueCallBacks
); 
1587                 if (saveName 
!= NULL
) { 
1588                         CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, saveName
); 
1590                         CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
); 
1592                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1593                 CFRelease(newEntity
); 
1596         if (saveName 
!= NULL
) CFRelease(saveName
); 
1598         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
1599         if (name 
!= NULL
) CFRetain(name
); 
1600         servicePrivate
->name 
= name
; 
1603                 SC_log(LOG_DEBUG
, "SCNetworkServiceSetName(): %@", service
); 
1611 #pragma mark SCNetworkService SPIs 
1616 __SCNetworkServiceExists(SCNetworkServiceRef service
) 
1618         CFDictionaryRef                 entity
; 
1620         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1622         if (servicePrivate
->prefs 
== NULL
) { 
1627         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1628                                                               servicePrivate
->serviceID
,        // service 
1629                                                               kSCEntNetInterface
);               // entity 
1630         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1633         if (!isA_CFDictionary(entity
)) { 
1634                 // a "service" must have an "interface" 
1642 SCNetworkServicePrimaryRank
 
1643 SCNetworkServiceGetPrimaryRank(SCNetworkServiceRef service
) 
1645         CFDictionaryRef                 entity
; 
1648         SCNetworkServicePrimaryRank     rank            
= kSCNetworkServicePrimaryRankDefault
; 
1649         CFStringRef                     rankStr         
= NULL
; 
1650         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1652         if (!isA_SCNetworkService(service
)) { 
1653                 _SCErrorSet(kSCStatusInvalidArgument
); 
1657         if (servicePrivate
->prefs 
!= NULL
) { 
1658                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1659                                                                       servicePrivate
->serviceID
, 
1661                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1663                 if (isA_CFDictionary(entity
)) { 
1664                         rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1665                         ok 
= __str_to_rank(rankStr
, &rank
); 
1667         } else if (servicePrivate
->store 
!= NULL
) { 
1668                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1669                                                                    kSCDynamicStoreDomainState
, 
1670                                                                    servicePrivate
->serviceID
, 
1672                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1674                 if (entity 
!= NULL
) { 
1675                         if (isA_CFDictionary(entity
)) { 
1676                                 rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1677                                 ok 
= __str_to_rank(rankStr
, &rank
); 
1682                 _SCErrorSet(kSCStatusInvalidArgument
); 
1687                 rank 
= kSCNetworkServicePrimaryRankDefault
; 
1688                 _SCErrorSet(kSCStatusInvalidArgument
); 
1689         } else if (rank 
== kSCNetworkServicePrimaryRankDefault
) { 
1690                 _SCErrorSet(kSCStatusOK
); 
1698 SCNetworkServiceSetPrimaryRank(SCNetworkServiceRef              service
, 
1699                                SCNetworkServicePrimaryRank      newRank
) 
1702         CFDictionaryRef                 entity
; 
1703         CFMutableDictionaryRef          newEntity
; 
1704         CFStringRef                     path            
= NULL
; 
1705         CFStringRef                     rankStr         
= NULL
; 
1706         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1708         if (!isA_SCNetworkService(service
)) { 
1709                 _SCErrorSet(kSCStatusInvalidArgument
); 
1713         if ((servicePrivate
->prefs 
!= NULL
) && !__SCNetworkServiceExists(service
)) { 
1714                 SC_log(LOG_ERR
, "SCNetworkServiceSetPrimaryRank() w/removed\n  service = %@", service
); 
1715                 _SC_crash_once("SCNetworkServiceSetPrimaryRank() w/removed service", NULL
, NULL
); 
1716                 _SCErrorSet(kSCStatusInvalidArgument
); 
1720         ok 
= __rank_to_str(newRank
, &rankStr
); 
1722                 _SCErrorSet(kSCStatusInvalidArgument
); 
1726         if (servicePrivate
->prefs 
!= NULL
) { 
1728                 case kSCNetworkServicePrimaryRankDefault
: 
1729                 case kSCNetworkServicePrimaryRankNever
: 
1730                 case kSCNetworkServicePrimaryRankScoped
: 
1731                         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1732                                                                               servicePrivate
->serviceID
, 
1734                         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1735                         if (entity 
!= NULL
) { 
1736                                 if (!isA_CFDictionary(entity
)) { 
1738                                         _SCErrorSet(kSCStatusFailed
); 
1741                                 newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1743                                 newEntity 
= CFDictionaryCreateMutable(NULL
, 
1745                                                                       &kCFTypeDictionaryKeyCallBacks
, 
1746                                                                       &kCFTypeDictionaryValueCallBacks
); 
1748                         if (rankStr 
!= NULL
) { 
1749                                 CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1751                                 CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1753                         if (CFDictionaryGetCount(newEntity
) > 0) { 
1754                                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1756                                 ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1758                         CFRelease(newEntity
); 
1764                         _SCErrorSet(kSCStatusInvalidArgument
); 
1767         } else if (servicePrivate
->store 
!= NULL
) { 
1768                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1769                                                                    kSCDynamicStoreDomainState
, 
1770                                                                    servicePrivate
->serviceID
, 
1772                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1773                 if (entity 
!= NULL
) { 
1774                         if (!isA_CFDictionary(entity
)) { 
1777                                 _SCErrorSet(kSCStatusFailed
); 
1780                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1783                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1785                                                               &kCFTypeDictionaryKeyCallBacks
, 
1786                                                               &kCFTypeDictionaryValueCallBacks
); 
1788                 if (rankStr 
!= NULL
) { 
1789                         CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1791                         CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1793                 if (CFDictionaryGetCount(newEntity
) > 0) { 
1794                         ok 
= SCDynamicStoreSetValue(servicePrivate
->store
, path
, newEntity
); 
1796                         ok 
= SCDynamicStoreRemoveValue(servicePrivate
->store
, path
); 
1798                 CFRelease(newEntity
); 
1803                 _SCErrorSet(kSCStatusInvalidArgument
); 
1809         if (path 
!= NULL
)       CFRelease(path
); 
1815 _SCNetworkServiceIsVPN(SCNetworkServiceRef service
) 
1817         SCNetworkInterfaceRef   interface
; 
1818         CFStringRef             interfaceType
; 
1820         interface 
= SCNetworkServiceGetInterface(service
); 
1821         if (interface 
== NULL
) { 
1825         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1826         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
1827                 interface 
= SCNetworkInterfaceGetInterface(interface
); 
1828                 if (interface 
== NULL
) { 
1832                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1833                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
1836 #pragma GCC diagnostic push 
1837 #pragma GCC diagnostic ignored "-Wdeprecated" 
1838                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) { 
1841 #pragma GCC diagnostic pop 
1842         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1844         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) { 
1853 SCNetworkServiceSetExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
, CFStringRef identifier
) 
1855         CFStringRef                     prefs_path
; 
1856         CFDictionaryRef                 service_dictionary
; 
1857         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
1858         Boolean                         success                 
= FALSE
; 
1859         CFStringRef                     prefixed_domain
; 
1861         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
) || !isA_CFString(identifierDomain
)) { 
1862                 _SCErrorSet(kSCStatusInvalidArgument
); 
1866         if (!__SCNetworkServiceExists(service
)) { 
1867                 SC_log(LOG_ERR
, "SCNetworkServiceSetExternalID() w/removed\n  service = %@\n  id = %@", 
1870                 _SC_crash_once("SCNetworkServiceSetExternalID() w/removed service", NULL
, NULL
); 
1871                 _SCErrorSet(kSCStatusInvalidArgument
); 
1875         if (identifier 
!= NULL 
&& !isA_CFString(identifier
)) { 
1876                 _SCErrorSet(kSCStatusInvalidArgument
); 
1880         prefixed_domain 
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
); 
1882         prefs_path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1883                                                                     servicePrivate
->serviceID
, 
1886         service_dictionary 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, prefs_path
); 
1887         if (isA_CFDictionary(service_dictionary
) || ((service_dictionary 
== NULL
) && (identifier 
!= NULL
))) { 
1888                 CFMutableDictionaryRef  new_service_dictionary
; 
1890                 if (service_dictionary 
!= NULL
) { 
1891                         new_service_dictionary 
= CFDictionaryCreateMutableCopy(NULL
, 0, service_dictionary
); 
1893                         new_service_dictionary 
= CFDictionaryCreateMutable(NULL
, 
1895                                                                            &kCFTypeDictionaryKeyCallBacks
, 
1896                                                                            &kCFTypeDictionaryValueCallBacks
); 
1899                 if (identifier 
!= NULL
) { 
1900                         CFDictionarySetValue(new_service_dictionary
, prefixed_domain
, identifier
); 
1902                         CFDictionaryRemoveValue(new_service_dictionary
, prefixed_domain
); 
1904                 success 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, prefs_path
, new_service_dictionary
); 
1905                 CFRelease(new_service_dictionary
); 
1907         CFRelease(prefs_path
); 
1909         if (identifier 
!= NULL
) { 
1910             if (servicePrivate
->externalIDs 
== NULL
) { 
1911                         servicePrivate
->externalIDs 
= CFDictionaryCreateMutable(NULL
, 
1913                                                                                  &kCFTypeDictionaryKeyCallBacks
, 
1914                                                                                  &kCFTypeDictionaryValueCallBacks
); 
1916             CFDictionarySetValue(servicePrivate
->externalIDs
, prefixed_domain
, identifier
); 
1918             if (servicePrivate
->externalIDs 
!= NULL
) { 
1919                         CFDictionaryRemoveValue(servicePrivate
->externalIDs
, prefixed_domain
); 
1923         CFRelease(prefixed_domain
); 
1926                 _SCErrorSet(kSCStatusFailed
); 
1934 SCNetworkServiceCopyExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
) 
1936         CFStringRef                     identifier              
= NULL
; 
1937         CFStringRef                     prefixed_domain
; 
1938         SCNetworkServicePrivateRef      service_private         
= (SCNetworkServicePrivateRef
)service
; 
1940         if (!isA_SCNetworkService(service
) || (service_private
->prefs 
== NULL
) || !isA_CFString(identifierDomain
)) { 
1941                 _SCErrorSet(kSCStatusInvalidArgument
); 
1945         prefixed_domain 
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
); 
1947         if (service_private
->externalIDs 
!= NULL
) { 
1948                 identifier 
= CFDictionaryGetValue(service_private
->externalIDs
, prefixed_domain
); 
1949                 if (identifier 
!= NULL
) { 
1950                         CFRetain(identifier
); 
1954         if (identifier 
== NULL
) { 
1955                 CFStringRef             prefs_path
; 
1956                 CFDictionaryRef         service_dictionary
; 
1958                 prefs_path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1959                                                                             service_private
->serviceID
, 
1962                 service_dictionary 
= SCPreferencesPathGetValue(service_private
->prefs
, prefs_path
); 
1963                 if (isA_CFDictionary(service_dictionary
)) { 
1964                         identifier 
= CFDictionaryGetValue(service_dictionary
, prefixed_domain
); 
1965                         if (identifier 
!= NULL
) { 
1966                                 CFRetain(identifier
); 
1967                                 if (service_private
->externalIDs 
== NULL
) { 
1968                                         service_private
->externalIDs 
= CFDictionaryCreateMutable(NULL
, 
1970                                                                                                  &kCFTypeDictionaryKeyCallBacks
, 
1971                                                                                                  &kCFTypeDictionaryValueCallBacks
); 
1973                                 CFDictionarySetValue(service_private
->externalIDs
, prefixed_domain
, identifier
); 
1976                 CFRelease(prefs_path
); 
1979         CFRelease(prefixed_domain
); 
1981         if (identifier 
== NULL
) { 
1982                 _SCErrorSet(kSCStatusNoKey
); 
1990         CFStringRef     oldServiceID
; 
1991         CFStringRef     newServiceID
; 
1992 } serviceContext
, *serviceContextRef
; 
1996 replaceServiceID(const void *value
, void *context
) 
1998         CFStringRef             link            
= NULL
; 
1999         CFStringRef             oldLink
; 
2000         CFMutableArrayRef       newServiceOrder
; 
2002         serviceContextRef       service_context 
= (serviceContextRef
)context
; 
2003         CFArrayRef              serviceOrder    
= NULL
; 
2004         SCNetworkSetRef         set             
= (SCNetworkSetRef
)value
; 
2005         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
2007         // update service order 
2008         serviceOrder 
= SCNetworkSetGetServiceOrder(set
); 
2009         if ((isA_CFArray(serviceOrder
) != NULL
) && 
2010             CFArrayContainsValue(serviceOrder
, 
2011                                   CFRangeMake(0, CFArrayGetCount(serviceOrder
)), 
2012                                   service_context
->oldServiceID
)) { 
2014                 CFIndex serviceOrderIndex
; 
2016                 // replacing all instances of old service ID with new one 
2017                 newServiceOrder 
= CFArrayCreateMutableCopy(NULL
, 0, serviceOrder
); 
2018                 count 
= CFArrayGetCount(newServiceOrder
); 
2019                 for (serviceOrderIndex 
= 0; serviceOrderIndex 
< count
; serviceOrderIndex
++) { 
2020                         CFStringRef     serviceID
; 
2022                         serviceID 
= CFArrayGetValueAtIndex(newServiceOrder
, serviceOrderIndex
); 
2023                         if (CFEqual(serviceID
, service_context
->oldServiceID
)) { 
2024                                 CFArraySetValueAtIndex(newServiceOrder
, serviceOrderIndex
, service_context
->newServiceID
); 
2027                 SCNetworkSetSetServiceOrder(set
, newServiceOrder
); 
2028                 CFRelease(newServiceOrder
); 
2031         // check if service with old serviceID is part of the set 
2032         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
2033                                                                  setPrivate
->setID
,             // set 
2034                                                                  service_context
->oldServiceID
, // service 
2036         oldLink 
= SCPreferencesPathGetLink(setPrivate
->prefs
, path
); 
2037         if (oldLink 
== NULL
) { 
2038                 // don't make any changes if service with old serviceID is not found 
2042         // remove link between "set" and old "service" 
2043         (void) SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
2046         // create the link between "set" and the "service" 
2047         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
2048                                                                  setPrivate
->setID
,             // set 
2049                                                                  service_context
->newServiceID
, // service 
2051         link 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
2052                                                               service_context
->newServiceID
,    // service 
2054         (void) SCPreferencesPathSetLink(setPrivate
->prefs
, path
, link
); 
2070 _SCNetworkServiceSetServiceID(SCNetworkServiceRef service
, CFStringRef newServiceID
) 
2072         CFArrayRef                      allSets         
= NULL
; 
2073         CFDictionaryRef                 entity
; 
2074         CFStringRef                     newPath
; 
2076         CFStringRef                     oldPath         
= NULL
; 
2077         serviceContext                  service_context
; 
2078         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
2080         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
2081                 _SCErrorSet(kSCStatusInvalidArgument
); 
2085         if (!isA_CFString(newServiceID
)) { 
2086                 _SCErrorSet(kSCStatusInvalidArgument
); 
2090         if (CFEqual(newServiceID
, servicePrivate
->serviceID
)) { 
2091                 // no work needs to be done if new service ID is equal to current service ID 
2095         if (!__SCNetworkServiceExists(service
)) { 
2096                 SC_log(LOG_ERR
, "_SCNetworkServiceSetServiceID() w/removed service\n  service = %@\n  serviceID = %@", 
2099                 _SC_crash_once("_SCNetworkServiceSetServiceID() w/removed service", NULL
, NULL
); 
2100                 _SCErrorSet(kSCStatusInvalidArgument
); 
2104         newPath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                          // allocator 
2105                                                                  newServiceID
,                  // service 
2107         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, newPath
); 
2108         if (isA_CFDictionary(entity
)) { 
2109                 // if the new service already exists 
2110                 _SCErrorSet(kSCStatusKeyExists
); 
2114         oldPath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                          // allocator 
2115                                                                  servicePrivate
->serviceID
,     // service 
2117         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, oldPath
); 
2118         if (!isA_CFDictionary(entity
)) { 
2119                 // if the service has already been removed 
2120                 _SCErrorSet(kSCStatusNoKey
); 
2124         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, newPath
, entity
); 
2127         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, oldPath
); 
2130         allSets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
2132         service_context
.newServiceID 
= newServiceID
; 
2133         service_context
.oldServiceID 
= servicePrivate
->serviceID
; 
2135         // find all sets w/oldServiceID and update 
2136         // ... and update the serviceOrder 
2137         CFArrayApplyFunction(allSets
, 
2138                              CFRangeMake(0, CFArrayGetCount(allSets
)), 
2142         if (servicePrivate
->interface 
!= NULL
) { 
2143                 SCNetworkInterfaceRef           newInterface
; 
2145                 // duplicate the interface and associate the copy with the new service ID 
2146                 newInterface 
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, 
2147                                                                                      servicePrivate
->interface
, 
2148                                                                                      servicePrivate
->prefs
, 
2150                 CFRelease(servicePrivate
->interface
); 
2151                 servicePrivate
->interface 
= newInterface
; 
2154         SC_log(LOG_DEBUG
, "_SCNetworkServiceSetServiceID(): %@ --> %@", service
, newServiceID
); 
2156         // replace serviceID with new one 
2157         CFRetain(newServiceID
); 
2158         CFRelease(servicePrivate
->serviceID
); 
2159         servicePrivate
->serviceID 
= newServiceID
; 
2163         if (oldPath 
!= NULL
) { 
2166         if (newPath 
!= NULL
) { 
2169         if (allSets 
!= NULL
) { 
2176 #define kVPNProtocolPayloadInfo                 CFSTR("com.apple.payload") 
2177 #define kSCEntNetLoginWindowEAPOL               CFSTR("EAPOL.LoginWindow") 
2180 copyInterfaceConfiguration(SCNetworkServiceRef oldService
, SCNetworkServiceRef newService
) 
2182         SCNetworkInterfaceRef   oldInterface
; 
2183         SCNetworkInterfaceRef   newInterface
; 
2185         oldInterface 
= SCNetworkServiceGetInterface(oldService
); 
2186         newInterface 
= SCNetworkServiceGetInterface(newService
); 
2188         while (oldInterface 
!= NULL
) { 
2189                 CFDictionaryRef configuration
; 
2190                 CFStringRef             interfaceType
; 
2192                 if (newInterface 
== NULL
) { 
2193                         // oops ... interface layering does not match 
2197                 // copy interface configuration 
2198                 configuration 
= SCNetworkInterfaceGetConfiguration(oldInterface
); 
2200                 if ((configuration 
!= NULL
) || 
2201                     (SCError() == kSCStatusOK
)) { 
2202                         if (!SCNetworkInterfaceSetConfiguration(newInterface
, configuration
)) { 
2203                                 SC_log(LOG_INFO
, "problem setting interface configuration"); 
2208                 // special case: PPP/L2TP + IPSec 
2209                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(oldInterface
); 
2210                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
2211                         SCNetworkInterfaceRef   childInterface
; 
2213                         childInterface 
= SCNetworkInterfaceGetInterface(oldInterface
); 
2214                         if (childInterface 
!= NULL
) { 
2215                                 CFStringRef             childInterfaceType
; 
2217                                 childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
2219                                 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
2220                                         configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetIPSec
); 
2221                                         if ((configuration 
!= NULL
) || 
2222                                             (SCError() == kSCStatusOK
)) { 
2223                                                 if (!SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetIPSec
, configuration
)) { 
2224                                                         SC_log(LOG_INFO
, "problem setting child interface configuration"); 
2231                 // special case: 802.1x 
2232                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetEAPOL
); 
2233                 if ((configuration 
!= NULL
) || 
2234                     (SCError() == kSCStatusOK
)) { 
2235                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetEAPOL
, configuration
); 
2238                 // special case: Managed Client 
2239                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kVPNProtocolPayloadInfo
); 
2240                 if ((configuration 
!= NULL
) || 
2241                     (SCError() == kSCStatusOK
)) { 
2242                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kVPNProtocolPayloadInfo
, configuration
); 
2245                 // special case: Network Pref 
2246                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCValNetPPPAuthProtocolEAP
); 
2247                 if ((configuration 
!= NULL
) || 
2248                     (SCError() == kSCStatusOK
)) { 
2249                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCValNetPPPAuthProtocolEAP
, configuration
); 
2252                 // special case: Remote Pref 
2253                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetLoginWindowEAPOL
); 
2254                 if ((configuration 
!= NULL
) || 
2255                     (SCError() == kSCStatusOK
)) { 
2256                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetLoginWindowEAPOL
, configuration
); 
2259                 // special case: Network Extension 
2260                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCNetworkInterfaceTypeIPSec
); 
2261                 if ((configuration 
!= NULL
) || 
2262                     (SCError() == kSCStatusOK
)) { 
2263                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCNetworkInterfaceTypeIPSec
, configuration
); 
2266                 oldInterface 
= SCNetworkInterfaceGetInterface(oldInterface
); 
2267                 newInterface 
= SCNetworkInterfaceGetInterface(newInterface
); 
2275 __SCNetworkServiceAddProtocolToService(SCNetworkServiceRef service
, CFStringRef protocolType
, CFDictionaryRef configuration
, Boolean enabled
) 
2278         SCNetworkProtocolRef protocol
; 
2280         protocol 
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
2282         if ((protocol 
== NULL
) && 
2283             (SCError() == kSCStatusNoKey
)) { 
2284                 ok 
= SCNetworkServiceAddProtocolType(service
, protocolType
); 
2286                         protocol 
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
2289         if (protocol 
!= NULL
) { 
2290                 SCNetworkProtocolSetConfiguration(protocol
, configuration
); 
2291                 SCNetworkProtocolSetEnabled(protocol
, enabled
); 
2292                 CFRelease(protocol
); 
2301 __SCNetworkServiceMigrateNew(SCPreferencesRef           prefs
, 
2302                              SCNetworkServiceRef        service
, 
2303                              CFDictionaryRef            bsdMapping
, 
2304                              CFDictionaryRef            setMapping
, 
2305                              CFDictionaryRef            serviceSetMapping
) 
2307         CFStringRef deviceName 
= NULL
; 
2309         SCNetworkInterfaceRef interface 
= NULL
; 
2310         CFDictionaryRef interfaceEntity 
= NULL
; 
2311         CFMutableDictionaryRef interfaceEntityMutable 
= NULL
; 
2312         SCNetworkSetRef newSet 
= NULL
; 
2313         SCPreferencesRef ni_prefs 
= NULL
; 
2314         SCNetworkInterfaceRef ni_interface 
= NULL
; 
2315         SCNetworkInterfaceRef oldInterface 
= NULL
; 
2316         SCNetworkSetRef oldSet 
= NULL
; 
2317         SCNetworkServiceRef newService 
= NULL
; 
2318         CFStringRef serviceID 
= NULL
; 
2319         SCNetworkServicePrivateRef servicePrivate 
= (SCNetworkServicePrivateRef
) service
; 
2320         CFArrayRef setList 
= NULL
; 
2321         Boolean success 
= FALSE
; 
2322         CFStringRef targetDeviceName 
= NULL
; 
2323         CFStringRef userDefinedName 
= NULL
; 
2324         CFStringRef userDefinedNameInterface 
= NULL
; 
2325         CFArrayRef protocols 
= NULL
; 
2326         CFStringRef subType
; 
2328         if ((isA_SCNetworkService(service
) == NULL
) || 
2329         (isA_SCNetworkInterface(servicePrivate
->interface
) == NULL
) || 
2330         (servicePrivate
->prefs 
== NULL
)) { 
2333         serviceID 
= servicePrivate
->serviceID
; 
2335         newService 
= SCNetworkServiceCopy(prefs
, serviceID
); 
2336         if (newService 
!= NULL
) { 
2337                 // Cannot add service if it already exists 
2338                 SC_log(LOG_INFO
, "Service already exists"); 
2342         oldInterface 
= SCNetworkServiceGetInterface(service
); 
2343         interfaceEntity 
= __SCNetworkInterfaceCopyInterfaceEntity(oldInterface
); 
2344         if (interfaceEntity 
== NULL
) { 
2345                 SC_log(LOG_INFO
, "No interface entity"); 
2348         interfaceEntityMutable 
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceEntity
); 
2350         if (isA_CFDictionary(bsdMapping
) != NULL
) { 
2351                 deviceName 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
); 
2352                 if (isA_CFString(deviceName
) != NULL
) { 
2353                         targetDeviceName 
= CFDictionaryGetValue(bsdMapping
, deviceName
); 
2354                         if (targetDeviceName 
!= NULL
) { 
2356                                 CFDictionarySetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
, targetDeviceName
); 
2357                                 ni_prefs 
= __SCPreferencesCreateNIPrefsFromPrefs(prefs
); 
2358                                 ni_interface 
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ni_prefs
, targetDeviceName
); 
2359                                 if (ni_interface 
!= NULL
) { 
2360                                         userDefinedNameInterface 
= __SCNetworkInterfaceGetUserDefinedName(ni_interface
); 
2364                 if (userDefinedNameInterface 
== NULL
) { 
2365                         userDefinedNameInterface 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropUserDefinedName
); 
2368         subType 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceSubType
); 
2369         interface 
= _SCNetworkInterfaceCreateWithEntity(NULL
, interfaceEntityMutable
, NULL
); 
2370         if (userDefinedNameInterface 
!= NULL
) { 
2371                 __SCNetworkInterfaceSetUserDefinedName(interface
, userDefinedNameInterface
); 
2373         // Supporting PPPoE subtype 
2374         if (subType 
!= NULL 
&& 
2375             CFEqual(subType
, kSCValNetInterfaceSubTypePPPoE
)) { 
2376                 SCNetworkInterfaceRef childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
2377                 if (childInterface 
!= NULL
) { 
2378                         __SCNetworkInterfaceSetUserDefinedName(childInterface
, userDefinedNameInterface
); 
2381         newService 
= SCNetworkServiceCreate(prefs
, interface
); 
2382         if (newService 
== NULL
) { 
2383                 SC_log(LOG_INFO
, "SCNetworkServiceCreate() failed"); 
2387         enabled 
= SCNetworkServiceGetEnabled(service
); 
2388         if (!SCNetworkServiceSetEnabled(newService
, enabled
)) { 
2389                 SCNetworkServiceRemove(newService
); 
2390                 SC_log(LOG_INFO
, "SCNetworkServiceSetEnabled() failed"); 
2394         if (!SCNetworkServiceEstablishDefaultConfiguration(newService
)) { 
2395                 SCNetworkServiceRemove(newService
); 
2396                 SC_log(LOG_INFO
, "SCNetworkServiceEstablishDefaultConfiguration() failed"); 
2401         _SCNetworkServiceSetServiceID(newService
, serviceID
); 
2403         userDefinedName 
= SCNetworkServiceGetName(service
); 
2404         if ((userDefinedName 
!= NULL
) && 
2405             !SCNetworkServiceSetName(newService
, userDefinedName
)) { 
2406                 SC_log(LOG_INFO
, "SCNetworkServiceSetName(, %@) failed", userDefinedName
); 
2409         // Determine which sets to add service 
2410         if (setMapping 
!= NULL 
&& 
2411             serviceSetMapping 
!= NULL
) { 
2412                 setList 
= CFDictionaryGetValue(serviceSetMapping
, service
); 
2413                 if (setList 
!= NULL
) { 
2414                         for (CFIndex idx 
= 0; idx 
< CFArrayGetCount(setList
); idx
++) { 
2415                                 oldSet 
= CFArrayGetValueAtIndex(setList
, idx
); 
2416                                 newSet 
= CFDictionaryGetValue(setMapping
, oldSet
); 
2417                                 if (newSet 
== NULL
) { 
2421                                 if (!SCNetworkSetAddService(newSet
, newService
)) { 
2422                                         SC_log(LOG_INFO
, "SCNetworkSetAddService() failed"); 
2428         protocols 
= SCNetworkServiceCopyProtocols(service
); 
2429         if (protocols 
!= NULL
) { 
2431                 for (CFIndex idx 
= 0; idx 
< CFArrayGetCount(protocols
); idx
++) { 
2432                         SCNetworkProtocolRef protocol 
= CFArrayGetValueAtIndex(protocols
, idx
); 
2433                         CFDictionaryRef configuration 
= SCNetworkProtocolGetConfiguration(protocol
); 
2434                         CFStringRef protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
2435                         enabled 
= SCNetworkProtocolGetEnabled(protocol
); 
2436                         __SCNetworkServiceAddProtocolToService(newService
, protocolType
, configuration
, enabled
); 
2438                 CFRelease(protocols
); 
2441         copyInterfaceConfiguration(service
, newService
); 
2445         if (interface 
!= NULL
) { 
2446                 CFRelease(interface
); 
2448         if (interfaceEntity 
!= NULL
) { 
2449                 CFRelease(interfaceEntity
); 
2451         if (interfaceEntityMutable 
!= NULL
) { 
2452                 CFRelease(interfaceEntityMutable
); 
2454         if (newService 
!= NULL
) { 
2455                 CFRelease(newService
); 
2457         if (ni_prefs 
!= NULL
) { 
2458                 CFRelease(ni_prefs
); 
2460         if (ni_interface 
!= NULL
) { 
2461                 CFRelease(ni_interface
); 
2469 __SCNetworkServiceCreate(SCPreferencesRef       prefs
, 
2470                          SCNetworkInterfaceRef  interface
, 
2471                          CFStringRef            userDefinedName
) 
2473         SCNetworkSetRef currentSet 
= NULL
; 
2475         SCNetworkServiceRef service 
= NULL
; 
2477         if (interface 
== NULL
) { 
2481         if (userDefinedName 
== NULL
) { 
2482                 userDefinedName 
= __SCNetworkInterfaceGetUserDefinedName(interface
); 
2483                 if (userDefinedName 
== NULL
) { 
2484                         SC_log(LOG_INFO
, "No userDefinedName"); 
2488         service 
= SCNetworkServiceCreate(prefs
, interface
); 
2489         if (service 
== NULL
) { 
2490                 SC_log(LOG_INFO
, "SCNetworkServiceCreate() failed: %s", SCErrorString(SCError())); 
2492                 ok 
= SCNetworkServiceSetName(service
, userDefinedName
); 
2494                         SC_log(LOG_INFO
, "SCNetworkServiceSetName() failed: %s", SCErrorString(SCError())); 
2495                         SCNetworkServiceRemove(service
); 
2499                 ok 
= SCNetworkServiceEstablishDefaultConfiguration(service
); 
2501                         SC_log(LOG_INFO
, "SCNetworkServiceEstablishDefaultConfiguration() failed: %s", SCErrorString(SCError())); 
2502                         SCNetworkServiceRemove(service
); 
2506         currentSet 
= SCNetworkSetCopyCurrent(prefs
); 
2507         if (currentSet 
== NULL
) { 
2508                 SC_log(LOG_INFO
, "No current set"); 
2509                 if (service 
!= NULL
) { 
2510                         SCNetworkServiceRemove(service
); 
2514         if (service 
!= NULL
) { 
2515                 ok 
= SCNetworkSetAddService(currentSet
, service
); 
2517                         SC_log(LOG_INFO
, "Could not add service to the current set"); 
2518                         SCNetworkServiceRemove(service
); 
2524         if (service 
!= NULL
) { 
2527         if (currentSet 
!= NULL
) { 
2528                 CFRelease(currentSet
); 
2533 __private_extern__ Boolean
 
2534 __SCNetworkServiceIsPPTP(SCNetworkServiceRef    service
) 
2536         CFStringRef intfSubtype
; 
2537         SCNetworkServicePrivateRef servicePrivate 
= (SCNetworkServicePrivateRef
)service
; 
2539         if (servicePrivate 
== NULL 
|| servicePrivate
->interface 
== NULL
) { 
2543         intfSubtype 
= __SCNetworkInterfaceGetEntitySubType(servicePrivate
->interface
); 
2544         if (intfSubtype 
== NULL
) { 
2548 #pragma GCC diagnostic push 
2549 #pragma GCC diagnostic ignored "-Wdeprecated" 
2550         if (CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) { 
2553 #pragma GCC diagnostic pop