2 * Copyright (c) 2004-2007 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
);
48 const CFStringRef kSCNetworkProtocolTypeAppleTalk
= CFSTR("AppleTalk");
49 const CFStringRef kSCNetworkProtocolTypeDNS
= CFSTR("DNS");
50 const CFStringRef kSCNetworkProtocolTypeIPv4
= CFSTR("IPv4");
51 const CFStringRef kSCNetworkProtocolTypeIPv6
= CFSTR("IPv6");
52 const CFStringRef kSCNetworkProtocolTypeProxies
= CFSTR("Proxies");
53 const CFStringRef kSCNetworkProtocolTypeSMB
= CFSTR("SMB");
56 static CFTypeID __kSCNetworkProtocolTypeID
= _kCFRuntimeNotATypeID
;
59 static const CFRuntimeClass __SCNetworkProtocolClass
= {
61 "SCNetworkProtocol", // className
64 __SCNetworkProtocolDeallocate
, // dealloc
65 __SCNetworkProtocolEqual
, // equal
66 __SCNetworkProtocolHash
, // hash
67 NULL
, // copyFormattingDesc
68 __SCNetworkProtocolCopyDescription
// copyDebugDesc
72 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
76 __SCNetworkProtocolCopyDescription(CFTypeRef cf
)
78 CFAllocatorRef allocator
= CFGetAllocator(cf
);
79 CFMutableStringRef result
;
80 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
82 result
= CFStringCreateMutable(allocator
, 0);
83 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkProtocol %p [%p]> {"), cf
, allocator
);
84 CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), protocolPrivate
->entityID
);
85 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %p"), protocolPrivate
->service
);
86 CFStringAppendFormat(result
, NULL
,
87 CFSTR(", prefs = %p"),
88 ((SCNetworkServicePrivateRef
)protocolPrivate
->service
)->prefs
);
89 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
96 __SCNetworkProtocolDeallocate(CFTypeRef cf
)
98 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
100 /* release resources */
101 CFRelease(protocolPrivate
->entityID
);
102 CFRelease(protocolPrivate
->service
);
109 __SCNetworkProtocolEqual(CFTypeRef cf1
, CFTypeRef cf2
)
111 SCNetworkProtocolPrivateRef p1
= (SCNetworkProtocolPrivateRef
)cf1
;
112 SCNetworkProtocolPrivateRef p2
= (SCNetworkProtocolPrivateRef
)cf2
;
117 if (!CFEqual(p1
->entityID
, p2
->entityID
))
118 return FALSE
; // if not the same protocol type
120 if (p1
->service
== p2
->service
)
121 return TRUE
; // if both point to the same service
123 if ((p1
->service
!= NULL
) && (p2
->service
!= NULL
) && CFEqual(p1
->service
, p2
->service
))
124 return TRUE
; // if both effectively point to the same service
131 __SCNetworkProtocolHash(CFTypeRef cf
)
133 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
135 return CFHash(protocolPrivate
->entityID
);
140 __SCNetworkProtocolInitialize(void)
142 __kSCNetworkProtocolTypeID
= _CFRuntimeRegisterClass(&__SCNetworkProtocolClass
);
147 __private_extern__ SCNetworkProtocolPrivateRef
148 __SCNetworkProtocolCreatePrivate(CFAllocatorRef allocator
,
149 CFStringRef entityID
,
150 SCNetworkServiceRef service
)
152 SCNetworkProtocolPrivateRef protocolPrivate
;
155 /* initialize runtime */
156 pthread_once(&initialized
, __SCNetworkProtocolInitialize
);
158 /* allocate target */
159 size
= sizeof(SCNetworkProtocolPrivate
) - sizeof(CFRuntimeBase
);
160 protocolPrivate
= (SCNetworkProtocolPrivateRef
)_CFRuntimeCreateInstance(allocator
,
161 __kSCNetworkProtocolTypeID
,
164 if (protocolPrivate
== NULL
) {
168 protocolPrivate
->entityID
= CFStringCreateCopy(NULL
, entityID
);
169 protocolPrivate
->service
= CFRetain(service
);
171 return protocolPrivate
;
175 __private_extern__ Boolean
176 __SCNetworkProtocolIsValidType(CFStringRef protocolType
)
179 static const CFStringRef
*valid_types
[] = {
180 &kSCNetworkProtocolTypeAppleTalk
,
181 &kSCNetworkProtocolTypeDNS
,
182 &kSCNetworkProtocolTypeIPv4
,
183 &kSCNetworkProtocolTypeIPv6
,
184 &kSCNetworkProtocolTypeProxies
,
185 &kSCNetworkProtocolTypeSMB
188 for (i
= 0; i
< sizeof(valid_types
)/sizeof(valid_types
[0]); i
++) {
189 if (CFEqual(protocolType
, *valid_types
[i
])) {
190 // if known/valid protocol type
195 if (CFStringFindWithOptions(protocolType
,
197 CFRangeMake(0, CFStringGetLength(protocolType
)),
200 // if user-defined protocol type (e.g. com.apple.myProtocol)
209 copyProtocolConfigurationPath(SCNetworkProtocolPrivateRef protocolPrivate
)
212 SCNetworkServicePrivateRef servicePrivate
;
214 servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
215 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
216 servicePrivate
->serviceID
, // service
217 protocolPrivate
->entityID
); // entity
223 #pragma mark SCNetworkProtocol APIs
227 SCNetworkProtocolGetTypeID()
229 pthread_once(&initialized
, __SCNetworkProtocolInitialize
); /* initialize runtime */
230 return __kSCNetworkProtocolTypeID
;
235 SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol
)
237 CFDictionaryRef config
;
239 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
240 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
242 if (!isA_SCNetworkProtocol(protocol
)) {
243 _SCErrorSet(kSCStatusInvalidArgument
);
247 path
= copyProtocolConfigurationPath(protocolPrivate
);
248 config
= __getPrefsConfiguration(servicePrivate
->prefs
, path
);
256 SCNetworkProtocolGetEnabled(SCNetworkProtocolRef protocol
)
260 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
261 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
263 if (!isA_SCNetworkProtocol(protocol
)) {
264 _SCErrorSet(kSCStatusInvalidArgument
);
268 path
= copyProtocolConfigurationPath(protocolPrivate
);
269 enabled
= __getPrefsEnabled(servicePrivate
->prefs
, path
);
277 SCNetworkProtocolGetProtocolType(SCNetworkProtocolRef protocol
)
279 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
281 if (!isA_SCNetworkProtocol(protocol
)) {
282 _SCErrorSet(kSCStatusInvalidArgument
);
286 return protocolPrivate
->entityID
;
291 SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol
, CFDictionaryRef config
)
295 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
296 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
298 if (!isA_SCNetworkProtocol(protocol
)) {
299 _SCErrorSet(kSCStatusInvalidArgument
);
303 path
= copyProtocolConfigurationPath(protocolPrivate
);
304 ok
= __setPrefsConfiguration(servicePrivate
->prefs
, path
, config
, TRUE
);
312 SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol
, Boolean enabled
)
316 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
317 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
319 if (!isA_SCNetworkProtocol(protocol
)) {
320 _SCErrorSet(kSCStatusInvalidArgument
);
324 path
= copyProtocolConfigurationPath(protocolPrivate
);
325 ok
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);