2 * Copyright (c) 2004-2008, 2016 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"
39 static CFStringRef
__SCNetworkProtocolCopyDescription (CFTypeRef cf
);
40 static void __SCNetworkProtocolDeallocate (CFTypeRef cf
);
41 static Boolean
__SCNetworkProtocolEqual (CFTypeRef cf1
, CFTypeRef cf2
);
42 static CFHashCode
__SCNetworkProtocolHash (CFTypeRef cf
);
45 const CFStringRef kSCNetworkProtocolTypeDNS
= CFSTR("DNS");
46 const CFStringRef kSCNetworkProtocolTypeIPv4
= CFSTR("IPv4");
47 const CFStringRef kSCNetworkProtocolTypeIPv6
= CFSTR("IPv6");
48 const CFStringRef kSCNetworkProtocolTypeProxies
= CFSTR("Proxies");
50 const CFStringRef kSCNetworkProtocolTypeSMB
= CFSTR("SMB");
51 #endif // !TARGET_OS_IPHONE
54 static CFTypeID __kSCNetworkProtocolTypeID
= _kCFRuntimeNotATypeID
;
57 static const CFRuntimeClass __SCNetworkProtocolClass
= {
59 "SCNetworkProtocol", // className
62 __SCNetworkProtocolDeallocate
, // dealloc
63 __SCNetworkProtocolEqual
, // equal
64 __SCNetworkProtocolHash
, // hash
65 NULL
, // copyFormattingDesc
66 __SCNetworkProtocolCopyDescription
// copyDebugDesc
70 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
74 __SCNetworkProtocolCopyDescription(CFTypeRef cf
)
76 CFAllocatorRef allocator
= CFGetAllocator(cf
);
77 CFMutableStringRef result
;
78 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
80 result
= CFStringCreateMutable(allocator
, 0);
81 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkProtocol %p [%p]> {"), cf
, allocator
);
82 CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), protocolPrivate
->entityID
);
83 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %p"), protocolPrivate
->service
);
84 CFStringAppendFormat(result
, NULL
,
85 CFSTR(", prefs = %p"),
86 ((SCNetworkServicePrivateRef
)protocolPrivate
->service
)->prefs
);
87 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
94 __SCNetworkProtocolDeallocate(CFTypeRef cf
)
96 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
98 /* release resources */
99 CFRelease(protocolPrivate
->entityID
);
100 CFRelease(protocolPrivate
->service
);
107 __SCNetworkProtocolEqual(CFTypeRef cf1
, CFTypeRef cf2
)
109 SCNetworkProtocolPrivateRef p1
= (SCNetworkProtocolPrivateRef
)cf1
;
110 SCNetworkProtocolPrivateRef p2
= (SCNetworkProtocolPrivateRef
)cf2
;
115 if (!CFEqual(p1
->entityID
, p2
->entityID
))
116 return FALSE
; // if not the same protocol type
118 if (p1
->service
== p2
->service
)
119 return TRUE
; // if both point to the same service
121 if ((p1
->service
!= NULL
) && (p2
->service
!= NULL
) && CFEqual(p1
->service
, p2
->service
))
122 return TRUE
; // if both effectively point to the same service
129 __SCNetworkProtocolHash(CFTypeRef cf
)
131 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)cf
;
133 return CFHash(protocolPrivate
->entityID
);
138 __SCNetworkProtocolInitialize(void)
140 __kSCNetworkProtocolTypeID
= _CFRuntimeRegisterClass(&__SCNetworkProtocolClass
);
145 __private_extern__ SCNetworkProtocolPrivateRef
146 __SCNetworkProtocolCreatePrivate(CFAllocatorRef allocator
,
147 CFStringRef entityID
,
148 SCNetworkServiceRef service
)
150 SCNetworkProtocolPrivateRef protocolPrivate
;
153 /* initialize runtime */
154 pthread_once(&initialized
, __SCNetworkProtocolInitialize
);
156 /* allocate target */
157 size
= sizeof(SCNetworkProtocolPrivate
) - sizeof(CFRuntimeBase
);
158 protocolPrivate
= (SCNetworkProtocolPrivateRef
)_CFRuntimeCreateInstance(allocator
,
159 __kSCNetworkProtocolTypeID
,
162 if (protocolPrivate
== NULL
) {
166 /* initialize non-zero/NULL members */
167 protocolPrivate
->entityID
= CFStringCreateCopy(NULL
, entityID
);
168 protocolPrivate
->service
= CFRetain(service
);
170 return protocolPrivate
;
174 __private_extern__ Boolean
175 __SCNetworkProtocolIsValidType(CFStringRef protocolType
)
178 static const CFStringRef
*valid_types
[] = {
179 &kSCNetworkProtocolTypeDNS
,
180 &kSCNetworkProtocolTypeIPv4
,
181 &kSCNetworkProtocolTypeIPv6
,
182 &kSCNetworkProtocolTypeProxies
,
183 #if !TARGET_OS_IPHONE
184 &kSCNetworkProtocolTypeSMB
,
185 #endif // !TARGET_OS_IPHONE
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
);
308 SC_log(LOG_DEBUG
, "SCNetworkProtocolSetConfiguration(): %@ --> %@",
310 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
318 SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol
, Boolean enabled
)
322 SCNetworkProtocolPrivateRef protocolPrivate
= (SCNetworkProtocolPrivateRef
)protocol
;
323 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)protocolPrivate
->service
;
325 if (!isA_SCNetworkProtocol(protocol
)) {
326 _SCErrorSet(kSCStatusInvalidArgument
);
330 path
= copyProtocolConfigurationPath(protocolPrivate
);
331 ok
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);
335 SC_log(LOG_DEBUG
, "SCNetworkProtocolSetEnabled(): %@ -> %s",
337 enabled
? "Enabled" : "Disabled");