]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkProtocol.c
configd-802.20.7.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkProtocol.c
1 /*
2 * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
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>
38
39 #include <pthread.h>
40
41
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);
46
47
48 #if !TARGET_OS_IPHONE
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");
55 #if !TARGET_OS_IPHONE
56 const CFStringRef kSCNetworkProtocolTypeSMB = CFSTR("SMB");
57 #endif // !TARGET_OS_IPHONE
58
59
60 static CFTypeID __kSCNetworkProtocolTypeID = _kCFRuntimeNotATypeID;
61
62
63 static const CFRuntimeClass __SCNetworkProtocolClass = {
64 0, // version
65 "SCNetworkProtocol", // className
66 NULL, // init
67 NULL, // copy
68 __SCNetworkProtocolDeallocate, // dealloc
69 __SCNetworkProtocolEqual, // equal
70 __SCNetworkProtocolHash, // hash
71 NULL, // copyFormattingDesc
72 __SCNetworkProtocolCopyDescription // copyDebugDesc
73 };
74
75
76 static pthread_once_t initialized = PTHREAD_ONCE_INIT;
77
78
79 static CFStringRef
80 __SCNetworkProtocolCopyDescription(CFTypeRef cf)
81 {
82 CFAllocatorRef allocator = CFGetAllocator(cf);
83 CFMutableStringRef result;
84 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)cf;
85
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("}"));
94
95 return result;
96 }
97
98
99 static void
100 __SCNetworkProtocolDeallocate(CFTypeRef cf)
101 {
102 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)cf;
103
104 /* release resources */
105 CFRelease(protocolPrivate->entityID);
106 CFRelease(protocolPrivate->service);
107
108 return;
109 }
110
111
112 static Boolean
113 __SCNetworkProtocolEqual(CFTypeRef cf1, CFTypeRef cf2)
114 {
115 SCNetworkProtocolPrivateRef p1 = (SCNetworkProtocolPrivateRef)cf1;
116 SCNetworkProtocolPrivateRef p2 = (SCNetworkProtocolPrivateRef)cf2;
117
118 if (p1 == p2)
119 return TRUE;
120
121 if (!CFEqual(p1->entityID, p2->entityID))
122 return FALSE; // if not the same protocol type
123
124 if (p1->service == p2->service)
125 return TRUE; // if both point to the same service
126
127 if ((p1->service != NULL) && (p2->service != NULL) && CFEqual(p1->service, p2->service))
128 return TRUE; // if both effectively point to the same service
129
130 return FALSE;
131 }
132
133
134 static CFHashCode
135 __SCNetworkProtocolHash(CFTypeRef cf)
136 {
137 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)cf;
138
139 return CFHash(protocolPrivate->entityID);
140 }
141
142
143 static void
144 __SCNetworkProtocolInitialize(void)
145 {
146 __kSCNetworkProtocolTypeID = _CFRuntimeRegisterClass(&__SCNetworkProtocolClass);
147 return;
148 }
149
150
151 __private_extern__ SCNetworkProtocolPrivateRef
152 __SCNetworkProtocolCreatePrivate(CFAllocatorRef allocator,
153 CFStringRef entityID,
154 SCNetworkServiceRef service)
155 {
156 SCNetworkProtocolPrivateRef protocolPrivate;
157 uint32_t size;
158
159 /* initialize runtime */
160 pthread_once(&initialized, __SCNetworkProtocolInitialize);
161
162 /* allocate target */
163 size = sizeof(SCNetworkProtocolPrivate) - sizeof(CFRuntimeBase);
164 protocolPrivate = (SCNetworkProtocolPrivateRef)_CFRuntimeCreateInstance(allocator,
165 __kSCNetworkProtocolTypeID,
166 size,
167 NULL);
168 if (protocolPrivate == NULL) {
169 return NULL;
170 }
171
172 protocolPrivate->entityID = CFStringCreateCopy(NULL, entityID);
173 protocolPrivate->service = CFRetain(service);
174
175 return protocolPrivate;
176 }
177
178
179 __private_extern__ Boolean
180 __SCNetworkProtocolIsValidType(CFStringRef protocolType)
181 {
182 int i;
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
194 };
195
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
199 return TRUE;
200 }
201 }
202
203 if (CFStringFindWithOptions(protocolType,
204 CFSTR("."),
205 CFRangeMake(0, CFStringGetLength(protocolType)),
206 0,
207 NULL)) {
208 // if user-defined protocol type (e.g. com.apple.myProtocol)
209 return TRUE;
210 }
211
212 return FALSE;
213 }
214
215
216 static CFStringRef
217 copyProtocolConfigurationPath(SCNetworkProtocolPrivateRef protocolPrivate)
218 {
219 CFStringRef path;
220 SCNetworkServicePrivateRef servicePrivate;
221
222 servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
223 path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator
224 servicePrivate->serviceID, // service
225 protocolPrivate->entityID); // entity
226 return path;
227 }
228
229
230 #pragma mark -
231 #pragma mark SCNetworkProtocol APIs
232
233
234 CFTypeID
235 SCNetworkProtocolGetTypeID()
236 {
237 pthread_once(&initialized, __SCNetworkProtocolInitialize); /* initialize runtime */
238 return __kSCNetworkProtocolTypeID;
239 }
240
241
242 CFDictionaryRef
243 SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol)
244 {
245 CFDictionaryRef config;
246 CFStringRef path;
247 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
248 SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
249
250 if (!isA_SCNetworkProtocol(protocol)) {
251 _SCErrorSet(kSCStatusInvalidArgument);
252 return NULL;
253 }
254
255 path = copyProtocolConfigurationPath(protocolPrivate);
256 config = __getPrefsConfiguration(servicePrivate->prefs, path);
257 CFRelease(path);
258
259 return config;
260 }
261
262
263 Boolean
264 SCNetworkProtocolGetEnabled(SCNetworkProtocolRef protocol)
265 {
266 Boolean enabled;
267 CFStringRef path;
268 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
269 SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
270
271 if (!isA_SCNetworkProtocol(protocol)) {
272 _SCErrorSet(kSCStatusInvalidArgument);
273 return FALSE;
274 }
275
276 path = copyProtocolConfigurationPath(protocolPrivate);
277 enabled = __getPrefsEnabled(servicePrivate->prefs, path);
278 CFRelease(path);
279
280 return enabled;
281 }
282
283
284 CFStringRef
285 SCNetworkProtocolGetProtocolType(SCNetworkProtocolRef protocol)
286 {
287 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
288
289 if (!isA_SCNetworkProtocol(protocol)) {
290 _SCErrorSet(kSCStatusInvalidArgument);
291 return NULL;
292 }
293
294 return protocolPrivate->entityID;
295 }
296
297
298 Boolean
299 SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol, CFDictionaryRef config)
300 {
301 Boolean ok;
302 CFStringRef path;
303 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
304 SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
305
306 if (!isA_SCNetworkProtocol(protocol)) {
307 _SCErrorSet(kSCStatusInvalidArgument);
308 return FALSE;
309 }
310
311 path = copyProtocolConfigurationPath(protocolPrivate);
312 ok = __setPrefsConfiguration(servicePrivate->prefs, path, config, TRUE);
313 CFRelease(path);
314
315 return ok;
316 }
317
318
319 Boolean
320 SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol, Boolean enabled)
321 {
322 Boolean ok;
323 CFStringRef path;
324 SCNetworkProtocolPrivateRef protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
325 SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
326
327 if (!isA_SCNetworkProtocol(protocol)) {
328 _SCErrorSet(kSCStatusInvalidArgument);
329 return FALSE;
330 }
331
332 path = copyProtocolConfigurationPath(protocolPrivate);
333 ok = __setPrefsEnabled(servicePrivate->prefs, path, enabled);
334 CFRelease(path);
335
336 return ok;
337 }