2  * Copyright (c) 2004-2020 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * Modification History 
  27  * May 13, 2004         Allan Nathanson <ajn@apple.com> 
  32 #include <CoreFoundation/CoreFoundation.h> 
  33 #include <CoreFoundation/CFRuntime.h> 
  34 #include "SCNetworkConfigurationInternal.h" 
  35 #include "SCPreferencesInternal.h" 
  40 #include <CommonCrypto/CommonDigest.h> 
  42 #define EXTERNAL_ID_DOMAIN_PREFIX       "_" 
  44 static CFStringRef      
__SCNetworkServiceCopyDescription       (CFTypeRef cf
); 
  45 static void             __SCNetworkServiceDeallocate            (CFTypeRef cf
); 
  46 static Boolean          
__SCNetworkServiceEqual                 (CFTypeRef cf1
, CFTypeRef cf2
); 
  47 static CFHashCode       
__SCNetworkServiceHash                  (CFTypeRef cf
); 
  50 static CFTypeID __kSCNetworkServiceTypeID               
= _kCFRuntimeNotATypeID
; 
  53 static const CFRuntimeClass __SCNetworkServiceClass 
= { 
  55         "SCNetworkService",                     // className 
  58         __SCNetworkServiceDeallocate
,           // dealloc 
  59         __SCNetworkServiceEqual
,                // equal 
  60         __SCNetworkServiceHash
,                 // hash 
  61         NULL
,                                   // copyFormattingDesc 
  62         __SCNetworkServiceCopyDescription       
// copyDebugDesc 
  66 static pthread_once_t           initialized             
= PTHREAD_ONCE_INIT
; 
  70 __SCNetworkServiceCopyDescription(CFTypeRef cf
) 
  72         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
  73         CFMutableStringRef              result
; 
  74         SCNetworkServiceRef             service         
= (SCNetworkServiceRef
)cf
; 
  75         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
  77         result 
= CFStringCreateMutable(allocator
, 0); 
  78         CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkService %p [%p]> {"), service
, allocator
); 
  79         CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), servicePrivate
->serviceID
); 
  80         if (servicePrivate
->prefs 
!= NULL
) { 
  81                 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), servicePrivate
->prefs
); 
  82         } else if (servicePrivate
->store 
!= NULL
) { 
  83                 CFStringAppendFormat(result
, NULL
, CFSTR(", store = %p"), servicePrivate
->store
); 
  85         if (servicePrivate
->name 
!= NULL
) { 
  86                 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), servicePrivate
->name
); 
  88         if (!__SCNetworkServiceExists(service
)) { 
  89                 CFStringAppendFormat(result
, NULL
, CFSTR(", REMOVED")); 
  91         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
  98 __SCNetworkServiceDeallocate(CFTypeRef cf
) 
 100         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
 102         /* release resources */ 
 104         CFRelease(servicePrivate
->serviceID
); 
 105         if (servicePrivate
->interface 
!= NULL
) CFRelease(servicePrivate
->interface
); 
 106         if (servicePrivate
->prefs 
!= NULL
) CFRelease(servicePrivate
->prefs
); 
 107         if (servicePrivate
->store 
!= NULL
) CFRelease(servicePrivate
->store
); 
 108         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
 109         if (servicePrivate
->externalIDs 
!= NULL
) CFRelease(servicePrivate
->externalIDs
); 
 116 __SCNetworkServiceEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 118         SCNetworkServicePrivateRef      s1      
= (SCNetworkServicePrivateRef
)cf1
; 
 119         SCNetworkServicePrivateRef      s2      
= (SCNetworkServicePrivateRef
)cf2
; 
 124         if (s1
->prefs 
!= s2
->prefs
) 
 125                 return FALSE
;   // if not the same prefs 
 127         if (!CFEqual(s1
->serviceID
, s2
->serviceID
)) 
 128                 return FALSE
;   // if not the same service identifier 
 135 __SCNetworkServiceHash(CFTypeRef cf
) 
 137         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)cf
; 
 139         return CFHash(servicePrivate
->serviceID
); 
 144 __SCNetworkServiceInitialize(void) 
 146         __kSCNetworkServiceTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkServiceClass
); 
 151 __private_extern__ SCNetworkServicePrivateRef
 
 152 __SCNetworkServiceCreatePrivate(CFAllocatorRef          allocator
, 
 153                                 SCPreferencesRef        prefs
, 
 154                                 CFStringRef             serviceID
, 
 155                                 SCNetworkInterfaceRef   interface
) 
 157         SCNetworkServicePrivateRef              servicePrivate
; 
 160         /* initialize runtime */ 
 161         pthread_once(&initialized
, __SCNetworkServiceInitialize
); 
 163         /* allocate target */ 
 164         size           
= sizeof(SCNetworkServicePrivate
) - sizeof(CFRuntimeBase
); 
 165         servicePrivate 
= (SCNetworkServicePrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 166                                                                               __kSCNetworkServiceTypeID
, 
 169         if (servicePrivate 
== NULL
) { 
 173         /* initialize non-zero/NULL members */ 
 174         servicePrivate
->prefs           
= (prefs 
!= NULL
) ? CFRetain(prefs
): NULL
; 
 175         servicePrivate
->serviceID       
= CFStringCreateCopy(NULL
, serviceID
); 
 176         servicePrivate
->interface       
= (interface 
!= NULL
) ? CFRetain(interface
) : NULL
; 
 178         return servicePrivate
; 
 183 #pragma mark Service ordering 
 187 _SCNetworkServiceCompare(const void *val1
, const void *val2
, void *context
) 
 191         CFArrayRef              order   
= (CFArrayRef
)context
; 
 192         SCNetworkServiceRef     s1      
= (SCNetworkServiceRef
)val1
; 
 193         SCNetworkServiceRef     s2      
= (SCNetworkServiceRef
)val2
; 
 195         id1 
= SCNetworkServiceGetServiceID(s1
); 
 196         id2 
= SCNetworkServiceGetServiceID(s2
); 
 203                 range 
= CFRangeMake(0, CFArrayGetCount(order
)); 
 204                 o1 
= CFArrayGetFirstIndexOfValue(order
, range
, id1
); 
 205                 o2 
= CFArrayGetFirstIndexOfValue(order
, range
, id2
); 
 208                         return (o2 
!= kCFNotFound
) ? kCFCompareGreaterThan 
: kCFCompareLessThan
; 
 209                 } else if (o1 
< o2
) { 
 210                         return (o1 
!= kCFNotFound
) ? kCFCompareLessThan    
: kCFCompareGreaterThan
; 
 214         return CFStringCompare(id1
, id2
, 0); 
 219 #pragma mark SCNetworkService APIs 
 225 __private_extern__ CFArrayRef 
/* of SCNetworkServiceRef's */ 
 226 __SCNetworkServiceCopyAllEnabled(SCPreferencesRef prefs
) 
 228         CFMutableArrayRef       array   
= NULL
; 
 233         sets 
= SCNetworkSetCopyAll(prefs
); 
 238         n_sets 
= CFArrayGetCount(sets
); 
 239         for (i_sets 
= 0; i_sets 
< n_sets
; i_sets
++) { 
 245                 set 
= CFArrayGetValueAtIndex(sets
, i_sets
); 
 246                 services 
= SCNetworkSetCopyServices(set
); 
 247                 if (services 
== NULL
) { 
 251                 n_services 
= CFArrayGetCount(services
); 
 252                 for (i_services 
= 0; i_services 
< n_services
; i_services
++) { 
 253                         SCNetworkServiceRef service
; 
 255                         service 
= CFArrayGetValueAtIndex(services
, i_services
); 
 256                         if (!SCNetworkServiceGetEnabled(service
)) { 
 261                         if ((array 
== NULL
) || 
 262                             !CFArrayContainsValue(array
, 
 263                                                   CFRangeMake(0, CFArrayGetCount(array
)), 
 266                                         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 268                                 CFArrayAppendValue(array
, service
); 
 279 __private_extern__ Boolean
 
 280 __SCNetworkServiceExistsForInterface(CFArrayRef services
, SCNetworkInterfaceRef interface
) 
 285         n 
= isA_CFArray(services
) ? CFArrayGetCount(services
) : 0; 
 286         for (i 
= 0; i 
< n
; i
++) { 
 287                 SCNetworkServiceRef     service
; 
 288                 SCNetworkInterfaceRef   service_interface
; 
 290                 service 
= CFArrayGetValueAtIndex(services
, i
); 
 292                 service_interface 
= SCNetworkServiceGetInterface(service
); 
 293                 while (service_interface 
!= NULL
) { 
 294                         if (CFEqual(interface
, service_interface
)) { 
 298                         service_interface 
= SCNetworkInterfaceGetInterface(service_interface
); 
 307 mergeDict(const void *key
, const void *value
, void *context
) 
 309         CFMutableDictionaryRef  newDict 
= (CFMutableDictionaryRef
)context
; 
 311         CFDictionarySetValue(newDict
, key
, value
); 
 316 static CF_RETURNS_RETAINED CFDictionaryRef
 
 317 _protocolTemplate(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 319         SCNetworkInterfaceRef           interface
; 
 320         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 321         CFDictionaryRef                 
template        = NULL
; 
 323         interface 
= servicePrivate
->interface
; 
 324         if (interface 
!= NULL
) { 
 325                 SCNetworkInterfaceRef   childInterface
; 
 326                 CFStringRef             childInterfaceType      
= NULL
; 
 327                 CFStringRef             interfaceType
; 
 330                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(servicePrivate
->interface
); 
 331                 childInterface 
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
); 
 332                 if (childInterface 
!= NULL
) { 
 333                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 336                 template = __copyProtocolTemplate(interfaceType
, childInterfaceType
, protocolType
); 
 337                 if (template != NULL
) { 
 338                         CFDictionaryRef         overrides
; 
 340                         // move to the interface at the lowest layer 
 341                         while (childInterface 
!= NULL
) { 
 342                                 interface 
= childInterface
; 
 343                                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 346                         overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, protocolType
); 
 347                         if (isA_CFDictionary(overrides
)) { 
 348                                 CFMutableDictionaryRef  newTemplate
; 
 350                                 newTemplate 
= CFDictionaryCreateMutableCopy(NULL
, 0, template); 
 351                                 CFDictionaryApplyFunction(overrides
, mergeDict
, newTemplate
); 
 353                                 template = newTemplate
; 
 358         if (template == NULL
) { 
 359                 template = CFDictionaryCreate(NULL
, 
 363                                               &kCFTypeDictionaryKeyCallBacks
, 
 364                                               &kCFTypeDictionaryValueCallBacks
); 
 372 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 374         CFDictionaryRef                 entity
; 
 376         CFDictionaryRef                 newEntity       
= NULL
; 
 379         SCNetworkProtocolRef            protocol        
= NULL
; 
 380         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 382         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 383                 _SCErrorSet(kSCStatusInvalidArgument
); 
 387         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
 388                 _SCErrorSet(kSCStatusInvalidArgument
); 
 392         if (!__SCNetworkServiceExists(service
)) { 
 393                 SC_log(LOG_ERR
, "SCNetworkServiceAddProtocolType() w/removed service\n  service = %@\n  protocol = %@", 
 396                 _SC_crash_once("SCNetworkServiceAddProtocolType() w/removed service", NULL
, NULL
); 
 397                 _SCErrorSet(kSCStatusInvalidArgument
); 
 401         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 402                                                               servicePrivate
->serviceID
,        // service 
 403                                                               protocolType
);                    // entity 
 405         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 406         if (entity 
!= NULL
) { 
 407                 // if "protocol" already exists 
 408                 _SCErrorSet(kSCStatusKeyExists
); 
 412         newEntity 
= CFDictionaryCreate(NULL
, 
 416                                        &kCFTypeDictionaryKeyCallBacks
, 
 417                                        &kCFTypeDictionaryValueCallBacks
); 
 418         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
 419         CFRelease(newEntity
); 
 425         protocol  
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
 426         assert(protocol 
!= NULL
); 
 428         newEntity 
= _protocolTemplate(service
, protocolType
); 
 429         assert(newEntity 
!= NULL
); 
 431         ok 
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
); 
 433                 // could not set default configuration 
 437         newEnabled 
= !CFDictionaryContainsKey(newEntity
, kSCResvInactive
); 
 438         ok 
= SCNetworkProtocolSetEnabled(protocol
, newEnabled
); 
 440                 // could not enable/disable protocol 
 446         if (newEntity 
!= NULL
) CFRelease(newEntity
); 
 447         if (protocol 
!= NULL
) CFRelease(protocol
); 
 450                 SC_log(LOG_DEBUG
, "SCNetworkServiceAddProtocolType(): %@, %@", service
, protocolType
); 
 458 CFArrayRef 
/* of SCNetworkServiceRef's */ 
 459 SCNetworkServiceCopyAll(SCPreferencesRef prefs
) 
 461         CFMutableArrayRef       array
; 
 464         CFDictionaryRef         services
; 
 467         path 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 468         services 
= SCPreferencesPathGetValue(prefs
, path
); 
 471         if ((services 
!= NULL
) && !isA_CFDictionary(services
)) { 
 475         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 477         n 
= (services 
!= NULL
) ? CFDictionaryGetCount(services
) : 0; 
 480                 const void *    keys_q
[N_QUICK
]; 
 481                 const void **   keys    
= keys_q
; 
 482                 const void *    vals_q
[N_QUICK
]; 
 483                 const void **   vals    
= vals_q
; 
 485                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 486                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 487                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 489                 CFDictionaryGetKeysAndValues(services
, keys
, vals
); 
 490                 for (i 
= 0; i 
< n
; i
++) { 
 491                         CFDictionaryRef                 entity
; 
 492                         SCNetworkServicePrivateRef      servicePrivate
; 
 494                         if (!isA_CFDictionary(vals
[i
])) { 
 495                                 SC_log(LOG_INFO
, "error w/service \"%@\"", keys
[i
]); 
 499                         entity 
= CFDictionaryGetValue(vals
[i
], kSCEntNetInterface
); 
 500                         if (!isA_CFDictionary(entity
)) { 
 502                                 SC_log(LOG_INFO
, "no \"%@\" entity for service \"%@\"", 
 508                         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 509                                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 513                         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, keys
[i
], NULL
); 
 514                         assert(servicePrivate 
!= NULL
); 
 515                         CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
); 
 516                         CFRelease(servicePrivate
); 
 518                 if (keys 
!= keys_q
) { 
 519                         CFAllocatorDeallocate(NULL
, keys
); 
 520                         CFAllocatorDeallocate(NULL
, vals
); 
 529 CFArrayRef 
/* of SCNetworkInterfaceRef's */ 
 530 __SCNetworkServiceCopyAllInterfaces(SCPreferencesRef prefs
) 
 532         CFMutableArrayRef interfaces 
= NULL
; 
 533         CFArrayRef services 
= NULL
; 
 534         CFIndex servicesCount 
= 0; 
 535         SCNetworkServiceRef service 
= NULL
; 
 536         SCNetworkInterfaceRef interface 
= NULL
; 
 538         services 
= SCNetworkServiceCopyAll(prefs
); 
 539         if (services 
== NULL
) { 
 543         servicesCount 
= CFArrayGetCount(services
); 
 544         if (servicesCount 
== 0) { 
 548         interfaces 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 550         for (CFIndex idx 
= 0; idx 
< servicesCount
; idx
++) { 
 551                 service 
= CFArrayGetValueAtIndex(services
, idx
); 
 552                 interface 
= SCNetworkServiceGetInterface(service
); 
 554                 if (isA_SCNetworkInterface(interface
) == NULL
) { 
 557                 CFArrayAppendValue(interfaces
, interface
); 
 560         if (CFArrayGetCount(interfaces
) == 0) { 
 561                 // Do not return an empty array 
 562                 CFRelease(interfaces
); 
 568         if (services 
!= NULL
) { 
 576  * build a list of all of a services entity types that are associated 
 577  * with the services interface.  The list will include : 
 579  * - entity types associated with the interface type (Ethernet, FireWire, PPP, ...) 
 580  * - entity types associated with the interface sub-type (PPPSerial, PPPoE, L2TP, PPTP, ...) 
 581  * - entity types associated with the hardware device (Ethernet, AirPort, FireWire, Modem, ...) 
 584 _copyInterfaceEntityTypes(CFDictionaryRef protocols
) 
 586         CFDictionaryRef interface
; 
 587         CFMutableSetRef interface_entity_types
; 
 589         interface_entity_types 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 591         interface 
= CFDictionaryGetValue(protocols
, kSCEntNetInterface
); 
 592         if (isA_CFDictionary(interface
)) { 
 593                 CFStringRef     entities
[]      = { kSCPropNetInterfaceType
, 
 594                                                     kSCPropNetInterfaceSubType
, 
 595                                                     kSCPropNetInterfaceHardware 
}; 
 597                 // include the "Interface" entity itself 
 598                 CFSetAddValue(interface_entity_types
, kSCEntNetInterface
); 
 600                 // include the entities associated with the interface 
 601                 for (size_t i 
= 0; i 
< sizeof(entities
)/sizeof(entities
[0]); i
++) { 
 604                         entity 
= CFDictionaryGetValue(interface
, entities
[i
]); 
 605                         if (isA_CFString(entity
)) { 
 606                                 CFSetAddValue(interface_entity_types
, entity
); 
 611                  * and, because we've found some misguided network preference code 
 612                  * developers leaving [PPP] entity dictionaries around even though 
 613                  * they are unused and/or unneeded... 
 615                 CFSetAddValue(interface_entity_types
, kSCEntNetPPP
); 
 618         return interface_entity_types
; 
 623 SCNetworkServiceCopy(SCPreferencesRef prefs
, CFStringRef serviceID
) 
 625         CFDictionaryRef                 entity
; 
 627         SCNetworkServicePrivateRef      servicePrivate
; 
 629         if (!isA_CFString(serviceID
)) { 
 630                 _SCErrorSet(kSCStatusInvalidArgument
); 
 634         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                     // allocator 
 635                                                               serviceID
,                // service 
 636                                                               kSCEntNetInterface
);      // entity 
 637         entity 
= SCPreferencesPathGetValue(prefs
, path
); 
 640         if (!isA_CFDictionary(entity
)) { 
 641                 // a "service" must have an "interface" 
 642                 _SCErrorSet(kSCStatusNoKey
); 
 646         if (__SCNetworkInterfaceEntityIsPPTP(entity
)) { 
 647                 SC_log(LOG_INFO
, "PPTP services are no longer supported"); 
 648                 _SCErrorSet(kSCStatusNoKey
); 
 652         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 653         return (SCNetworkServiceRef
)servicePrivate
; 
 658 _SCNetworkServiceCopyActive(SCDynamicStoreRef store
, CFStringRef serviceID
) 
 660         SCNetworkServicePrivateRef      servicePrivate
; 
 662         if (!isA_CFString(serviceID
)) { 
 663                 _SCErrorSet(kSCStatusInvalidArgument
); 
 667         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, NULL
, serviceID
, NULL
); 
 668         assert(servicePrivate 
!= NULL
); 
 670                 servicePrivate
->store 
= CFRetain(store
); 
 672         return (SCNetworkServiceRef
)servicePrivate
; 
 677 SCNetworkServiceCopyProtocol(SCNetworkServiceRef service
, CFStringRef protocolType
) 
 679         CFSetRef                        non_protocol_entities
; 
 681         CFDictionaryRef                 protocols
; 
 682         SCNetworkProtocolPrivateRef     protocolPrivate 
= NULL
; 
 683         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 685         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 686                 _SCErrorSet(kSCStatusInvalidArgument
); 
 690         if (!isA_CFString(protocolType
)) { 
 691                 _SCErrorSet(kSCStatusInvalidArgument
); 
 695         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 696                                                               servicePrivate
->serviceID
,        // service 
 698         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 701         if (!isA_CFDictionary(protocols
)) { 
 703                 _SCErrorSet(kSCStatusFailed
); 
 707         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 708         if (CFSetContainsValue(non_protocol_entities
, protocolType
)) { 
 709                 // if the "protocolType" matches an interface entity type 
 710                 _SCErrorSet(kSCStatusInvalidArgument
); 
 714         if (!CFDictionaryContainsKey(protocols
, protocolType
)) { 
 715                 // if the "protocolType" entity does not exist 
 716                 _SCErrorSet(kSCStatusNoKey
); 
 720         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, protocolType
, service
); 
 724         CFRelease(non_protocol_entities
); 
 726         return (SCNetworkProtocolRef
)protocolPrivate
; 
 730 CFArrayRef 
/* of SCNetworkProtocolRef's */ 
 731 SCNetworkServiceCopyProtocols(SCNetworkServiceRef service
) 
 733         CFMutableArrayRef               array
; 
 735         CFSetRef                        non_protocol_entities
; 
 737         CFDictionaryRef                 protocols
; 
 738         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
 740         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
 741                 _SCErrorSet(kSCStatusInvalidArgument
); 
 745         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 746                                                               servicePrivate
->serviceID
,        // service 
 748         protocols 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
 751         if (!isA_CFDictionary(protocols
)) { 
 753                 _SCErrorSet(kSCStatusFailed
); 
 757         non_protocol_entities 
= _copyInterfaceEntityTypes(protocols
); 
 759         array 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 761         n 
= CFDictionaryGetCount(protocols
); 
 764                 const void *                    keys_q
[N_QUICK
]; 
 765                 const void **                   keys            
= keys_q
; 
 766                 const void *                    vals_q
[N_QUICK
]; 
 767                 const void **                   vals            
= vals_q
; 
 769                 if (n 
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) { 
 770                         keys 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFTypeRef
), 0); 
 771                         vals 
= CFAllocatorAllocate(NULL
, n 
* sizeof(CFPropertyListRef
), 0); 
 773                 CFDictionaryGetKeysAndValues(protocols
, keys
, vals
); 
 774                 for (i 
= 0; i 
< n
; i
++) { 
 775                         SCNetworkProtocolPrivateRef     protocolPrivate
; 
 777                         if (!isA_CFDictionary(vals
[i
])) { 
 778                                 // if it's not a dictionary then it can't be a protocol entity 
 782                         if (CFSetContainsValue(non_protocol_entities
, keys
[i
])) { 
 783                                 // skip any non-protocol (interface) entities 
 787                         protocolPrivate 
= __SCNetworkProtocolCreatePrivate(NULL
, keys
[i
], service
); 
 788                         CFArrayAppendValue(array
, (SCNetworkProtocolRef
)protocolPrivate
); 
 790                         CFRelease(protocolPrivate
); 
 792                 if (keys 
!= keys_q
) { 
 793                         CFAllocatorDeallocate(NULL
, keys
); 
 794                         CFAllocatorDeallocate(NULL
, vals
); 
 798         CFRelease(non_protocol_entities
); 
 805 __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef     service
, 
 806                                      SCNetworkInterfaceRef   interface
) 
 808         CFDictionaryRef                 entity
; 
 811         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
 813         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 814                                                               servicePrivate
->serviceID
,        // service 
 815                                                               kSCEntNetInterface
);              // entity 
 816         entity 
= __SCNetworkInterfaceCopyInterfaceEntity(interface
); 
 817         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, entity
); 
 826 SCNetworkServiceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
) 
 828         CFArrayRef                      components
; 
 829         CFArrayRef                      interface_config
; 
 830         CFStringRef                     interface_name
; 
 831         SCNetworkInterfaceRef           newInterface
; 
 834         CFStringRef                     serviceID
; 
 835         SCNetworkServicePrivateRef      servicePrivate
; 
 836         CFArrayRef                      supported_protocols
; 
 838         if (!isA_SCNetworkInterface(interface
)) { 
 839                 _SCErrorSet(kSCStatusInvalidArgument
); 
 843         // only allow network interfaces which support one or more protocols 
 844         // to be added to a service.  The one exception is that we allow 
 845         // third-party interface types to be configured. 
 846         supported_protocols 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
 847         if (supported_protocols 
== NULL
) { 
 848                 CFStringRef     interface_type
; 
 850                 interface_type 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 851                 if (CFStringFind(interface_type
, CFSTR("."), 0).location 
== kCFNotFound
) { 
 852                         _SCErrorSet(kSCStatusInvalidArgument
); 
 857         // do not allow creation of a network service if the interface is a 
 858         // member of a bond or bridge 
 859         if (__SCNetworkInterfaceIsMember(prefs
, interface
)) { 
 860                 _SCErrorSet(kSCStatusKeyExists
); 
 864         // establish the service 
 865         prefix 
= SCPreferencesPathKeyCreateNetworkServices(NULL
); 
 866         path 
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
); 
 867         if (path 
== NULL
) path 
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
); 
 873         components 
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/")); 
 876         serviceID 
= CFArrayGetValueAtIndex(components
, 2); 
 877         servicePrivate 
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
); 
 878         CFRelease(components
); 
 880         // duplicate the interface and associate the copy with the new service 
 881         newInterface 
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, 
 885         servicePrivate
->interface 
= newInterface
; 
 887         // establish "default" configuration(s) for the interface 
 888         for (interface 
= newInterface
; 
 890              interface 
= SCNetworkInterfaceGetInterface(interface
)) { 
 891                 SCNetworkInterfaceRef   childInterface
; 
 892                 CFStringRef             childInterfaceType      
= NULL
; 
 893                 CFDictionaryRef         config
; 
 894                 CFStringRef             interfaceType
; 
 896                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
 897                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
 898                 if (childInterface 
!= NULL
) { 
 899                         childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
 902                 config 
= __copyInterfaceTemplate(interfaceType
, childInterfaceType
); 
 903                 if (config 
!= NULL
) { 
 904                         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBluetooth
) || 
 905                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeIrDA     
) || 
 906                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem    
) || 
 907                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeSerial   
) || 
 908                             CFEqual(interfaceType
, kSCNetworkInterfaceTypeWWAN     
)) { 
 909                                 CFDictionaryRef         overrides
; 
 911                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypeModem
); 
 913                                 // a ConnectionScript (and related keys) from the interface 
 914                                 // should trump the settings from the configuration template. 
 915                                 if (isA_CFDictionary(overrides
)) { 
 916                                         CFMutableDictionaryRef  newConfig
; 
 918                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 919                                         if (CFDictionaryContainsKey(overrides
, kSCPropNetModemConnectionScript
)) { 
 920                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionPersonality
); 
 921                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionScript
); 
 922                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceVendor
); 
 923                                                 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceModel
); 
 925                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 929                         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
) || 
 930                                    CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
 931                                 CFDictionaryRef         overrides
; 
 933                                 overrides 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypePPP
); 
 934                                 if (isA_CFDictionary(overrides
)) { 
 935                                         CFMutableDictionaryRef  newConfig
; 
 937                                         newConfig 
= CFDictionaryCreateMutableCopy(NULL
, 0, config
); 
 938                                         CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
); 
 944                         if (!__SCNetworkInterfaceSetConfiguration(interface
, NULL
, config
, TRUE
)) { 
 945                                 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL", 
 952         // add the interface [entity] to the service 
 953         (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef
)servicePrivate
, 
 954                                                     servicePrivate
->interface
); 
 956         // push the [deep] interface configuration into the service. 
 957         interface_config 
= __SCNetworkInterfaceCopyDeepConfiguration(NULL
, servicePrivate
->interface
); 
 958         __SCNetworkInterfaceSetDeepConfiguration(NULL
, servicePrivate
->interface
, interface_config
); 
 959         if (interface_config 
!= NULL
) CFRelease(interface_config
); 
 961         // set the service name to match that of the associated interface 
 963         // Note: It might seem a bit odd to call SCNetworkServiceGetName 
 964         // followed by an immediate call to SCNetworkServiceSetName.  The 
 965         // trick here is that if no name has previously been set, the 
 966         // "get" function will return the name of the associated interface. 
 968         // ... and we "set" a name to ensure that applications that do 
 969         // not use the APIs will still find a UserDefinedName property 
 970         // in the SCDynamicStore. 
 972         interface_name 
= SCNetworkServiceGetName((SCNetworkServiceRef
)servicePrivate
); 
 973         if (interface_name 
!= NULL
) { 
 974                 (void) SCNetworkServiceSetName((SCNetworkServiceRef
)servicePrivate
, 
 978         SC_log(LOG_DEBUG
, "SCNetworkServiceCreate(): %@", servicePrivate
); 
 980         return (SCNetworkServiceRef
)servicePrivate
; 
 984 static CF_RETURNS_RETAINED CFStringRef
 
 985 copyInterfaceUUID(CFStringRef bsdName
) 
 988                 unsigned char   sha256_bytes
[CC_SHA256_DIGEST_LENGTH
]; 
 989                 CFUUIDBytes     uuid_bytes
; 
 992         char            if_name
[IF_NAMESIZE
]; 
 994         CFStringRef     uuid_str
; 
 996         // start with interface name 
 997         memset(&if_name
, 0, sizeof(if_name
)); 
 998         (void) _SC_cfstring_to_cstring(bsdName
, 
1001                                        kCFStringEncodingASCII
); 
1003         // create SHA256 hash 
1004         memset(&bytes
, 0, sizeof(bytes
)); 
1005         CC_SHA256_Init(&ctx
); 
1006         CC_SHA256_Update(&ctx
, 
1009         CC_SHA256_Final(bytes
.sha256_bytes
, &ctx
); 
1011         // create UUID string 
1012         uuid 
= CFUUIDCreateFromUUIDBytes(NULL
, bytes
.uuid_bytes
); 
1013         uuid_str 
= CFUUIDCreateString(NULL
, uuid
); 
1021 _SCNetworkServiceCreatePreconfigured(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
) 
1023         CFStringRef             bsdName
; 
1025         SCNetworkServiceRef     service
; 
1026         CFStringRef             serviceID
; 
1028         bsdName 
= SCNetworkInterfaceGetBSDName(interface
); 
1030         // create network service 
1031         service 
= SCNetworkServiceCreate(prefs
, interface
); 
1032         if (service 
== NULL
) { 
1033                 SC_log(LOG_ERR
, "could not create network service for \"%@\": %s", 
1035                        SCErrorString(SCError())); 
1039         // update network service to use a consistent serviceID 
1040         serviceID 
= copyInterfaceUUID(bsdName
); 
1041         if (serviceID 
!= NULL
) { 
1042                 ok 
= _SCNetworkServiceSetServiceID(service
, serviceID
); 
1043                 CFRelease(serviceID
); 
1045                         SC_log(LOG_ERR
, "_SCNetworkServiceSetServiceID() failed: %s", 
1046                                SCErrorString(SCError())); 
1047                         // ... and keep whatever random UUID was created for the service 
1050                 SC_log(LOG_ERR
, "could not create serviceID for \"%@\"", bsdName
); 
1051                 // ... and we'll use whatever random UUID was created for the service 
1054         // establish [template] configuration 
1055         ok 
= SCNetworkServiceEstablishDefaultConfiguration(service
); 
1057                 SC_log(LOG_ERR
, "could not establish network service for \"%@\": %s", 
1059                        SCErrorString(SCError())); 
1060                 SCNetworkServiceRemove(service
); 
1070 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service
) 
1073         SCNetworkInterfaceRef           interface
; 
1076         CFArrayRef                      protocolTypes
; 
1077         CFStringRef                     rankStr
; 
1078         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1080         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1081                 _SCErrorSet(kSCStatusInvalidArgument
); 
1085         interface 
= SCNetworkServiceGetInterface(service
); 
1086         if (interface 
== NULL
) { 
1090         protocolTypes 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
1091         n 
= (protocolTypes 
!= NULL
) ? CFArrayGetCount(protocolTypes
) : 0; 
1092         for (i 
= 0; i 
< n
; i
++) { 
1093                 CFStringRef     protocolType
; 
1095                 protocolType 
= CFArrayGetValueAtIndex(protocolTypes
, i
); 
1096                 ok 
= SCNetworkServiceAddProtocolType(service
, protocolType
); 
1099                                "SCNetworkServiceEstablishDefaultConfiguration(): could not add protocol \"%@\"", 
1104         rankStr 
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCPropNetServicePrimaryRank
); 
1105         if (isA_CFString(rankStr
)) { 
1106                 SCNetworkServicePrimaryRank     rank
; 
1108                 ok 
= __str_to_rank(rankStr
, &rank
); 
1111                                "SCNetworkServiceEstablishDefaultConfiguration(): unknown rank \"%@\"", 
1116                 ok 
= SCNetworkServiceSetPrimaryRank(service
, rank
); 
1119                                "SCNetworkServiceEstablishDefaultConfiguration(): could not set rank \"%@\"", 
1132 SCNetworkServiceGetEnabled(SCNetworkServiceRef service
) 
1136         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1138         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1139                 _SCErrorSet(kSCStatusInvalidArgument
); 
1143         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1144                                                               servicePrivate
->serviceID
,        // service 
1146         enabled 
= __getPrefsEnabled(servicePrivate
->prefs
, path
); 
1153 SCNetworkInterfaceRef
 
1154 SCNetworkServiceGetInterface(SCNetworkServiceRef service
) 
1156         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1158         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1159                 _SCErrorSet(kSCStatusInvalidArgument
); 
1163         if (servicePrivate
->interface 
== NULL
) { 
1164                 CFDictionaryRef entity
; 
1167                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1168                                                                       servicePrivate
->serviceID
,        // service 
1169                                                                       kSCEntNetInterface
);              // entity 
1170                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1173                 if (isA_CFDictionary(entity
)) { 
1174                         servicePrivate
->interface 
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, service
); 
1178         return servicePrivate
->interface
; 
1183 SCNetworkServiceGetName(SCNetworkServiceRef service
) 
1185         CFDictionaryRef                 entity
; 
1186         SCNetworkInterfaceRef           interface
; 
1187         CFStringRef                     name            
= NULL
; 
1189         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1190         Boolean                         useSystemInterfaces 
= TRUE
; 
1192         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1193                 _SCErrorSet(kSCStatusInvalidArgument
); 
1197         if (servicePrivate
->name 
!= NULL
) { 
1198                 return servicePrivate
->name
; 
1201         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1202                                                               servicePrivate
->serviceID
,        // service 
1204         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1207         useSystemInterfaces 
= !_SCNetworkConfigurationBypassSystemInterfaces(servicePrivate
->prefs
); 
1209         if (isA_CFDictionary(entity
)) { 
1210                 name 
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
); 
1211                 if (isA_CFString(name
)) { 
1212                         servicePrivate
->name 
= CFRetain(name
); 
1213                         if (!useSystemInterfaces
) { 
1214                                 return servicePrivate
->name
; 
1219         interface 
= SCNetworkServiceGetInterface(service
); 
1220         while (interface 
!= NULL
) { 
1221                 SCNetworkInterfaceRef   childInterface
; 
1222                 CFStringRef             interfaceType
; 
1224                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1225                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1229                 childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1230                 if ((childInterface 
== NULL
) || 
1231                     CFEqual(childInterface
, kSCNetworkInterfaceIPv4
)) { 
1235                 interface 
= childInterface
; 
1238         if (interface 
!= NULL
) { 
1240                 CFStringRef     interface_name  
= NULL
; 
1241                 CFStringRef     suffix          
= NULL
; 
1244                 // check if the [stored] service name matches the non-localized interface 
1245                 // name.  If so, return the localized name. 
1247                 // Also, the older "Built-in XXX" interface names are too long for the 
1248                 // current UI. If we find that the [stored] service name matches the older 
1249                 // name, return the newer (and shorter) localized name. 
1251                 // Note: the user/admin will no longer be able to set the service name 
1252                 //       to "Built-in Ethernet". 
1254                 for (i 
= 0; i 
< 3; i
++) { 
1255                         if (servicePrivate
->name 
== NULL
) { 
1256                                 // if no [stored] service name to compare 
1262                                         // compare the non-localized interface name 
1263                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1264                                         if (interface_name 
!= NULL
) { 
1265                                                 CFRetain(interface_name
); 
1268 #if     !TARGET_OS_IPHONE 
1270                                         // compare the older "Built-in XXX" localized name 
1271                                         interface_name 
= __SCNetworkInterfaceCopyXLocalizedDisplayName(interface
); 
1274                                         // compare the older "Built-in XXX" non-localized name 
1275                                         interface_name 
= __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface
); 
1277 #else   // !TARGET_OS_IPHONE 
1280 #endif  // !TARGET_OS_IPHONE 
1283                         if (interface_name 
!= NULL
) { 
1284                                 Boolean match   
= FALSE
; 
1286                                 if (CFEqual(name
, interface_name
)) { 
1287                                         // if service name matches the OLD localized 
1290                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1291                                         CFIndex prefixLen       
= CFStringGetLength(interface_name
); 
1292                                         CFIndex suffixLen       
= CFStringGetLength(name
); 
1294                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1296                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1299                                 CFRelease(interface_name
); 
1302                                         CFRelease(servicePrivate
->name
); 
1303                                         servicePrivate
->name 
= NULL
; 
1310                 // if the service name has not been set, use the localized interface name 
1312                 if (servicePrivate
->name 
== NULL
) { 
1313                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1314                         if (interface_name 
!= NULL
) { 
1315                                 if (suffix 
!= NULL
) { 
1316                                         servicePrivate
->name 
= CFStringCreateWithFormat(NULL
, 
1322                                         servicePrivate
->name 
= CFRetain(interface_name
); 
1326                 if (suffix 
!= NULL
) CFRelease(suffix
); 
1329         return servicePrivate
->name
; 
1334 SCNetworkServiceGetServiceID(SCNetworkServiceRef service
) 
1336         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1338         if (!isA_SCNetworkService(service
)) { 
1339                 _SCErrorSet(kSCStatusInvalidArgument
); 
1343         return servicePrivate
->serviceID
; 
1348 SCNetworkServiceGetTypeID(void) 
1350         pthread_once(&initialized
, __SCNetworkServiceInitialize
);       /* initialize runtime */ 
1351         return __kSCNetworkServiceTypeID
; 
1356 SCNetworkServiceRemove(SCNetworkServiceRef service
) 
1360         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1363         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1364                 _SCErrorSet(kSCStatusInvalidArgument
); 
1368         if (!__SCNetworkServiceExists(service
)) { 
1369                 SC_log(LOG_ERR
, "SCNetworkServiceRemove() w/removed service\n  service = %@", service
); 
1370                 _SC_crash_once("SCNetworkServiceRemove() w/removed service", NULL
, NULL
); 
1371                 _SCErrorSet(kSCStatusInvalidArgument
); 
1375         // remove service from all sets 
1377         sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1381                 n 
= CFArrayGetCount(sets
); 
1382                 for (CFIndex i 
= 0; i 
< n
; i
++) { 
1383                         SCNetworkSetRef set
; 
1385                         set 
= CFArrayGetValueAtIndex(sets
, i
); 
1386                         ok 
= SCNetworkSetRemoveService(set
, service
); 
1387                         if (!ok 
&& (SCError() != kSCStatusNoKey
)) { 
1397         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1398                                                               servicePrivate
->serviceID
,        // service 
1400         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1404                 SC_log(LOG_DEBUG
, "SCNetworkServiceRemove(): %@", service
); 
1412 SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
) 
1414         CFDictionaryRef                 entity
; 
1417         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1419         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1420                 _SCErrorSet(kSCStatusInvalidArgument
); 
1424         if (!__SCNetworkServiceExists(service
)) { 
1425                 SC_log(LOG_ERR
, "SCNetworkServiceRemoveProtocolType() w/removed service\n  service = %@\n  protocol = %@", 
1428                 _SC_crash_once("SCNetworkServiceRemoveProtocolType() w/removed service", NULL
, NULL
); 
1429                 _SCErrorSet(kSCStatusInvalidArgument
); 
1433         if (!__SCNetworkProtocolIsValidType(protocolType
)) { 
1434                 _SCErrorSet(kSCStatusInvalidArgument
); 
1438         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1439                                                               servicePrivate
->serviceID
,        // service 
1440                                                               protocolType
);                    // entity 
1442         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1443         if (entity 
== NULL
) { 
1444                 // if "protocol" does not exist 
1445                 _SCErrorSet(kSCStatusNoKey
); 
1449         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1454                 SC_log(LOG_DEBUG
, "SCNetworkServiceRemoveProtocolType(): %@, %@", service
, protocolType
); 
1463 SCNetworkServiceSetEnabled(SCNetworkServiceRef service
, Boolean enabled
) 
1467         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1469         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1470                 _SCErrorSet(kSCStatusInvalidArgument
); 
1474         if (!__SCNetworkServiceExists(service
)) { 
1475                 SC_log(LOG_ERR
, "SCNetworkServiceSetEnabled() w/removed service\n  service = %@", service
); 
1476                 _SC_crash_once("SCNetworkProtocolSetEnabled() w/removed service", NULL
, NULL
); 
1477                 _SCErrorSet(kSCStatusInvalidArgument
); 
1481         // make sure that we do not enable a network service if the 
1482         // associated interface is a member of a bond or bridge. 
1484                 SCNetworkInterfaceRef   interface
; 
1486                 interface 
= SCNetworkServiceGetInterface(service
); 
1487                 if ((interface 
!= NULL
) && 
1488                     __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) { 
1489                         _SCErrorSet(kSCStatusKeyExists
); 
1494         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1495                                                               servicePrivate
->serviceID
,        // service 
1497         ok 
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
); 
1501                 SC_log(LOG_DEBUG
, "SCNetworkServiceSetEnabled(): %@ -> %s", 
1503                        enabled 
? "Enabled" : "Disabled"); 
1511 SCNetworkServiceSetName(SCNetworkServiceRef service
, CFStringRef name
) 
1513         CFDictionaryRef                 entity
; 
1516         CFStringRef                     saveName        
= NULL
; 
1517         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1519         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
1520                 _SCErrorSet(kSCStatusInvalidArgument
); 
1524         if (!__SCNetworkServiceExists(service
)) { 
1525                 SC_log(LOG_ERR
, "SCNetworkServiceSetName() w/removed service\n  service = %@\n  name = %@", 
1527                        name 
!= NULL 
? name 
: CFSTR("<NULL>")); 
1528                 _SC_crash_once("SCNetworkServiceSetName() w/removed service", NULL
, NULL
); 
1529                 _SCErrorSet(kSCStatusInvalidArgument
); 
1534                 if (!isA_CFString(name
)) { 
1535                         _SCErrorSet(kSCStatusInvalidArgument
); 
1538                 saveName 
= CFRetain(name
); 
1542                 SCNetworkInterfaceRef   interface
; 
1544                 interface 
= SCNetworkServiceGetInterface(service
); 
1545                 while (interface 
!= NULL
) { 
1546                         SCNetworkInterfaceRef   childInterface
; 
1548                         childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
1549                         if (childInterface 
== NULL
) { 
1553                         interface 
= childInterface
; 
1556                 if (interface 
!= NULL
) { 
1557                         CFStringRef     interface_name
; 
1559                         interface_name 
= SCNetworkInterfaceGetLocalizedDisplayName(interface
); 
1560                         if (interface_name 
!= NULL
) { 
1561                                 if (CFEqual(name
, interface_name
)) { 
1562                                         // if service name matches the localized interface name 
1563                                         // then store the non-localized name. 
1564                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1565                                         if (interface_name 
!= NULL
) { 
1566                                                 CFRelease(saveName
); 
1567                                                 saveName 
= CFRetain(interface_name
); 
1569                                 } else if (CFStringHasPrefix(name
, interface_name
)) { 
1570                                         CFIndex         prefixLen       
= CFStringGetLength(interface_name
); 
1572                                         CFIndex         suffixLen       
= CFStringGetLength(name
); 
1574                                         // if service name matches the localized interface name plus 
1575                                         // a few extra characters) then store the non-localized name with 
1577                                         suffix 
= CFStringCreateWithSubstring(NULL
, 
1579                                                                              CFRangeMake(prefixLen
, suffixLen 
- prefixLen
)); 
1580                                         interface_name 
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
); 
1581                                         if (interface_name 
!= NULL
) { 
1582                                                 CFRelease(saveName
); 
1583                                                 saveName 
= CFStringCreateWithFormat(NULL
, 
1595 #define PREVENT_DUPLICATE_SERVICE_NAMES 
1596 #ifdef  PREVENT_DUPLICATE_SERVICE_NAMES 
1600                 // ensure that each service is uniquely named within its sets 
1602                 sets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
1607                         set_count 
= CFArrayGetCount(sets
); 
1608                         for (set_index 
= 0; set_index 
< set_count
; set_index
++) { 
1609                                 CFIndex         service_index
; 
1610                                 Boolean         isDup           
= FALSE
; 
1611                                 Boolean         isMember        
= FALSE
; 
1612                                 CFIndex         service_count
; 
1613                                 CFArrayRef      services
; 
1614                                 SCNetworkSetRef set             
= CFArrayGetValueAtIndex(sets
, set_index
); 
1616                                 services 
= SCNetworkSetCopyServices(set
); 
1618                                 service_count 
= CFArrayGetCount(services
); 
1619                                 for (service_index 
= 0; service_index 
< service_count
; service_index
++) { 
1620                                         CFStringRef             otherID
; 
1621                                         CFStringRef             otherName
; 
1622                                         SCNetworkServiceRef     otherService
; 
1624                                         otherService 
= CFArrayGetValueAtIndex(services
, service_index
); 
1626                                         otherID 
= SCNetworkServiceGetServiceID(otherService
); 
1627                                         if (CFEqual(servicePrivate
->serviceID
, otherID
)) { 
1628                                                 // if the service is a member of this set 
1633                                         otherName 
= SCNetworkServiceGetName(otherService
); 
1634                                         if ((otherName 
!= NULL
) && CFEqual(name
, otherName
)) { 
1640                                 CFRelease(services
); 
1642                                 if (isMember 
&& isDup
) { 
1644                                          * if this service is a member of the set and 
1645                                          * the "name" is not unique. 
1648                                         if (saveName 
!= NULL
) CFRelease(saveName
); 
1649                                         _SCErrorSet(kSCStatusKeyExists
); 
1657 #endif  /* PREVENT_DUPLICATE_SERVICE_NAMES */ 
1659         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1660                                                               servicePrivate
->serviceID
,        // service 
1662         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1663         if (isA_CFDictionary(entity
) || 
1664             ((entity 
== NULL
) && (name 
!= NULL
))) { 
1665                 CFMutableDictionaryRef  newEntity
; 
1667                 if (entity 
!= NULL
) { 
1668                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1670                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1672                                                               &kCFTypeDictionaryKeyCallBacks
, 
1673                                                               &kCFTypeDictionaryValueCallBacks
); 
1675                 if (saveName 
!= NULL
) { 
1676                         CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, saveName
); 
1678                         CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
); 
1680                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1681                 CFRelease(newEntity
); 
1684         if (saveName 
!= NULL
) CFRelease(saveName
); 
1686         if (servicePrivate
->name 
!= NULL
) CFRelease(servicePrivate
->name
); 
1687         if (name 
!= NULL
) CFRetain(name
); 
1688         servicePrivate
->name 
= name
; 
1691                 SC_log(LOG_DEBUG
, "SCNetworkServiceSetName(): %@", service
); 
1699 #pragma mark SCNetworkService SPIs 
1704 __SCNetworkServiceExists(SCNetworkServiceRef service
) 
1706         CFDictionaryRef                 entity
; 
1708         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1710         if (servicePrivate
->prefs 
== NULL
) { 
1715         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
1716                                                               servicePrivate
->serviceID
,        // service 
1717                                                               kSCEntNetInterface
);               // entity 
1718         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1721         if (!isA_CFDictionary(entity
)) { 
1722                 // a "service" must have an "interface" 
1730 SCNetworkServicePrimaryRank
 
1731 SCNetworkServiceGetPrimaryRank(SCNetworkServiceRef service
) 
1733         CFDictionaryRef                 entity
; 
1736         SCNetworkServicePrimaryRank     rank            
= kSCNetworkServicePrimaryRankDefault
; 
1737         CFStringRef                     rankStr         
= NULL
; 
1738         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1740         if (!isA_SCNetworkService(service
)) { 
1741                 _SCErrorSet(kSCStatusInvalidArgument
); 
1745         if (servicePrivate
->prefs 
!= NULL
) { 
1746                 path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1747                                                                       servicePrivate
->serviceID
, 
1749                 entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1751                 if (isA_CFDictionary(entity
)) { 
1752                         rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1753                         ok 
= __str_to_rank(rankStr
, &rank
); 
1755         } else if (servicePrivate
->store 
!= NULL
) { 
1756                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1757                                                                    kSCDynamicStoreDomainState
, 
1758                                                                    servicePrivate
->serviceID
, 
1760                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1762                 if (entity 
!= NULL
) { 
1763                         if (isA_CFDictionary(entity
)) { 
1764                                 rankStr 
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
); 
1765                                 ok 
= __str_to_rank(rankStr
, &rank
); 
1770                 _SCErrorSet(kSCStatusInvalidArgument
); 
1775                 rank 
= kSCNetworkServicePrimaryRankDefault
; 
1776                 _SCErrorSet(kSCStatusInvalidArgument
); 
1777         } else if (rank 
== kSCNetworkServicePrimaryRankDefault
) { 
1778                 _SCErrorSet(kSCStatusOK
); 
1786 SCNetworkServiceSetPrimaryRank(SCNetworkServiceRef              service
, 
1787                                SCNetworkServicePrimaryRank      newRank
) 
1790         CFDictionaryRef                 entity
; 
1791         CFMutableDictionaryRef          newEntity
; 
1792         CFStringRef                     path            
= NULL
; 
1793         CFStringRef                     rankStr         
= NULL
; 
1794         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
1796         if (!isA_SCNetworkService(service
)) { 
1797                 _SCErrorSet(kSCStatusInvalidArgument
); 
1801         if ((servicePrivate
->prefs 
!= NULL
) && !__SCNetworkServiceExists(service
)) { 
1802                 SC_log(LOG_ERR
, "SCNetworkServiceSetPrimaryRank() w/removed\n  service = %@", service
); 
1803                 _SC_crash_once("SCNetworkServiceSetPrimaryRank() w/removed service", NULL
, NULL
); 
1804                 _SCErrorSet(kSCStatusInvalidArgument
); 
1808         ok 
= __rank_to_str(newRank
, &rankStr
); 
1810                 _SCErrorSet(kSCStatusInvalidArgument
); 
1814         if (servicePrivate
->prefs 
!= NULL
) { 
1816                 case kSCNetworkServicePrimaryRankDefault
: 
1817                 case kSCNetworkServicePrimaryRankNever
: 
1818                 case kSCNetworkServicePrimaryRankScoped
: 
1819                         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1820                                                                               servicePrivate
->serviceID
, 
1822                         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
); 
1823                         if (entity 
!= NULL
) { 
1824                                 if (!isA_CFDictionary(entity
)) { 
1826                                         _SCErrorSet(kSCStatusFailed
); 
1829                                 newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1831                                 newEntity 
= CFDictionaryCreateMutable(NULL
, 
1833                                                                       &kCFTypeDictionaryKeyCallBacks
, 
1834                                                                       &kCFTypeDictionaryValueCallBacks
); 
1836                         if (rankStr 
!= NULL
) { 
1837                                 CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1839                                 CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1841                         if (CFDictionaryGetCount(newEntity
) > 0) { 
1842                                 ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
); 
1844                                 ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
); 
1846                         CFRelease(newEntity
); 
1852                         _SCErrorSet(kSCStatusInvalidArgument
); 
1855         } else if (servicePrivate
->store 
!= NULL
) { 
1856                 path 
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, 
1857                                                                    kSCDynamicStoreDomainState
, 
1858                                                                    servicePrivate
->serviceID
, 
1860                 entity 
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
); 
1861                 if (entity 
!= NULL
) { 
1862                         if (!isA_CFDictionary(entity
)) { 
1865                                 _SCErrorSet(kSCStatusFailed
); 
1868                         newEntity 
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
); 
1871                         newEntity 
= CFDictionaryCreateMutable(NULL
, 
1873                                                               &kCFTypeDictionaryKeyCallBacks
, 
1874                                                               &kCFTypeDictionaryValueCallBacks
); 
1876                 if (rankStr 
!= NULL
) { 
1877                         CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
); 
1879                         CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
); 
1881                 if (CFDictionaryGetCount(newEntity
) > 0) { 
1882                         ok 
= SCDynamicStoreSetValue(servicePrivate
->store
, path
, newEntity
); 
1884                         ok 
= SCDynamicStoreRemoveValue(servicePrivate
->store
, path
); 
1886                 CFRelease(newEntity
); 
1891                 _SCErrorSet(kSCStatusInvalidArgument
); 
1897         if (path 
!= NULL
)       CFRelease(path
); 
1903 _SCNetworkServiceIsVPN(SCNetworkServiceRef service
) 
1905         SCNetworkInterfaceRef   interface
; 
1906         CFStringRef             interfaceType
; 
1908         interface 
= SCNetworkServiceGetInterface(service
); 
1909         if (interface 
== NULL
) { 
1913         interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1914         if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
1915                 interface 
= SCNetworkInterfaceGetInterface(interface
); 
1916                 if (interface 
== NULL
) { 
1920                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(interface
); 
1921                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
1924 #pragma GCC diagnostic push 
1925 #pragma GCC diagnostic ignored "-Wdeprecated" 
1926                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) { 
1929 #pragma GCC diagnostic pop 
1930         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) { 
1932         } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) { 
1941 SCNetworkServiceSetExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
, CFStringRef identifier
) 
1943         CFStringRef                     prefs_path
; 
1944         CFDictionaryRef                 service_dictionary
; 
1945         SCNetworkServicePrivateRef      servicePrivate          
= (SCNetworkServicePrivateRef
)service
; 
1946         Boolean                         success                 
= FALSE
; 
1947         CFStringRef                     prefixed_domain
; 
1949         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
) || !isA_CFString(identifierDomain
)) { 
1950                 _SCErrorSet(kSCStatusInvalidArgument
); 
1954         if (!__SCNetworkServiceExists(service
)) { 
1955                 SC_log(LOG_ERR
, "SCNetworkServiceSetExternalID() w/removed\n  service = %@\n  id = %@", 
1958                 _SC_crash_once("SCNetworkServiceSetExternalID() w/removed service", NULL
, NULL
); 
1959                 _SCErrorSet(kSCStatusInvalidArgument
); 
1963         if (identifier 
!= NULL 
&& !isA_CFString(identifier
)) { 
1964                 _SCErrorSet(kSCStatusInvalidArgument
); 
1968         prefixed_domain 
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
); 
1970         prefs_path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
1971                                                                     servicePrivate
->serviceID
, 
1974         service_dictionary 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, prefs_path
); 
1975         if (isA_CFDictionary(service_dictionary
) || ((service_dictionary 
== NULL
) && (identifier 
!= NULL
))) { 
1976                 CFMutableDictionaryRef  new_service_dictionary
; 
1978                 if (service_dictionary 
!= NULL
) { 
1979                         new_service_dictionary 
= CFDictionaryCreateMutableCopy(NULL
, 0, service_dictionary
); 
1981                         new_service_dictionary 
= CFDictionaryCreateMutable(NULL
, 
1983                                                                            &kCFTypeDictionaryKeyCallBacks
, 
1984                                                                            &kCFTypeDictionaryValueCallBacks
); 
1987                 if (identifier 
!= NULL
) { 
1988                         CFDictionarySetValue(new_service_dictionary
, prefixed_domain
, identifier
); 
1990                         CFDictionaryRemoveValue(new_service_dictionary
, prefixed_domain
); 
1992                 success 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, prefs_path
, new_service_dictionary
); 
1993                 CFRelease(new_service_dictionary
); 
1995         CFRelease(prefs_path
); 
1997         if (identifier 
!= NULL
) { 
1998             if (servicePrivate
->externalIDs 
== NULL
) { 
1999                         servicePrivate
->externalIDs 
= CFDictionaryCreateMutable(NULL
, 
2001                                                                                  &kCFTypeDictionaryKeyCallBacks
, 
2002                                                                                  &kCFTypeDictionaryValueCallBacks
); 
2004             CFDictionarySetValue(servicePrivate
->externalIDs
, prefixed_domain
, identifier
); 
2006             if (servicePrivate
->externalIDs 
!= NULL
) { 
2007                         CFDictionaryRemoveValue(servicePrivate
->externalIDs
, prefixed_domain
); 
2011         CFRelease(prefixed_domain
); 
2014                 _SCErrorSet(kSCStatusFailed
); 
2022 SCNetworkServiceCopyExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
) 
2024         CFStringRef                     identifier              
= NULL
; 
2025         CFStringRef                     prefixed_domain
; 
2026         SCNetworkServicePrivateRef      service_private         
= (SCNetworkServicePrivateRef
)service
; 
2028         if (!isA_SCNetworkService(service
) || (service_private
->prefs 
== NULL
) || !isA_CFString(identifierDomain
)) { 
2029                 _SCErrorSet(kSCStatusInvalidArgument
); 
2033         prefixed_domain 
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
); 
2035         if (service_private
->externalIDs 
!= NULL
) { 
2036                 identifier 
= CFDictionaryGetValue(service_private
->externalIDs
, prefixed_domain
); 
2037                 if (identifier 
!= NULL
) { 
2038                         CFRetain(identifier
); 
2042         if (identifier 
== NULL
) { 
2043                 CFStringRef             prefs_path
; 
2044                 CFDictionaryRef         service_dictionary
; 
2046                 prefs_path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, 
2047                                                                             service_private
->serviceID
, 
2050                 service_dictionary 
= SCPreferencesPathGetValue(service_private
->prefs
, prefs_path
); 
2051                 if (isA_CFDictionary(service_dictionary
)) { 
2052                         identifier 
= CFDictionaryGetValue(service_dictionary
, prefixed_domain
); 
2053                         if (identifier 
!= NULL
) { 
2054                                 CFRetain(identifier
); 
2055                                 if (service_private
->externalIDs 
== NULL
) { 
2056                                         service_private
->externalIDs 
= CFDictionaryCreateMutable(NULL
, 
2058                                                                                                  &kCFTypeDictionaryKeyCallBacks
, 
2059                                                                                                  &kCFTypeDictionaryValueCallBacks
); 
2061                                 CFDictionarySetValue(service_private
->externalIDs
, prefixed_domain
, identifier
); 
2064                 CFRelease(prefs_path
); 
2067         CFRelease(prefixed_domain
); 
2069         if (identifier 
== NULL
) { 
2070                 _SCErrorSet(kSCStatusNoKey
); 
2078         CFStringRef     oldServiceID
; 
2079         CFStringRef     newServiceID
; 
2080 } serviceContext
, *serviceContextRef
; 
2084 replaceServiceID(const void *value
, void *context
) 
2086         CFStringRef             link            
= NULL
; 
2087         CFStringRef             oldLink
; 
2088         CFMutableArrayRef       newServiceOrder
; 
2090         serviceContextRef       service_context 
= (serviceContextRef
)context
; 
2091         CFArrayRef              serviceOrder    
= NULL
; 
2092         SCNetworkSetRef         set             
= (SCNetworkSetRef
)value
; 
2093         SCNetworkSetPrivateRef  setPrivate      
= (SCNetworkSetPrivateRef
)set
; 
2095         // update service order 
2096         serviceOrder 
= SCNetworkSetGetServiceOrder(set
); 
2097         if ((isA_CFArray(serviceOrder
) != NULL
) && 
2098             CFArrayContainsValue(serviceOrder
, 
2099                                   CFRangeMake(0, CFArrayGetCount(serviceOrder
)), 
2100                                   service_context
->oldServiceID
)) { 
2102                 CFIndex serviceOrderIndex
; 
2104                 // replacing all instances of old service ID with new one 
2105                 newServiceOrder 
= CFArrayCreateMutableCopy(NULL
, 0, serviceOrder
); 
2106                 count 
= CFArrayGetCount(newServiceOrder
); 
2107                 for (serviceOrderIndex 
= 0; serviceOrderIndex 
< count
; serviceOrderIndex
++) { 
2108                         CFStringRef     serviceID
; 
2110                         serviceID 
= CFArrayGetValueAtIndex(newServiceOrder
, serviceOrderIndex
); 
2111                         if (CFEqual(serviceID
, service_context
->oldServiceID
)) { 
2112                                 CFArraySetValueAtIndex(newServiceOrder
, serviceOrderIndex
, service_context
->newServiceID
); 
2115                 SCNetworkSetSetServiceOrder(set
, newServiceOrder
); 
2116                 CFRelease(newServiceOrder
); 
2119         // check if service with old serviceID is part of the set 
2120         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
2121                                                                  setPrivate
->setID
,             // set 
2122                                                                  service_context
->oldServiceID
, // service 
2124         oldLink 
= SCPreferencesPathGetLink(setPrivate
->prefs
, path
); 
2125         if (oldLink 
== NULL
) { 
2126                 // don't make any changes if service with old serviceID is not found 
2130         // remove link between "set" and old "service" 
2131         (void) SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
); 
2134         // create the link between "set" and the "service" 
2135         path 
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
,                          // allocator 
2136                                                                  setPrivate
->setID
,             // set 
2137                                                                  service_context
->newServiceID
, // service 
2139         link 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
2140                                                               service_context
->newServiceID
,    // service 
2142         (void) SCPreferencesPathSetLink(setPrivate
->prefs
, path
, link
); 
2158 _SCNetworkServiceSetServiceID(SCNetworkServiceRef service
, CFStringRef newServiceID
) 
2160         CFArrayRef                      allSets         
= NULL
; 
2161         CFDictionaryRef                 entity
; 
2162         CFStringRef                     newPath
; 
2164         CFStringRef                     oldPath         
= NULL
; 
2165         serviceContext                  service_context
; 
2166         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)service
; 
2168         if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs 
== NULL
)) { 
2169                 _SCErrorSet(kSCStatusInvalidArgument
); 
2173         if (!isA_CFString(newServiceID
)) { 
2174                 _SCErrorSet(kSCStatusInvalidArgument
); 
2178         if (CFEqual(newServiceID
, servicePrivate
->serviceID
)) { 
2179                 // no work needs to be done if new service ID is equal to current service ID 
2183         if (!__SCNetworkServiceExists(service
)) { 
2184                 SC_log(LOG_ERR
, "_SCNetworkServiceSetServiceID() w/removed service\n  service = %@\n  serviceID = %@", 
2187                 _SC_crash_once("_SCNetworkServiceSetServiceID() w/removed service", NULL
, NULL
); 
2188                 _SCErrorSet(kSCStatusInvalidArgument
); 
2192         newPath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                          // allocator 
2193                                                                  newServiceID
,                  // service 
2195         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, newPath
); 
2196         if (isA_CFDictionary(entity
)) { 
2197                 // if the new service already exists 
2198                 _SCErrorSet(kSCStatusKeyExists
); 
2202         oldPath 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                          // allocator 
2203                                                                  servicePrivate
->serviceID
,     // service 
2205         entity 
= SCPreferencesPathGetValue(servicePrivate
->prefs
, oldPath
); 
2206         if (!isA_CFDictionary(entity
)) { 
2207                 // if the service has already been removed 
2208                 _SCErrorSet(kSCStatusNoKey
); 
2212         ok 
= SCPreferencesPathSetValue(servicePrivate
->prefs
, newPath
, entity
); 
2215         ok 
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, oldPath
); 
2218         allSets 
= SCNetworkSetCopyAll(servicePrivate
->prefs
); 
2220         service_context
.newServiceID 
= newServiceID
; 
2221         service_context
.oldServiceID 
= servicePrivate
->serviceID
; 
2223         // find all sets w/oldServiceID and update 
2224         // ... and update the serviceOrder 
2225         CFArrayApplyFunction(allSets
, 
2226                              CFRangeMake(0, CFArrayGetCount(allSets
)), 
2230         if (servicePrivate
->interface 
!= NULL
) { 
2231                 SCNetworkInterfaceRef           newInterface
; 
2233                 // duplicate the interface and associate the copy with the new service ID 
2234                 newInterface 
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, 
2235                                                                                      servicePrivate
->interface
, 
2236                                                                                      servicePrivate
->prefs
, 
2238                 CFRelease(servicePrivate
->interface
); 
2239                 servicePrivate
->interface 
= newInterface
; 
2242         SC_log(LOG_DEBUG
, "_SCNetworkServiceSetServiceID(): %@ --> %@", service
, newServiceID
); 
2244         // replace serviceID with new one 
2245         CFRetain(newServiceID
); 
2246         CFRelease(servicePrivate
->serviceID
); 
2247         servicePrivate
->serviceID 
= newServiceID
; 
2251         if (oldPath 
!= NULL
) { 
2254         if (newPath 
!= NULL
) { 
2257         if (allSets 
!= NULL
) { 
2264 #define kVPNProtocolPayloadInfo                 CFSTR("com.apple.payload") 
2265 #define kSCEntNetLoginWindowEAPOL               CFSTR("EAPOL.LoginWindow") 
2268 copyInterfaceConfiguration(SCNetworkServiceRef oldService
, SCNetworkServiceRef newService
) 
2270         SCNetworkInterfaceRef   oldInterface
; 
2271         SCNetworkInterfaceRef   newInterface
; 
2273         oldInterface 
= SCNetworkServiceGetInterface(oldService
); 
2274         newInterface 
= SCNetworkServiceGetInterface(newService
); 
2276         while (oldInterface 
!= NULL
) { 
2277                 CFDictionaryRef configuration
; 
2278                 CFStringRef             interfaceType
; 
2280                 if (newInterface 
== NULL
) { 
2281                         // oops ... interface layering does not match 
2285                 // copy interface configuration 
2286                 configuration 
= SCNetworkInterfaceGetConfiguration(oldInterface
); 
2288                 if ((configuration 
!= NULL
) || 
2289                     (SCError() == kSCStatusOK
)) { 
2290                         if (!SCNetworkInterfaceSetConfiguration(newInterface
, configuration
)) { 
2291                                 SC_log(LOG_INFO
, "problem setting interface configuration"); 
2296                 // special case: PPP/L2TP + IPSec 
2297                 interfaceType 
= SCNetworkInterfaceGetInterfaceType(oldInterface
); 
2298                 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) { 
2299                         SCNetworkInterfaceRef   childInterface
; 
2301                         childInterface 
= SCNetworkInterfaceGetInterface(oldInterface
); 
2302                         if (childInterface 
!= NULL
) { 
2303                                 CFStringRef             childInterfaceType
; 
2305                                 childInterfaceType 
= SCNetworkInterfaceGetInterfaceType(childInterface
); 
2307                                 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) { 
2308                                         configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetIPSec
); 
2309                                         if ((configuration 
!= NULL
) || 
2310                                             (SCError() == kSCStatusOK
)) { 
2311                                                 if (!SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetIPSec
, configuration
)) { 
2312                                                         SC_log(LOG_INFO
, "problem setting child interface configuration"); 
2319                 // special case: 802.1x 
2320                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetEAPOL
); 
2321                 if ((configuration 
!= NULL
) || 
2322                     (SCError() == kSCStatusOK
)) { 
2323                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetEAPOL
, configuration
); 
2326                 // special case: Managed Client 
2327                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kVPNProtocolPayloadInfo
); 
2328                 if ((configuration 
!= NULL
) || 
2329                     (SCError() == kSCStatusOK
)) { 
2330                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kVPNProtocolPayloadInfo
, configuration
); 
2333                 // special case: Network Pref 
2334                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCValNetPPPAuthProtocolEAP
); 
2335                 if ((configuration 
!= NULL
) || 
2336                     (SCError() == kSCStatusOK
)) { 
2337                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCValNetPPPAuthProtocolEAP
, configuration
); 
2340                 // special case: Remote Pref 
2341                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetLoginWindowEAPOL
); 
2342                 if ((configuration 
!= NULL
) || 
2343                     (SCError() == kSCStatusOK
)) { 
2344                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetLoginWindowEAPOL
, configuration
); 
2347                 // special case: Network Extension 
2348                 configuration 
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCNetworkInterfaceTypeIPSec
); 
2349                 if ((configuration 
!= NULL
) || 
2350                     (SCError() == kSCStatusOK
)) { 
2351                         (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCNetworkInterfaceTypeIPSec
, configuration
); 
2354                 oldInterface 
= SCNetworkInterfaceGetInterface(oldInterface
); 
2355                 newInterface 
= SCNetworkInterfaceGetInterface(newInterface
); 
2363 __SCNetworkServiceAddProtocolToService(SCNetworkServiceRef service
, CFStringRef protocolType
, CFDictionaryRef configuration
, Boolean enabled
) 
2366         SCNetworkProtocolRef protocol
; 
2368         protocol 
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
2370         if ((protocol 
== NULL
) && 
2371             (SCError() == kSCStatusNoKey
)) { 
2372                 ok 
= SCNetworkServiceAddProtocolType(service
, protocolType
); 
2374                         protocol 
= SCNetworkServiceCopyProtocol(service
, protocolType
); 
2377         if (protocol 
!= NULL
) { 
2378                 SCNetworkProtocolSetConfiguration(protocol
, configuration
); 
2379                 SCNetworkProtocolSetEnabled(protocol
, enabled
); 
2380                 CFRelease(protocol
); 
2389 __SCNetworkServiceMigrateNew(SCPreferencesRef           prefs
, 
2390                              SCNetworkServiceRef        service
, 
2391                              CFDictionaryRef            bsdMapping
, 
2392                              CFDictionaryRef            setMapping
, 
2393                              CFDictionaryRef            serviceSetMapping
) 
2395         CFStringRef deviceName 
= NULL
; 
2397         SCNetworkInterfaceRef interface 
= NULL
; 
2398         CFDictionaryRef interfaceEntity 
= NULL
; 
2399         CFMutableDictionaryRef interfaceEntityMutable 
= NULL
; 
2400         SCNetworkSetRef newSet 
= NULL
; 
2401         SCPreferencesRef ni_prefs 
= NULL
; 
2402         SCNetworkInterfaceRef ni_interface 
= NULL
; 
2403         SCNetworkInterfaceRef oldInterface 
= NULL
; 
2404         SCNetworkSetRef oldSet 
= NULL
; 
2405         SCNetworkServiceRef newService 
= NULL
; 
2406         CFStringRef serviceID 
= NULL
; 
2407         SCNetworkServicePrivateRef servicePrivate 
= (SCNetworkServicePrivateRef
) service
; 
2408         CFArrayRef setList 
= NULL
; 
2409         Boolean success 
= FALSE
; 
2410         CFStringRef targetDeviceName 
= NULL
; 
2411         CFStringRef userDefinedName 
= NULL
; 
2412         CFStringRef userDefinedNameInterface 
= NULL
; 
2413         CFArrayRef protocols 
= NULL
; 
2414         CFStringRef subType
; 
2416         if ((isA_SCNetworkService(service
) == NULL
) || 
2417         (isA_SCNetworkInterface(servicePrivate
->interface
) == NULL
) || 
2418         (servicePrivate
->prefs 
== NULL
)) { 
2421         serviceID 
= servicePrivate
->serviceID
; 
2423         newService 
= SCNetworkServiceCopy(prefs
, serviceID
); 
2424         if (newService 
!= NULL
) { 
2425                 // Cannot add service if it already exists 
2426                 SC_log(LOG_INFO
, "Service already exists"); 
2430         oldInterface 
= SCNetworkServiceGetInterface(service
); 
2431         interfaceEntity 
= __SCNetworkInterfaceCopyInterfaceEntity(oldInterface
); 
2432         if (interfaceEntity 
== NULL
) { 
2433                 SC_log(LOG_INFO
, "No interface entity"); 
2436         interfaceEntityMutable 
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceEntity
); 
2438         if (isA_CFDictionary(bsdMapping
) != NULL
) { 
2439                 deviceName 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
); 
2440                 if (isA_CFString(deviceName
) != NULL
) { 
2441                         targetDeviceName 
= CFDictionaryGetValue(bsdMapping
, deviceName
); 
2442                         if (targetDeviceName 
!= NULL
) { 
2444                                 CFDictionarySetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
, targetDeviceName
); 
2445                                 ni_prefs 
= __SCPreferencesCreateNIPrefsFromPrefs(prefs
); 
2446                                 ni_interface 
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ni_prefs
, targetDeviceName
); 
2447                                 if (ni_interface 
!= NULL
) { 
2448                                         userDefinedNameInterface 
= __SCNetworkInterfaceGetUserDefinedName(ni_interface
); 
2452                 if (userDefinedNameInterface 
== NULL
) { 
2453                         userDefinedNameInterface 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropUserDefinedName
); 
2456         subType 
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceSubType
); 
2457         interface 
= _SCNetworkInterfaceCreateWithEntity(NULL
, interfaceEntityMutable
, NULL
); 
2458         if (userDefinedNameInterface 
!= NULL
) { 
2459                 __SCNetworkInterfaceSetUserDefinedName(interface
, userDefinedNameInterface
); 
2461         // Supporting PPPoE subtype 
2462         if (subType 
!= NULL 
&& 
2463             CFEqual(subType
, kSCValNetInterfaceSubTypePPPoE
)) { 
2464                 SCNetworkInterfaceRef childInterface 
= SCNetworkInterfaceGetInterface(interface
); 
2465                 if (childInterface 
!= NULL
) { 
2466                         __SCNetworkInterfaceSetUserDefinedName(childInterface
, userDefinedNameInterface
); 
2469         newService 
= SCNetworkServiceCreate(prefs
, interface
); 
2470         if (newService 
== NULL
) { 
2471                 SC_log(LOG_INFO
, "SCNetworkServiceCreate() failed"); 
2475         enabled 
= SCNetworkServiceGetEnabled(service
); 
2476         if (!SCNetworkServiceSetEnabled(newService
, enabled
)) { 
2477                 SCNetworkServiceRemove(newService
); 
2478                 SC_log(LOG_INFO
, "SCNetworkServiceSetEnabled() failed"); 
2482         if (!SCNetworkServiceEstablishDefaultConfiguration(newService
)) { 
2483                 SCNetworkServiceRemove(newService
); 
2484                 SC_log(LOG_INFO
, "SCNetworkServiceEstablishDefaultConfiguration() failed"); 
2489         _SCNetworkServiceSetServiceID(newService
, serviceID
); 
2491         userDefinedName 
= SCNetworkServiceGetName(service
); 
2492         if ((userDefinedName 
!= NULL
) && 
2493             !SCNetworkServiceSetName(newService
, userDefinedName
)) { 
2494                 SC_log(LOG_INFO
, "SCNetworkServiceSetName(, %@) failed", userDefinedName
); 
2497         // Determine which sets to add service 
2498         if (setMapping 
!= NULL 
&& 
2499             serviceSetMapping 
!= NULL
) { 
2500                 setList 
= CFDictionaryGetValue(serviceSetMapping
, service
); 
2501                 if (setList 
!= NULL
) { 
2502                         for (CFIndex idx 
= 0; idx 
< CFArrayGetCount(setList
); idx
++) { 
2503                                 oldSet 
= CFArrayGetValueAtIndex(setList
, idx
); 
2504                                 newSet 
= CFDictionaryGetValue(setMapping
, oldSet
); 
2505                                 if (newSet 
== NULL
) { 
2509                                 if (!SCNetworkSetAddService(newSet
, newService
)) { 
2510                                         SC_log(LOG_INFO
, "SCNetworkSetAddService() failed"); 
2516         protocols 
= SCNetworkServiceCopyProtocols(service
); 
2517         if (protocols 
!= NULL
) { 
2519                 for (CFIndex idx 
= 0; idx 
< CFArrayGetCount(protocols
); idx
++) { 
2520                         SCNetworkProtocolRef protocol 
= CFArrayGetValueAtIndex(protocols
, idx
); 
2521                         CFDictionaryRef configuration 
= SCNetworkProtocolGetConfiguration(protocol
); 
2522                         CFStringRef protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
2523                         enabled 
= SCNetworkProtocolGetEnabled(protocol
); 
2524                         __SCNetworkServiceAddProtocolToService(newService
, protocolType
, configuration
, enabled
); 
2526                 CFRelease(protocols
); 
2529         copyInterfaceConfiguration(service
, newService
); 
2533         if (interface 
!= NULL
) { 
2534                 CFRelease(interface
); 
2536         if (interfaceEntity 
!= NULL
) { 
2537                 CFRelease(interfaceEntity
); 
2539         if (interfaceEntityMutable 
!= NULL
) { 
2540                 CFRelease(interfaceEntityMutable
); 
2542         if (newService 
!= NULL
) { 
2543                 CFRelease(newService
); 
2545         if (ni_prefs 
!= NULL
) { 
2546                 CFRelease(ni_prefs
); 
2548         if (ni_interface 
!= NULL
) { 
2549                 CFRelease(ni_interface
); 
2557 __SCNetworkServiceCreate(SCPreferencesRef       prefs
, 
2558                          SCNetworkInterfaceRef  interface
, 
2559                          CFStringRef            userDefinedName
) 
2561         SCNetworkSetRef currentSet 
= NULL
; 
2563         SCNetworkServiceRef service 
= NULL
; 
2565         if (interface 
== NULL
) { 
2569         if (userDefinedName 
== NULL
) { 
2570                 userDefinedName 
= __SCNetworkInterfaceGetUserDefinedName(interface
); 
2571                 if (userDefinedName 
== NULL
) { 
2572                         SC_log(LOG_INFO
, "No userDefinedName"); 
2576         service 
= SCNetworkServiceCreate(prefs
, interface
); 
2577         if (service 
== NULL
) { 
2578                 SC_log(LOG_INFO
, "SCNetworkServiceCreate() failed: %s", SCErrorString(SCError())); 
2580                 ok 
= SCNetworkServiceSetName(service
, userDefinedName
); 
2582                         SC_log(LOG_INFO
, "SCNetworkServiceSetName() failed: %s", SCErrorString(SCError())); 
2583                         SCNetworkServiceRemove(service
); 
2587                 ok 
= SCNetworkServiceEstablishDefaultConfiguration(service
); 
2589                         SC_log(LOG_INFO
, "SCNetworkServiceEstablishDefaultConfiguration() failed: %s", SCErrorString(SCError())); 
2590                         SCNetworkServiceRemove(service
); 
2594         currentSet 
= SCNetworkSetCopyCurrent(prefs
); 
2595         if (currentSet 
== NULL
) { 
2596                 SC_log(LOG_INFO
, "No current set"); 
2597                 if (service 
!= NULL
) { 
2598                         SCNetworkServiceRemove(service
); 
2602         if (service 
!= NULL
) { 
2603                 ok 
= SCNetworkSetAddService(currentSet
, service
); 
2605                         SC_log(LOG_INFO
, "Could not add service to the current set"); 
2606                         SCNetworkServiceRemove(service
); 
2612         if (service 
!= NULL
) { 
2615         if (currentSet 
!= NULL
) { 
2616                 CFRelease(currentSet
); 
2621 __private_extern__ Boolean
 
2622 __SCNetworkServiceIsPPTP(SCNetworkServiceRef    service
) 
2624         CFStringRef intfSubtype
; 
2625         SCNetworkServicePrivateRef servicePrivate 
= (SCNetworkServicePrivateRef
)service
; 
2627         if (servicePrivate 
== NULL 
|| servicePrivate
->interface 
== NULL
) { 
2631         intfSubtype 
= __SCNetworkInterfaceGetEntitySubType(servicePrivate
->interface
); 
2632         if (intfSubtype 
== NULL
) { 
2636 #pragma GCC diagnostic push 
2637 #pragma GCC diagnostic ignored "-Wdeprecated" 
2638         if (CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) { 
2641 #pragma GCC diagnostic pop