2  * Copyright (c) 2004-2011 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 <SystemConfiguration/SystemConfiguration.h> 
  35 #include "SCNetworkConfigurationInternal.h" 
  36 #include <SystemConfiguration/SCValidation.h> 
  37 #include <SystemConfiguration/SCPrivate.h> 
  42 static CFStringRef      
__SCNetworkServiceCopyDescription       (CFTypeRef cf
); 
  43 static void             __SCNetworkServiceDeallocate            (CFTypeRef cf
); 
  44 static Boolean          
__SCNetworkServiceEqual                 (CFTypeRef cf1
, CFTypeRef cf2
); 
  45 static CFHashCode       
__SCNetworkServiceHash                  (CFTypeRef cf
); 
  48 static CFTypeID __kSCNetworkServiceTypeID               
= _kCFRuntimeNotATypeID
; 
  51 static const CFRuntimeClass __SCNetworkServiceClass 
= { 
  53         "SCNetworkService",                     // className 
  56         __SCNetworkServiceDeallocate
,           // dealloc 
  57         __SCNetworkServiceEqual
,                // equal 
  58         __SCNetworkServiceHash
,                 // hash 
  59         NULL
,                                   // copyFormattingDesc 
  60         __SCNetworkServiceCopyDescription       
// copyDebugDesc 
  64 static pthread_once_t           initialized             
= PTHREAD_ONCE_INIT
; 
  68 __SCNetworkServiceCopyDescription(CFTypeRef cf
) 
  70         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
  71         CFMutableStringRef              result
; 
  72         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
  74         result 
= CFStringCreateMutable(allocator
, 0); 
  75         CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkService %p [%p]> {"), cf
, 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         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  92 __SCNetworkServiceDeallocate(CFTypeRef cf
) 
  94         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
  96         /* release resources */ 
  98         CFRelease(servicePrivate
->serviceID
); 
  99         if (servicePrivate
->interface 
!= NULL
) CFRelease(servicePrivate
->interface
); 
 100         if (servicePrivate
->prefs 
!= NULL
) CFRelease(servicePrivate
->prefs
); 
 101         if (servicePrivate
->store 
!= NULL
) CFRelease(servicePrivate
->store
); 
 102         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
 109 __SCNetworkServiceEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 111         SCNetworkServicePrivateRef      s1      
= (SCNetworkServicePrivateRef
)cf1
; 
 112         SCNetworkServicePrivateRef      s2      
= (SCNetworkServicePrivateRef
)cf2
; 
 117         if (s1
->prefs 
!= s2
->prefs
) 
 118                 return FALSE
;   // if not the same prefs 
 120         if (!CFEqual(s1
->serviceID
, s2
->serviceID
)) 
 121                 return FALSE
;   // if not the same service identifier 
 128 __SCNetworkServiceHash(CFTypeRef cf
) 
 130         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
 132         return CFHash(servicePrivate
->serviceID
); 
 137 __SCNetworkServiceInitialize(void) 
 139         __kSCNetworkServiceTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkServiceClass
); 
 144 __private_extern__ SCNetworkServicePrivateRef
 
 145 __SCNetworkServiceCreatePrivate(CFAllocatorRef          allocator
, 
 146                                 SCPreferencesRef        prefs
, 
 147                                 CFStringRef             serviceID
, 
 148                                 SCNetworkInterfaceRef   interface
) 
 150         SCNetworkServicePrivateRef              servicePrivate
; 
 153         /* initialize runtime */ 
 154         pthread_once(&initialized
, __SCNetworkServiceInitialize
); 
 156         /* allocate target */ 
 157         size           
= sizeof(SCNetworkServicePrivate
) - sizeof(CFRuntimeBase
); 
 158         servicePrivate 
= (SCNetworkServicePrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 159                                                                               __kSCNetworkServiceTypeID
, 
 162         if (servicePrivate 
== NULL
) { 
 166         servicePrivate
->prefs           
= (prefs 
!= NULL
) ? CFRetain(prefs
): NULL
; 
 167         servicePrivate
->serviceID       
= CFStringCreateCopy(NULL
, serviceID
); 
 168         servicePrivate
->interface       
= (interface 
!= NULL
) ? CFRetain(interface
) : NULL
; 
 169         servicePrivate
->name            
= NULL
; 
 171         return servicePrivate
; 
 176 #pragma mark Service ordering 
 180 _SCNetworkServiceCompare(const void *val1
, const void *val2
, void *context
) 
 184         CFArrayRef              order   
= (CFArrayRef
)context
; 
 185         SCNetworkServiceRef     s1      
= (SCNetworkServiceRef
)val1
; 
 186         SCNetworkServiceRef     s2      
= (SCNetworkServiceRef
)val2
; 
 188         id1 
= SCNetworkServiceGetServiceID(s1
); 
 189         id2 
= SCNetworkServiceGetServiceID(s2
); 
 196                 range 
= CFRangeMake(0, CFArrayGetCount(order
)); 
 197                 o1 
= CFArrayGetFirstIndexOfValue(order
, range
, id1
); 
 198                 o2 
= CFArrayGetFirstIndexOfValue(order
, range
, id2
); 
 201                         return (o2 
!= kCFNotFound
) ? kCFCompareGreaterThan 
: kCFCompareLessThan
; 
 202                 } else if (o1 
< o2
) { 
 203                         return (o1 
!= kCFNotFound
) ? kCFCompareLessThan    
: kCFCompareGreaterThan
; 
 207         return CFStringCompare(id1
, id2
, 0); 
 212 #pragma mark SCNetworkService APIs 
 218 __private_extern__ CFArrayRef 
/* of SCNetworkServiceRef's */ 
 219 __SCNetworkServiceCopyAllEnabled(SCPreferencesRef prefs
) 
 221         CFMutableArrayRef       array   
= NULL
; 
 226         sets 
= SCNetworkSetCopyAll(prefs
); 
 231         n_sets 
= CFArrayGetCount(sets
); 
 232         for (i_sets 
= 0; i_sets 
< n_sets
; i_sets
++) { 
 238                 set 
= CFArrayGetValueAtIndex(sets
, i_sets
); 
 239                 services 
= SCNetworkSetCopyServices(set
); 
 240                 if (services 
== NULL
) { 
 244                 n_services 
= CFArrayGetCount(services
); 
 245                 for (i_services 
= 0; i_services 
< n_services
; i_services
++) { 
 246                         SCNetworkServiceRef service
; 
 248                         service 
= CFArrayGetValueAtIndex(services
, i_services
); 
 249                         if (!SCNetworkServiceGetEnabled(service
)) { 
 254                         if ((array 
== NULL
) || 
 255                             !CFArrayContainsValue(array
, 
 256                                                   CFRangeMake(0, CFArrayGetCount(array
)), 
 259                                         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 261                                 CFArrayAppendValue(array
, service
); 
 272 __private_extern__ Boolean
 
 273 __SCNetworkServiceExistsForInterface(CFArrayRef services
, SCNetworkInterfaceRef interface
) 
 278         n 
= isA_CFArray(services
) ? CFArrayGetCount(services
) : 0; 
 279         for (i 
= 0; i 
< n
; i
++) { 
 280                 SCNetworkServiceRef     service
; 
 281                 SCNetworkInterfaceRef   service_interface
; 
 283                 service 
= CFArrayGetValueAtIndex(services
, i
); 
 285                 service_interface 
= SCNetworkServiceGetInterface(service
); 
 286                 while (service_interface 
!= NULL
) { 
 287                         if (CFEqual(interface
, service_interface
)) { 
 291                         service_interface 
= SCNetworkInterfaceGetInterface(service_interface
); 
 299 __private_extern__ CFStringRef
 
 300 __SCNetworkServiceNextName(SCNetworkServiceRef service
) 
 302         CFArrayRef              components
; 
 305         CFMutableArrayRef       newComponents
; 
 308         name 
= SCNetworkServiceGetName(service
); 
 313         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, name
, CFSTR(" ")); 
 314         if (components 
!= NULL
) { 
 315                 newComponents 
= CFArrayCreateMutableCopy(NULL
, 0, components
); 
 316                 CFRelease(components
); 
 318                 newComponents 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 319                 CFArrayAppendValue(newComponents
, name
); 
 322         n 
= CFArrayGetCount(newComponents
); 
 326                 str 
= CFArrayGetValueAtIndex(newComponents
, n 
- 1); 
 327                 suffix 
= CFStringGetIntValue(str
); 
 329                         CFArrayRemoveValueAtIndex(newComponents
, n 
- 1); 
 335         name 
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), suffix
); 
 336         CFArrayAppendValue(newComponents
, name
); 
 339         name 
= CFStringCreateByCombiningStrings(NULL
, newComponents
, CFSTR(" ")); 
 340         CFRelease(newComponents
); 
 347 mergeDict(const void *key
, const void *value
, void *context
) 
 349         CFMutableDictionaryRef  newDict 
= (CFMutableDictionaryRef
)context
; 
 351         CFDictionarySetValue(newDict
, key
, value
); 
 356 static CFDictionaryRef
 
 357 _protocolTemplate(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 359         SCNetworkInterfaceRef           interface
; 
 360         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 361         CFDictionaryRef                 
template        = NULL
; 
 363         interface 
= servicePrivate
->interface
; 
 364         if (interface 
!= NULL
) { 
 365                 SCNetworkInterfaceRef   childInterface
; 
 366                 CFStringRef             childInterfaceType      
= NULL
; 
 367                 CFStringRef             interfaceType
; 
 370                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(servicePrivate
->interface
); 
 371                 childInterface 
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
); 
 372                 if (childInterface 
!= NULL
) { 
 373                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 376                 template = __copyProtocolTemplate(interfaceType
, childInterfaceType
, protocolType
); 
 377                 if (template != NULL
) { 
 378                         CFDictionaryRef         overrides
; 
 380                         // move to the interface at the lowest layer 
 381                         while (childInterface 
!= NULL
) { 
 382                                 interface 
= childInterface
; 
 383                                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 386                         overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, protocolType
); 
 387                         if (overrides 
!= NULL
) { 
 388                                 CFMutableDictionaryRef  newTemplate
; 
 390                                 newTemplate 
= CFDictionaryCreateMutableCopy(NULL
, 0, template); 
 391                                 CFDictionaryApplyFunction(overrides
, mergeDict
, newTemplate
); 
 393                                 template = newTemplate
; 
 398         if (template == NULL
) { 
 399                 template = CFDictionaryCreate(NULL
, 
 403                                               &kCFTypeDictionaryKeyCallBacks
, 
 404                                               &kCFTypeDictionaryValueCallBacks
); 
 412 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 414         CFDictionaryRef                 entity
; 
 415         CFDictionaryRef                 newEntity       
= NULL
; 
 418         SCNetworkProtocolRef            protocol
; 
 419         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 421         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 422                 _SCErrorSet(kSCStatusInvalidArgument
); 
 426         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
 427                 _SCErrorSet(kSCStatusInvalidArgument
); 
 431         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 432                                                               servicePrivate
->serviceID
,        // service 
 433                                                               protocolType
);                    // entity 
 435         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 436         if (entity 
!= NULL
) { 
 437                 // if "protocol" already exists 
 438                 _SCErrorSet(kSCStatusKeyExists
); 
 442         newEntity 
= CFDictionaryCreate(NULL
, 
 446                                        &kCFTypeDictionaryKeyCallBacks
, 
 447                                        &kCFTypeDictionaryValueCallBacks
); 
 448         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
 449         CFRelease(newEntity
); 
 454         protocol  
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
 455         newEntity 
= _protocolTemplate(service
, protocolType
); 
 456         ok 
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
); 
 457         CFRelease(newEntity
); 
 467 CFArrayRef 
/* of SCNetworkServiceRef's */ 
 468 SCNetworkServiceCopyAll(SCPreferencesRef prefs
) 
 470         CFMutableArrayRef       array
; 
 473         CFDictionaryRef         services
; 
 475         path 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 476         services 
= SCPreferencesPathGetValue(prefs
, path
); 
 479         if ((services 
!= NULL
) && !isA_CFDictionary(services
)) { 
 483         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 485         n 
= (services 
!= NULL
) ? CFDictionaryGetCount(services
) : 0; 
 488                 const void *    keys_q
[N_QUICK
]; 
 489                 const void **   keys    
= keys_q
; 
 490                 const void *    vals_q
[N_QUICK
]; 
 491                 const void **   vals    
= vals_q
; 
 493                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 494                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 495                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 497                 CFDictionaryGetKeysAndValues(services
, keys
, vals
); 
 498                 for (i 
= 0; i 
< n
; i
++) { 
 499                         CFDictionaryRef                 entity
; 
 500                         SCNetworkServicePrivateRef      servicePrivate
; 
 502                         if (!isA_CFDictionary(vals
[i
])) { 
 505                                       CFSTR("SCNetworkServiceCopyAll(): error w/service \"%@\"\n"), 
 510                         entity 
= CFDictionaryGetValue(vals
[i
], kSCEntNetInterface
); 
 511                         if (!isA_CFDictionary(entity
)) { 
 515                                       CFSTR("SCNetworkServiceCopyAll(): no \"%@\" entity for service \"%@\"\n"), 
 521                         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, keys
[i
], NULL
); 
 522                         CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
); 
 523                         CFRelease(servicePrivate
); 
 525                 if (keys 
!= keys_q
) { 
 526                         CFAllocatorDeallocate(NULL
, keys
); 
 527                         CFAllocatorDeallocate(NULL
, vals
); 
 536  * build a list of all of a servives entity types that are associated 
 537  * with the services interface.  The list will include : 
 539  * - entity types associated with the interface type (Ethernet, FireWire, PPP, ...) 
 540  * - entity types associated with the interface sub-type (PPPSerial, PPPoE, L2TP, PPTP, ...) 
 541  * - entity types associated with the hardware device (Ethernet, AirPort, FireWire, Modem, ...) 
 544 _copyInterfaceEntityTypes(CFDictionaryRef protocols
) 
 546         CFDictionaryRef interface
; 
 547         CFMutableSetRef interface_entity_types
; 
 549         interface_entity_types 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 551         interface 
= CFDictionaryGetValue(protocols
, kSCEntNetInterface
); 
 552         if (isA_CFDictionary(interface
)) { 
 553                 CFStringRef     entities
[]      = { kSCPropNetInterfaceType
, 
 554                                                     kSCPropNetInterfaceSubType
, 
 555                                                     kSCPropNetInterfaceHardware 
}; 
 558                 // include the "Interface" entity itself 
 559                 CFSetAddValue(interface_entity_types
, kSCEntNetInterface
); 
 561                 // include the entities associated with the interface 
 562                 for (i 
= 0; i 
< sizeof(entities
)/sizeof(entities
[0]); i
++) { 
 565                         entity 
= CFDictionaryGetValue(interface
, entities
[i
]); 
 566                         if (isA_CFString(entity
)) { 
 567                                 CFSetAddValue(interface_entity_types
, entity
); 
 572                  * and, because we've found some misguided network preference code 
 573                  * developers leaving [PPP] entity dictionaries around even though 
 574                  * they are unused and/or unneeded... 
 576                 CFSetAddValue(interface_entity_types
, kSCEntNetPPP
); 
 579         return interface_entity_types
; 
 584 SCNetworkServiceCopy(SCPreferencesRef prefs
, CFStringRef serviceID
) 
 586         CFDictionaryRef                 entity
; 
 588         SCNetworkServicePrivateRef      servicePrivate
; 
 590         if (!isA_CFString(serviceID
)) { 
 591                 _SCErrorSet(kSCStatusInvalidArgument
); 
 595         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                     // allocator 
 596                                                               serviceID
,                // service 
 597                                                               kSCEntNetInterface
);      // entity 
 598         entity 
= SCPreferencesPathGetValue(prefs
, path
); 
 601         if (!isA_CFDictionary(entity
)) { 
 602                 // a "service" must have an "interface" 
 603                 _SCErrorSet(kSCStatusNoKey
); 
 607         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 608         return (SCNetworkServiceRef
)servicePrivate
; 
 613 _SCNetworkServiceCopyActive(SCDynamicStoreRef store
, CFStringRef serviceID
) 
 615         SCNetworkServicePrivateRef      servicePrivate
; 
 617         if (!isA_CFString(serviceID
)) { 
 618                 _SCErrorSet(kSCStatusInvalidArgument
); 
 622         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, NULL
, serviceID
, NULL
); 
 624                 servicePrivate
->store 
= CFRetain(store
); 
 626         return (SCNetworkServiceRef
)servicePrivate
; 
 631 SCNetworkServiceCopyProtocol(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 633         CFSetRef                        non_protocol_entities
; 
 635         CFDictionaryRef                 protocols
; 
 636         SCNetworkProtocolPrivateRef     protocolPrivate 
= NULL
; 
 637         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 639         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 640                 _SCErrorSet(kSCStatusInvalidArgument
); 
 644         if (!isA_CFString(protocolType
)) { 
 645                 _SCErrorSet(kSCStatusInvalidArgument
); 
 649         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 650                                                               servicePrivate
->serviceID
,        // service 
 652         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 655         if (!isA_CFDictionary(protocols
)) { 
 657                 _SCErrorSet(kSCStatusFailed
); 
 661         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 662         if (CFSetContainsValue(non_protocol_entities
, protocolType
)) { 
 663                 // if the "protocolType" matches an interface entity type 
 664                 _SCErrorSet(kSCStatusInvalidArgument
); 
 668         if (!CFDictionaryContainsKey(protocols
, protocolType
)) { 
 669                 // if the "protocolType" entity does not exist 
 670                 _SCErrorSet(kSCStatusNoKey
); 
 674         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, protocolType
, service
); 
 678         CFRelease(non_protocol_entities
); 
 680         return (SCNetworkProtocolRef
)protocolPrivate
; 
 684 CFArrayRef 
/* of SCNetworkProtocolRef's */ 
 685 SCNetworkServiceCopyProtocols(SCNetworkServiceRef service
) 
 687         CFMutableArrayRef               array
; 
 689         CFSetRef                        non_protocol_entities
; 
 691         CFDictionaryRef                 protocols
; 
 692         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 694         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 695                 _SCErrorSet(kSCStatusInvalidArgument
); 
 699         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 700                                                               servicePrivate
->serviceID
,        // service 
 702         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 705         if (!isA_CFDictionary(protocols
)) { 
 707                 _SCErrorSet(kSCStatusFailed
); 
 711         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 713         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 715         n 
= CFDictionaryGetCount(protocols
); 
 718                 const void *                    keys_q
[N_QUICK
]; 
 719                 const void **                   keys            
= keys_q
; 
 720                 const void *                    vals_q
[N_QUICK
]; 
 721                 const void **                   vals            
= vals_q
; 
 723                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 724                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 725                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 727                 CFDictionaryGetKeysAndValues(protocols
, keys
, vals
); 
 728                 for (i 
= 0; i 
< n
; i
++) { 
 729                         SCNetworkProtocolPrivateRef     protocolPrivate
; 
 731                         if (!isA_CFDictionary(vals
[i
])) { 
 732                                 // if it's not a dictionary then it can't be a protocol entity 
 736                         if (CFSetContainsValue(non_protocol_entities
, keys
[i
])) { 
 737                                 // skip any non-protocol (interface) entities 
 741                         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, keys
[i
], service
); 
 742                         CFArrayAppendValue(array
, (SCNetworkProtocolRef
)protocolPrivate
); 
 744                         CFRelease(protocolPrivate
); 
 746                 if (keys 
!= keys_q
) { 
 747                         CFAllocatorDeallocate(NULL
, keys
); 
 748                         CFAllocatorDeallocate(NULL
, vals
); 
 752         CFRelease(non_protocol_entities
); 
 759 __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef     service
, 
 760                                      SCNetworkInterfaceRef   interface
) 
 762         CFDictionaryRef                 entity
; 
 765         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
 767         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 768                                                               servicePrivate
->serviceID
,        // service 
 769                                                               kSCEntNetInterface
);              // entity 
 770         entity 
= __SCNetworkInterfaceCopyInterfaceEntity(interface
); 
 771         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, entity
); 
 780 SCNetworkServiceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
) 
 782         CFArrayRef                      components
; 
 783         CFArrayRef                      interface_config
; 
 784         CFStringRef                     interface_name
; 
 785         SCNetworkInterfaceRef           newInterface
; 
 788         CFStringRef                     serviceID
; 
 789         SCNetworkServicePrivateRef      servicePrivate
; 
 790         CFArrayRef                      supported_protocols
; 
 792         if (!isA_SCNetworkInterface(interface
)) { 
 793                 _SCErrorSet(kSCStatusInvalidArgument
); 
 797         // only allow network interfaces which support one or more protocols 
 798         // to be added to a service.  The one exception is that we allow 
 799         // third-party interface types to be configured. 
 800         supported_protocols 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
 801         if (supported_protocols 
== NULL
) { 
 802                 CFStringRef     interface_type
; 
 804                 interface_type 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 805                 if (CFStringFind(interface_type
, CFSTR("."), 0).location 
== kCFNotFound
) { 
 806                         _SCErrorSet(kSCStatusInvalidArgument
); 
 811         // do not allow creation of a network service if the interface is a 
 812         // member of a bond or bridge 
 813         if (__SCNetworkInterfaceIsMember(prefs
, interface
)) { 
 814                 _SCErrorSet(kSCStatusKeyExists
); 
 818         // establish the service 
 819         prefix 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 820         path 
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
); 
 821         if (path 
== NULL
) path 
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
); 
 827         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/")); 
 830         serviceID 
= CFArrayGetValueAtIndex(components
, 2); 
 831         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 832         CFRelease(components
); 
 834         // duplicate the interface and associate the copy with the new service 
 835         newInterface 
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, 
 839         servicePrivate
->interface 
= newInterface
; 
 841         // establish "default" configuration(s) for the interface 
 842         for (interface 
= newInterface
; 
 844              interface 
= SCNetworkInterfaceGetInterface(interface
)) { 
 845                 SCNetworkInterfaceRef   childInterface
; 
 846                 CFStringRef             childInterfaceType      
= NULL
; 
 847                 CFDictionaryRef         config
; 
 848                 CFStringRef             interfaceType
; 
 850                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 851                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 852                 if (childInterface 
!= NULL
) { 
 853                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 856                 config 
= __copyInterfaceTemplate(interfaceType
, childInterfaceType
); 
 857                 if (config 
!= NULL
) { 
 858                         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBluetooth
) || 
 859                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeIrDA     
) || 
 860                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem    
) || 
 861                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeSerial   
) || 
 862                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeWWAN     
)) { 
 863                                 CFDictionaryRef         overrides
; 
 865                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypeModem
); 
 867                                 // a ConnectionScript (and related keys) from the interface 
 868                                 // should trump the settings from the configuration template. 
 869                                 if (overrides 
!= NULL
) { 
 870                                         CFMutableDictionaryRef  newConfig
; 
 872                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 873                                         if (CFDictionaryContainsKey(overrides
, kSCPropNetModemConnectionScript
)) { 
 874                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionPersonality
); 
 875                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionScript
); 
 876                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceVendor
); 
 877                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceModel
); 
 879                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 883                         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
) || 
 884                                    CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
 885                                 CFDictionaryRef         overrides
; 
 887                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypePPP
); 
 888                                 if (overrides 
!= NULL
) { 
 889                                         CFMutableDictionaryRef  newConfig
; 
 891                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 892                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 898                         if (!__SCNetworkInterfaceSetConfiguration(interface
, NULL
, config
, TRUE
)) { 
 899                                 SCLog(TRUE
, LOG_DEBUG
, 
 900                                       CFSTR("SCNetworkService __SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL"), 
 907         // add the interface [entity] to the service 
 908         (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef
)servicePrivate
, 
 909                                                     servicePrivate
->interface
); 
 911         // push the [deep] interface configuration into the service. 
 912         interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(NULL
, servicePrivate
->interface
); 
 913         __SCNetworkInterfaceSetDeepConfiguration(NULL
, servicePrivate
->interface
, interface_config
); 
 914         if (interface_config 
!= NULL
) CFRelease(interface_config
); 
 916         // set the service name to match that of the associated interface 
 918         // Note: It might seem a bit odd to call SCNetworkServiceGetName 
 919         // followed by an immediate call to SCNetworkServiceSetName.  The 
 920         // trick here is that if no name has previously been set, the 
 921         // "get" function will return the name of the associated interface. 
 923         // ... and we "set" a name to ensure that applications that do 
 924         // not use the APIs will still find a UserDefinedName property 
 925         // in the SCDynamicStore. 
 927         interface_name 
= SCNetworkServiceGetName((SCNetworkServiceRef
)servicePrivate
); 
 928         if (interface_name 
!= NULL
) { 
 929                 (void) SCNetworkServiceSetName((SCNetworkServiceRef
)servicePrivate
, 
 933         return (SCNetworkServiceRef
)servicePrivate
; 
 938 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service
) 
 941         SCNetworkInterfaceRef           interface
; 
 943         CFArrayRef                      protocolTypes
; 
 944         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 946         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 947                 _SCErrorSet(kSCStatusInvalidArgument
); 
 951         interface 
= SCNetworkServiceGetInterface(service
); 
 952         if (interface 
== NULL
) { 
 956         protocolTypes 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
 957         n 
= (protocolTypes 
!= NULL
) ? CFArrayGetCount(protocolTypes
) : 0; 
 958         for (i 
= 0; i 
< n
; i
++) { 
 960                 CFDictionaryRef         newEntity       
= NULL
; 
 962                 SCNetworkProtocolRef    protocol        
= NULL
; 
 963                 CFStringRef             protocolType
; 
 965                 protocolType 
= CFArrayGetValueAtIndex(protocolTypes
, i
); 
 966                 ok 
= SCNetworkServiceAddProtocolType(service
, protocolType
); 
 967                 if (!ok 
&& (SCError() != kSCStatusKeyExists
)) { 
 968                         // could not add protocol 
 972                 protocol 
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
 973                 if (protocol 
== NULL
) { 
 974                         // oops, somethings wrong (should never happen) 
 978                 newEntity 
= _protocolTemplate(service
, protocolType
); 
 979                 ok 
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
); 
 981                         // could not set default configuration 
 985                 enabled 
= !CFDictionaryContainsKey(newEntity
, kSCResvInactive
); 
 986                 ok 
= SCNetworkProtocolSetEnabled(protocol
, enabled
); 
 988                         // could not enable/disable protocol 
 994                 if (newEntity 
!= NULL
) CFRelease(newEntity
); 
 995                 if (protocol  
!= NULL
) CFRelease(protocol
); 
1003 SCNetworkServiceGetEnabled(SCNetworkServiceRef service
) 
1007         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1009         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1010                 _SCErrorSet(kSCStatusInvalidArgument
); 
1014         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1015                                                               servicePrivate
->serviceID
,        // service 
1017         enabled 
= __getPrefsEnabled(servicePrivate
->prefs
, path
); 
1024 SCNetworkInterfaceRef
 
1025 SCNetworkServiceGetInterface(SCNetworkServiceRef service
) 
1027         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1029         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1030                 _SCErrorSet(kSCStatusInvalidArgument
); 
1034         if (servicePrivate
->interface 
== NULL
) { 
1035                 CFDictionaryRef entity
; 
1038                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1039                                                                       servicePrivate
->serviceID
,        // service 
1040                                                                       kSCEntNetInterface
);              // entity 
1041                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1044                 if (isA_CFDictionary(entity
)) { 
1045                         servicePrivate
->interface 
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, service
); 
1049         return servicePrivate
->interface
; 
1054 SCNetworkServiceGetName(SCNetworkServiceRef service
) 
1056         CFDictionaryRef                 entity
; 
1057         SCNetworkInterfaceRef           interface
; 
1058         CFStringRef                     name            
= NULL
; 
1060         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1062         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1063                 _SCErrorSet(kSCStatusInvalidArgument
); 
1067         if (servicePrivate
->name 
!= NULL
) { 
1068                 return servicePrivate
->name
; 
1071         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1072                                                               servicePrivate
->serviceID
,        // service 
1074         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1077         if (isA_CFDictionary(entity
)) { 
1078                 name 
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
); 
1079                 if (isA_CFString(name
)) { 
1080                         servicePrivate
->name 
= CFRetain(name
); 
1084         interface 
= SCNetworkServiceGetInterface(service
); 
1085         while (interface 
!= NULL
) { 
1086                 SCNetworkInterfaceRef   childInterface
; 
1087                 CFStringRef             interfaceType
; 
1089                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1090                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1094                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1095                 if ((childInterface 
== NULL
) || 
1096                     CFEqual(childInterface
, kSCNetworkInterfaceIPv4
)) { 
1100                 interface 
= childInterface
; 
1103         if (interface 
!= NULL
) { 
1105                 CFStringRef     interface_name  
= NULL
; 
1106                 CFStringRef     suffix          
= NULL
; 
1109                 // check if the [stored] service name matches the non-localized interface 
1110                 // name.  If so, return the localized name. 
1112                 // Also, the older "Built-in XXX" interface names are too long for the 
1113                 // current UI. If we find that the [stored] service name matches the older 
1114                 // name, return the newer (and shorter) localized name. 
1116                 // Note: the user/admin will no longer be able to set the service name 
1117                 //       to "Built-in Ethernet". 
1119                 for (i 
= 0; i 
< 3; i
++) { 
1120                         if (servicePrivate
->name 
== NULL
) { 
1121                                 // if no [stored] service name to compare 
1127                                         // compare the non-localized interface name 
1128                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1129                                         if (interface_name 
!= NULL
) { 
1130                                                 CFRetain(interface_name
); 
1133 #if     !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR 
1135                                         // compare the older "Built-in XXX" localized name 
1136                                         interface_name 
= __SCNetworkInterfaceCopyXLocalizedDisplayName(interface
); 
1139                                         // compare the older "Built-in XXX" non-localized name 
1140                                         interface_name 
= __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface
); 
1142 #endif  // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR 
1147                         if (interface_name 
!= NULL
) { 
1148                                 Boolean match   
= FALSE
; 
1150                                 if (CFEqual(name
, interface_name
)) { 
1151                                         // if service name matches the OLD localized 
1154                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1155                                         CFIndex prefixLen       
= CFStringGetLength(interface_name
); 
1156                                         CFIndex suffixLen       
= CFStringGetLength(name
); 
1158                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1160                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1163                                 CFRelease(interface_name
); 
1166                                         CFRelease(servicePrivate
->name
); 
1167                                         servicePrivate
->name 
= NULL
; 
1174                 // if the service name has not been set, use the localized interface name 
1176                 if (servicePrivate
->name 
== NULL
) { 
1177                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1178                         if (interface_name 
!= NULL
) { 
1179                                 if (suffix 
!= NULL
) { 
1180                                         servicePrivate
->name 
= CFStringCreateWithFormat(NULL
, 
1186                                         servicePrivate
->name 
= CFRetain(interface_name
); 
1190                 if (suffix 
!= NULL
) CFRelease(suffix
); 
1193         return servicePrivate
->name
; 
1198 SCNetworkServiceGetServiceID(SCNetworkServiceRef service
) 
1200         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1202         if (!isA_SCNetworkService(service
)) { 
1203                 _SCErrorSet(kSCStatusInvalidArgument
); 
1207         return servicePrivate
->serviceID
; 
1212 SCNetworkServiceGetTypeID(void) 
1214         pthread_once(&initialized
, __SCNetworkServiceInitialize
);       /* initialize runtime */ 
1215         return __kSCNetworkServiceTypeID
; 
1220 SCNetworkServiceRemove(SCNetworkServiceRef service
) 
1224         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1227         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1228                 _SCErrorSet(kSCStatusInvalidArgument
); 
1232         // remove service from all sets 
1234         sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1239                 n 
= CFArrayGetCount(sets
); 
1240                 for (i 
= 0; i 
< n
; i
++) { 
1241                         SCNetworkSetRef set
; 
1243                         set 
= CFArrayGetValueAtIndex(sets
, i
); 
1244                         ok 
= SCNetworkSetRemoveService(set
, service
); 
1245                         if (!ok 
&& (SCError() != kSCStatusNoKey
)) { 
1255         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1256                                                               servicePrivate
->serviceID
,        // service 
1258         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1266 SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
1268         CFDictionaryRef                 entity
; 
1271         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1273         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1274                 _SCErrorSet(kSCStatusInvalidArgument
); 
1278         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
1279                 _SCErrorSet(kSCStatusInvalidArgument
); 
1283         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1284                                                               servicePrivate
->serviceID
,        // service 
1285                                                               protocolType
);                    // entity 
1287         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1288         if (entity 
== NULL
) { 
1289                 // if "protocol" does not exist 
1290                 _SCErrorSet(kSCStatusNoKey
); 
1294         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1304 SCNetworkServiceSetEnabled(SCNetworkServiceRef service
, Boolean enabled
) 
1308         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1310         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1311                 _SCErrorSet(kSCStatusInvalidArgument
); 
1315         // make sure that we do not enable a network service if the 
1316         // associated interface is a member of a bond or bridge. 
1318                 SCNetworkInterfaceRef   interface
; 
1320                 interface 
= SCNetworkServiceGetInterface(service
); 
1321                 if ((interface 
!= NULL
) && 
1322                     __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) { 
1323                         _SCErrorSet(kSCStatusKeyExists
); 
1328         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1329                                                               servicePrivate
->serviceID
,        // service 
1331         ok 
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
); 
1339 SCNetworkServiceSetName(SCNetworkServiceRef service
, CFStringRef name
) 
1341         CFDictionaryRef                 entity
; 
1344         CFStringRef                     saveName        
= NULL
; 
1345         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1347         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1348                 _SCErrorSet(kSCStatusInvalidArgument
); 
1353                 if (!isA_CFString(name
)) { 
1354                         _SCErrorSet(kSCStatusInvalidArgument
); 
1357                 saveName 
= CFRetain(name
); 
1361                 SCNetworkInterfaceRef   interface
; 
1363                 interface 
= SCNetworkServiceGetInterface(service
); 
1364                 while (interface 
!= NULL
) { 
1365                         SCNetworkInterfaceRef   childInterface
; 
1367                         childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1368                         if (childInterface 
== NULL
) { 
1372                         interface 
= childInterface
; 
1375                 if (interface 
!= NULL
) { 
1376                         CFStringRef     interface_name
; 
1378                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1379                         if (interface_name 
!= NULL
) { 
1380                                 if (CFEqual(name
, interface_name
)) { 
1381                                         // if service name matches the localized interface name 
1382                                         // then store the non-localized name. 
1383                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1384                                         if (interface_name 
!= NULL
) { 
1385                                                 CFRelease(saveName
); 
1386                                                 saveName 
= CFRetain(interface_name
); 
1388                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1389                                         CFIndex         prefixLen       
= CFStringGetLength(interface_name
); 
1391                                         CFIndex         suffixLen       
= CFStringGetLength(name
); 
1393                                         // if service name matches the localized interface name plus 
1394                                         // a few extra characters) then store the non-localized name with 
1396                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1398                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1399                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1400                                         if (interface_name 
!= NULL
) { 
1401                                                 CFRelease(saveName
); 
1402                                                 saveName 
= CFStringCreateWithFormat(NULL
, 
1414 #define PREVENT_DUPLICATE_SERVICE_NAMES 
1415 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
1419                 // ensure that each service is uniquely named within its sets 
1421                 sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1426                         set_count 
= CFArrayGetCount(sets
); 
1427                         for (set_index 
= 0; set_index 
< set_count
; set_index
++) { 
1428                                 CFIndex         service_index
; 
1429                                 Boolean         isDup           
= FALSE
; 
1430                                 Boolean         isMember        
= FALSE
; 
1431                                 CFIndex         service_count
; 
1432                                 CFArrayRef      services
; 
1433                                 SCNetworkSetRef set             
= CFArrayGetValueAtIndex(sets
, set_index
); 
1435                                 services 
= SCNetworkSetCopyServices(set
); 
1437                                 service_count 
= CFArrayGetCount(services
); 
1438                                 for (service_index 
= 0; service_index 
< service_count
; service_index
++) { 
1439                                         CFStringRef             otherID
; 
1440                                         CFStringRef             otherName
; 
1441                                         SCNetworkServiceRef     otherService
; 
1443                                         otherService 
= CFArrayGetValueAtIndex(services
, service_index
); 
1445                                         otherID 
= SCNetworkServiceGetServiceID(otherService
); 
1446                                         if (CFEqual(servicePrivate
->serviceID
, otherID
)) { 
1447                                                 // if the service is a member of this set 
1452                                         otherName 
= SCNetworkServiceGetName(otherService
); 
1453                                         if ((otherName 
!= NULL
) && CFEqual(name
, otherName
)) { 
1459                                 CFRelease(services
); 
1461                                 if (isMember 
&& isDup
) { 
1463                                          * if this service is a member of the set and 
1464                                          * the "name" is not unique. 
1467                                         if (saveName 
!= NULL
) CFRelease(saveName
); 
1468                                         _SCErrorSet(kSCStatusKeyExists
); 
1476 #endif  /* PREVENT_DUPLICATE_SERVICE_NAMES */ 
1478         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1479                                                               servicePrivate
->serviceID
,        // service 
1481         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1482         if (isA_CFDictionary(entity
) || 
1483             ((entity 
== NULL
) && (name 
!= NULL
))) { 
1484                 CFMutableDictionaryRef  newEntity
; 
1486                 if (entity 
!= NULL
) { 
1487                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1489                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1491                                                               &kCFTypeDictionaryKeyCallBacks
, 
1492                                                               &kCFTypeDictionaryValueCallBacks
); 
1494                 if (saveName 
!= NULL
) { 
1495                         CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, saveName
); 
1497                         CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
); 
1499                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1500                 CFRelease(newEntity
); 
1503         if (saveName 
!= NULL
) CFRelease(saveName
); 
1505         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
1506         if (name 
!= NULL
) CFRetain(name
); 
1507         servicePrivate
->name 
= name
; 
1514 #pragma mark SCNetworkService SPIs 
1518 str_to_rank(CFStringRef rankStr
, SCNetworkServicePrimaryRank 
*rank
) 
1520         if (isA_CFString(rankStr
)) { 
1521                 if (CFEqual(rankStr
, kSCValNetServicePrimaryRankFirst
)) { 
1522                         *rank 
= kSCNetworkServicePrimaryRankFirst
; 
1523                 } else if (CFEqual(rankStr
, kSCValNetServicePrimaryRankLast
)) { 
1524                         *rank 
= kSCNetworkServicePrimaryRankLast
; 
1525                 } else if (CFEqual(rankStr
, kSCValNetServicePrimaryRankNever
)) { 
1526                         *rank 
= kSCNetworkServicePrimaryRankNever
; 
1530         } else if (rankStr 
== NULL
) { 
1531                 *rank 
= kSCNetworkServicePrimaryRankDefault
; 
1540 SCNetworkServicePrimaryRank
 
1541 SCNetworkServiceGetPrimaryRank(SCNetworkServiceRef service
) 
1543         CFDictionaryRef                 entity
; 
1546         SCNetworkServicePrimaryRank     rank            
= kSCNetworkServicePrimaryRankDefault
; 
1547         CFStringRef                     rankStr         
= NULL
; 
1548         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1550         if (!isA_SCNetworkService(service
)) { 
1551                 _SCErrorSet(kSCStatusInvalidArgument
); 
1555         if (servicePrivate
->prefs 
!= NULL
) { 
1556                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1557                                                                       servicePrivate
->serviceID
, 
1559                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1561                 if (isA_CFDictionary(entity
)) { 
1562                         rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1563                         ok 
= str_to_rank(rankStr
, &rank
); 
1565         } else if (servicePrivate
->store 
!= NULL
) { 
1566                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1567                                                                    kSCDynamicStoreDomainState
, 
1568                                                                    servicePrivate
->serviceID
, 
1570                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1572                 if (entity 
!= NULL
) { 
1573                         if (isA_CFDictionary(entity
)) { 
1574                                 rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1575                                 ok 
= str_to_rank(rankStr
, &rank
); 
1580                 _SCErrorSet(kSCStatusInvalidArgument
); 
1585                 rank 
= kSCNetworkServicePrimaryRankDefault
; 
1586                 _SCErrorSet(kSCStatusInvalidArgument
); 
1587         } else if (rank 
== kSCNetworkServicePrimaryRankDefault
) { 
1588                 _SCErrorSet(kSCStatusOK
); 
1596 rank_to_str(SCNetworkServicePrimaryRank rank
, CFStringRef 
*rankStr
) 
1599                 case kSCNetworkServicePrimaryRankDefault 
: 
1602                 case kSCNetworkServicePrimaryRankFirst 
: 
1603                         *rankStr 
= kSCValNetServicePrimaryRankFirst
; 
1605                 case kSCNetworkServicePrimaryRankLast 
: 
1606                         *rankStr 
= kSCValNetServicePrimaryRankLast
; 
1608                 case kSCNetworkServicePrimaryRankNever 
: 
1609                         *rankStr 
= kSCValNetServicePrimaryRankNever
; 
1620 SCNetworkServiceSetPrimaryRank(SCNetworkServiceRef              service
, 
1621                                SCNetworkServicePrimaryRank      newRank
) 
1624         CFDictionaryRef                 entity
; 
1625         CFMutableDictionaryRef          newEntity
; 
1626         CFStringRef                     path            
= NULL
; 
1627         CFStringRef                     rankStr         
= NULL
; 
1628         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1630         if (!isA_SCNetworkService(service
)) { 
1631                 _SCErrorSet(kSCStatusInvalidArgument
); 
1635         ok 
= rank_to_str(newRank
, &rankStr
); 
1637                 _SCErrorSet(kSCStatusInvalidArgument
); 
1641         if (servicePrivate
->prefs 
!= NULL
) { 
1642                 if ((newRank 
== kSCNetworkServicePrimaryRankDefault
) || (newRank 
== kSCNetworkServicePrimaryRankNever
)) { 
1643                         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1644                                                                               servicePrivate
->serviceID
, 
1646                         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1647                         if (entity 
!= NULL
) { 
1648                                 if (!isA_CFDictionary(entity
)) { 
1650                                         _SCErrorSet(kSCStatusFailed
); 
1653                                 newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1655                                 newEntity 
= CFDictionaryCreateMutable(NULL
, 
1657                                                                       &kCFTypeDictionaryKeyCallBacks
, 
1658                                                                       &kCFTypeDictionaryValueCallBacks
); 
1660                         if (rankStr 
!= NULL
) { 
1661                                 CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1663                                 CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1665                         if (CFDictionaryGetCount(newEntity
) > 0) { 
1666                                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1668                                 ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1670                         CFRelease(newEntity
); 
1675                         _SCErrorSet(kSCStatusInvalidArgument
); 
1678         } else if (servicePrivate
->store 
!= NULL
) { 
1679                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1680                                                                    kSCDynamicStoreDomainState
, 
1681                                                                    servicePrivate
->serviceID
, 
1683                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1684                 if (entity 
!= NULL
) { 
1685                         if (!isA_CFDictionary(entity
)) { 
1688                                 _SCErrorSet(kSCStatusFailed
); 
1691                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1694                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1696                                                               &kCFTypeDictionaryKeyCallBacks
, 
1697                                                               &kCFTypeDictionaryValueCallBacks
); 
1699                 if (rankStr 
!= NULL
) { 
1700                         CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1702                         CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1704                 if (CFDictionaryGetCount(newEntity
) > 0) { 
1705                         ok 
= SCDynamicStoreSetValue(servicePrivate
->store
, path
, newEntity
); 
1707                         ok 
= SCDynamicStoreRemoveValue(servicePrivate
->store
, path
); 
1709                 CFRelease(newEntity
); 
1714                 _SCErrorSet(kSCStatusInvalidArgument
); 
1720         if (path 
!= NULL
)       CFRelease(path
); 
1726 _SCNetworkServiceIsVPN(SCNetworkServiceRef service
) 
1728         SCNetworkInterfaceRef   interface
; 
1729         CFStringRef             interfaceType
; 
1731         interface 
= SCNetworkServiceGetInterface(service
); 
1732         if (interface 
== NULL
) { 
1736         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1737         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
1738                 interface 
= SCNetworkInterfaceGetInterface(interface
); 
1739                 if (interface 
== NULL
) { 
1743                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1744                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
1747                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) { 
1750         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1752         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {