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