2  * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * Modification History 
  27  * May 13, 2004         Allan Nathanson <ajn@apple.com> 
  32 #include <CoreFoundation/CoreFoundation.h> 
  33 #include <CoreFoundation/CFRuntime.h> 
  34 #include <SystemConfiguration/SystemConfiguration.h> 
  35 #include <SystemConfiguration/SCNetworkConfigurationInternal.h> 
  36 #include <SystemConfiguration/SCValidation.h> 
  37 #include <SystemConfiguration/SCPrivate.h> 
  39 #include "SCNetworkConfiguration.h" 
  40 #include "SCNetworkConfigurationInternal.h" 
  45 static CFStringRef      
__SCNetworkProtocolCopyDescription      (CFTypeRef cf
); 
  46 static void             __SCNetworkProtocolDeallocate           (CFTypeRef cf
); 
  47 static Boolean          
__SCNetworkProtocolEqual                (CFTypeRef cf1
, CFTypeRef cf2
); 
  50 const CFStringRef kSCNetworkProtocolTypeAppleTalk       
= CFSTR("AppleTalk"); 
  51 const CFStringRef kSCNetworkProtocolTypeDNS             
= CFSTR("DNS"); 
  52 const CFStringRef kSCNetworkProtocolTypeIPv4            
= CFSTR("IPv4"); 
  53 const CFStringRef kSCNetworkProtocolTypeIPv6            
= CFSTR("IPv6"); 
  54 const CFStringRef kSCNetworkProtocolTypeProxies         
= CFSTR("Proxies"); 
  57 static CFTypeID __kSCNetworkProtocolTypeID      
= _kCFRuntimeNotATypeID
; 
  60 static const CFRuntimeClass __SCNetworkProtocolClass 
= { 
  62         "SCNetworkProtocol",                    // className 
  65         __SCNetworkProtocolDeallocate
,          // dealloc 
  66         __SCNetworkProtocolEqual
,               // equal 
  68         NULL
,                                   // copyFormattingDesc 
  69         __SCNetworkProtocolCopyDescription      
// copyDebugDesc 
  73 static pthread_once_t           initialized     
= PTHREAD_ONCE_INIT
; 
  76 static __inline__ CFTypeRef
 
  77 isA_SCNetworkProtocol(CFTypeRef obj
) 
  79         return (isA_CFType(obj
, SCNetworkProtocolGetTypeID())); 
  84 __SCNetworkProtocolCopyDescription(CFTypeRef cf
) 
  86         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
  87         CFMutableStringRef              result
; 
  88         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)cf
; 
  90         result 
= CFStringCreateMutable(allocator
, 0); 
  91         CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkProtocol %p [%p]> { "), cf
, allocator
); 
  92         CFStringAppendFormat(result
, NULL
, CFSTR("id=%@"), protocolPrivate
->entityID
); 
  93         CFStringAppendFormat(result
, NULL
, CFSTR(", service=%@"), protocolPrivate
->service
); 
  94         CFStringAppendFormat(result
, NULL
, CFSTR(" }")); 
 101 __SCNetworkProtocolDeallocate(CFTypeRef cf
) 
 103         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)cf
; 
 105         /* release resources */ 
 106         CFRelease(protocolPrivate
->entityID
); 
 113 __SCNetworkProtocolEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
 115         SCNetworkProtocolPrivateRef     p1      
= (SCNetworkProtocolPrivateRef
)cf1
; 
 116         SCNetworkProtocolPrivateRef     p2      
= (SCNetworkProtocolPrivateRef
)cf2
; 
 121         if (!CFEqual(p1
->entityID
, p2
->entityID
)) 
 122                 return FALSE
;   // if not the same protocol type 
 124         if (p1
->service 
== p2
->service
) 
 125                 return TRUE
;    // if both point to the same service 
 127         if ((p1
->service 
!= NULL
) && (p2
->service 
!= NULL
) && CFEqual(p1
->service
, p2
->service
)) 
 128                 return TRUE
;    // if both effectively point to the same service 
 135 __SCNetworkProtocolInitialize(void) 
 137         __kSCNetworkProtocolTypeID 
= _CFRuntimeRegisterClass(&__SCNetworkProtocolClass
); 
 142 __private_extern__ SCNetworkProtocolPrivateRef
 
 143 __SCNetworkProtocolCreatePrivate(CFAllocatorRef         allocator
, 
 144                                  CFStringRef            entityID
, 
 145                                  SCNetworkServiceRef    service
) 
 147         SCNetworkProtocolPrivateRef             protocolPrivate
; 
 150         /* initialize runtime */ 
 151         pthread_once(&initialized
, __SCNetworkProtocolInitialize
); 
 153         /* allocate target */ 
 154         size           
= sizeof(SCNetworkProtocolPrivate
) - sizeof(CFRuntimeBase
); 
 155         protocolPrivate 
= (SCNetworkProtocolPrivateRef
)_CFRuntimeCreateInstance(allocator
, 
 156                                                                               __kSCNetworkProtocolTypeID
, 
 159         if (protocolPrivate 
== NULL
) { 
 163         protocolPrivate
->entityID       
= CFStringCreateCopy(NULL
, entityID
); 
 164         protocolPrivate
->service        
= service
; 
 166         return protocolPrivate
; 
 170 __private_extern__ Boolean
 
 171 __SCNetworkProtocolIsValidType(CFStringRef protocolType
) 
 174         static const CFStringRef        
*valid_types
[]   = { 
 175                 &kSCNetworkProtocolTypeAppleTalk
, 
 176                 &kSCNetworkProtocolTypeDNS
, 
 177                 &kSCNetworkProtocolTypeIPv4
, 
 178                 &kSCNetworkProtocolTypeIPv6
, 
 179                 &kSCNetworkProtocolTypeProxies
 
 182         for (i 
= 0; i 
< sizeof(valid_types
)/sizeof(valid_types
[0]); i
++) { 
 183                 if (CFEqual(protocolType
, *valid_types
[i
])) { 
 184                         // if known/valid protocol type 
 189         if (CFStringFindWithOptions(protocolType
, 
 191                                     CFRangeMake(0, CFStringGetLength(protocolType
)), 
 194                 // if user-defined protocol type (e.g. com.apple.myProtocol) 
 203 copyProtocolConfigurationPath(SCNetworkProtocolPrivateRef protocolPrivate
) 
 206         SCNetworkServicePrivateRef      servicePrivate
; 
 208         servicePrivate 
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
; 
 209         path 
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,                             // allocator 
 210                                                               servicePrivate
->serviceID
,        // service 
 211                                                               protocolPrivate
->entityID
);       // entity 
 216 /* ---------- SCNetworkProtocol APIs ---------- */ 
 220 SCNetworkProtocolGetTypeID() 
 222         pthread_once(&initialized
, __SCNetworkProtocolInitialize
);      /* initialize runtime */ 
 223         return __kSCNetworkProtocolTypeID
; 
 228 SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol
) 
 230         CFDictionaryRef                 config
; 
 232         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)protocol
; 
 233         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
; 
 235         path 
= copyProtocolConfigurationPath(protocolPrivate
); 
 236         config 
= __getPrefsConfiguration(servicePrivate
->prefs
, path
); 
 244 SCNetworkProtocolGetEnabled(SCNetworkProtocolRef protocol
) 
 248         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)protocol
; 
 249         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
; 
 251         path 
= copyProtocolConfigurationPath(protocolPrivate
); 
 252         enabled 
= __getPrefsEnabled(servicePrivate
->prefs
, path
); 
 260 SCNetworkProtocolGetProtocolType(SCNetworkProtocolRef protocol
) 
 262         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)protocol
; 
 264         return protocolPrivate
->entityID
; 
 269 SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol
, CFDictionaryRef config
) 
 273         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)protocol
; 
 274         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
; 
 276         path 
= copyProtocolConfigurationPath(protocolPrivate
); 
 277         ok 
= __setPrefsConfiguration(servicePrivate
->prefs
, path
, config
, TRUE
); 
 285 SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol
, Boolean enabled
) 
 289         SCNetworkProtocolPrivateRef     protocolPrivate 
= (SCNetworkProtocolPrivateRef
)protocol
; 
 290         SCNetworkServicePrivateRef      servicePrivate  
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
; 
 292         path 
= copyProtocolConfigurationPath(protocolPrivate
); 
 293         ok 
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);