2 * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <CoreFoundation/CFRuntime.h>
34 #include <SystemConfiguration/SystemConfiguration.h>
35 #include "SCNetworkConfigurationInternal.h"
36 #include <SystemConfiguration/SCValidation.h>
37 #include <SystemConfiguration/SCPrivate.h>
42 static CFStringRef
__SCNetworkProtocolCopyDescription (CFTypeRef cf
);
43 static void __SCNetworkProtocolDeallocate (CFTypeRef cf
);
44 static Boolean
__SCNetworkProtocolEqual (CFTypeRef cf1
, CFTypeRef cf2
);
45 static CFHashCode
__SCNetworkProtocolHash (CFTypeRef cf
);
49 const CFStringRef kSCNetworkProtocolTypeAppleTalk
= CFSTR("AppleTalk");
50 #endif // !TARGET_OS_IPHONE
51 const CFStringRef kSCNetworkProtocolTypeDNS
= CFSTR("DNS");
52 const CFStringRef kSCNetworkProtocolTypeIPv4
= CFSTR("IPv4");
53 const CFStringRef kSCNetworkProtocolTypeIPv6
= CFSTR("IPv6");
54 const CFStringRef kSCNetworkProtocolTypeProxies
= CFSTR("Proxies");
56 const CFStringRef kSCNetworkProtocolTypeSMB
= CFSTR("SMB");
57 #endif // !TARGET_OS_IPHONE
60 static CFTypeID __kSCNetworkProtocolTypeID
= _kCFRuntimeNotATypeID
;
63 static const CFRuntimeClass __SCNetworkProtocolClass
= {
65 "SCNetworkProtocol", // className
68 __SCNetworkProtocolDeallocate
, // dealloc
69 __SCNetworkProtocolEqual
, // equal
70 __SCNetworkProtocolHash
, // hash
71 NULL
, // copyFormattingDesc
72 __SCNetworkProtocolCopyDescription
// copyDebugDesc
76 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
80 __SCNetworkProtocolCopyDescription(CFTypeRef cf
)
82 CFAllocatorRef allocator
= CFGetAllocator(cf
);
83 CFMutableStringRef result
;
84 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
86 result
= CFStringCreateMutable(allocator
, 0);
87 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkProtocol %p [%p]> {"), cf
, allocator
);
88 CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), protocolPrivate
->entityID
);
89 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %p"), protocolPrivate
->service
);
90 CFStringAppendFormat(result
, NULL
,
91 CFSTR(", prefs = %p"),
92 ((SCNetworkServicePrivateRef
)protocolPrivate
->service
)->prefs
);
93 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
100 __SCNetworkProtocolDeallocate(CFTypeRef cf
)
102 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
104 /* release resources */
105 CFRelease(protocolPrivate
->entityID
);
106 CFRelease(protocolPrivate
->service
);
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 __SCNetworkProtocolHash(CFTypeRef cf
)
137 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
139 return CFHash(protocolPrivate
->entityID
);
144 __SCNetworkProtocolInitialize(void)
146 __kSCNetworkProtocolTypeID
= _CFRuntimeRegisterClass(&__SCNetworkProtocolClass
);
151 __private_extern__ SCNetworkProtocolPrivateRef
152 __SCNetworkProtocolCreatePrivate(CFAllocatorRef allocator
,
153 CFStringRef entityID
,
154 SCNetworkServiceRef service
)
156 SCNetworkProtocolPrivateRef protocolPrivate
;
159 /* initialize runtime */
160 pthread_once(&initialized
, __SCNetworkProtocolInitialize
);
162 /* allocate target */
163 size
= sizeof(SCNetworkProtocolPrivate
) - sizeof(CFRuntimeBase
);
164 protocolPrivate
= (SCNetworkProtocolPrivateRef
)_CFRuntimeCreateInstance(allocator
,
165 __kSCNetworkProtocolTypeID
,
168 if (protocolPrivate
== NULL
) {
172 protocolPrivate
->entityID
= CFStringCreateCopy(NULL
, entityID
);
173 protocolPrivate
->service
= CFRetain(service
);
175 return protocolPrivate
;
179 __private_extern__ Boolean
180 __SCNetworkProtocolIsValidType(CFStringRef protocolType
)
183 static const CFStringRef
*valid_types
[] = {
184 #if !TARGET_OS_IPHONE
185 &kSCNetworkProtocolTypeAppleTalk
,
186 #endif // !TARGET_OS_IPHONE
187 &kSCNetworkProtocolTypeDNS
,
188 &kSCNetworkProtocolTypeIPv4
,
189 &kSCNetworkProtocolTypeIPv6
,
190 &kSCNetworkProtocolTypeProxies
,
191 #if !TARGET_OS_IPHONE
192 &kSCNetworkProtocolTypeSMB
,
193 #endif // !TARGET_OS_IPHONE
196 for (i
= 0; i
< sizeof(valid_types
)/sizeof(valid_types
[0]); i
++) {
197 if (CFEqual(protocolType
, *valid_types
[i
])) {
198 // if known/valid protocol type
203 if (CFStringFindWithOptions(protocolType
,
205 CFRangeMake(0, CFStringGetLength(protocolType
)),
208 // if user-defined protocol type (e.g. com.apple.myProtocol)
217 copyProtocolConfigurationPath(SCNetworkProtocolPrivateRef protocolPrivate
)
220 SCNetworkServicePrivateRef servicePrivate
;
222 servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
223 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
224 servicePrivate
->serviceID
, // service
225 protocolPrivate
->entityID
); // entity
231 #pragma mark SCNetworkProtocol APIs
235 SCNetworkProtocolGetTypeID()
237 pthread_once(&initialized
, __SCNetworkProtocolInitialize
); /* initialize runtime */
238 return __kSCNetworkProtocolTypeID
;
243 SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol
)
245 CFDictionaryRef config
;
247 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
248 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
250 if (!isA_SCNetworkProtocol(protocol
)) {
251 _SCErrorSet(kSCStatusInvalidArgument
);
255 path
= copyProtocolConfigurationPath(protocolPrivate
);
256 config
= __getPrefsConfiguration(servicePrivate
->prefs
, path
);
264 SCNetworkProtocolGetEnabled(SCNetworkProtocolRef protocol
)
268 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
269 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
271 if (!isA_SCNetworkProtocol(protocol
)) {
272 _SCErrorSet(kSCStatusInvalidArgument
);
276 path
= copyProtocolConfigurationPath(protocolPrivate
);
277 enabled
= __getPrefsEnabled(servicePrivate
->prefs
, path
);
285 SCNetworkProtocolGetProtocolType(SCNetworkProtocolRef protocol
)
287 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
289 if (!isA_SCNetworkProtocol(protocol
)) {
290 _SCErrorSet(kSCStatusInvalidArgument
);
294 return protocolPrivate
->entityID
;
299 SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol
, CFDictionaryRef config
)
303 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
304 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
306 if (!isA_SCNetworkProtocol(protocol
)) {
307 _SCErrorSet(kSCStatusInvalidArgument
);
311 path
= copyProtocolConfigurationPath(protocolPrivate
);
312 ok
= __setPrefsConfiguration(servicePrivate
->prefs
, path
, config
, TRUE
);
320 SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol
, Boolean enabled
)
324 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
325 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
327 if (!isA_SCNetworkProtocol(protocol
)) {
328 _SCErrorSet(kSCStatusInvalidArgument
);
332 path
= copyProtocolConfigurationPath(protocolPrivate
);
333 ok
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);