]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
configd-137.3.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkConfigurationInternal.c
1 /*
2 * Copyright (c) 2004,2005 Apple Computer, 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 27, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <SystemConfiguration/SystemConfiguration.h>
34 #include <SystemConfiguration/SCValidation.h>
35 #include <SystemConfiguration/SCPrivate.h>
36
37 #include <sys/ioctl.h>
38 #include <net/if.h>
39
40
41 __private_extern__ CFDictionaryRef
42 __getPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path)
43 {
44 CFDictionaryRef config;
45 CFIndex n;
46
47 config = SCPreferencesPathGetValue(prefs, path);
48
49 n = isA_CFDictionary(config) ? CFDictionaryGetCount(config) : 0;
50 switch (n) {
51 case 0 :
52 // ignore empty configuration entities
53 config = NULL;
54 break;
55 case 1 :
56 if (CFDictionaryContainsKey(config, kSCResvInactive)) {
57 // ignore [effectively] empty configuration entities
58 config = NULL;
59 }
60 break;
61 default :
62 break;
63 }
64
65 return config;
66 }
67
68
69 __private_extern__ Boolean
70 __setPrefsConfiguration(SCPreferencesRef prefs,
71 CFStringRef path,
72 CFDictionaryRef config,
73 Boolean keepInactive)
74 {
75 CFMutableDictionaryRef newConfig;
76 Boolean ok;
77
78 if (!isA_CFDictionary(config)) {
79 _SCErrorSet(kSCStatusInvalidArgument);
80 return FALSE;
81 }
82
83 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
84
85 if (keepInactive) {
86 CFDictionaryRef curConfig;
87
88 // preserve enabled/disabled state
89 curConfig = SCPreferencesPathGetValue(prefs, path);
90 if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
91 // if currently disabled
92 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
93 } else {
94 // if currently enabled
95 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
96 }
97 }
98
99 // set new configuration
100 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
101
102 CFRelease(newConfig);
103 return ok;
104 }
105
106
107 __private_extern__ Boolean
108 __getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path)
109 {
110 CFDictionaryRef config;
111
112 config = SCPreferencesPathGetValue(prefs, path);
113 if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) {
114 return FALSE;
115 }
116
117 return TRUE;
118 }
119
120
121 __private_extern__ Boolean
122 __setPrefsEnabled(SCPreferencesRef prefs,
123 CFStringRef path,
124 Boolean enabled)
125 {
126 CFDictionaryRef curConfig = NULL;
127 CFMutableDictionaryRef newConfig = NULL;
128 Boolean ok = FALSE;
129
130 // preserve current configuration
131 curConfig = SCPreferencesPathGetValue(prefs, path);
132 if (curConfig != NULL) {
133 if (!isA_CFDictionary(curConfig)) {
134 _SCErrorSet(kSCStatusFailed);
135 return FALSE;
136 }
137 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig);
138 } else {
139 newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
140 }
141
142 if (enabled) {
143 // enable
144 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
145 } else {
146 // disable
147 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
148 }
149
150 // update configuration
151 if (CFDictionaryGetCount(newConfig) == 0) {
152 CFRelease(newConfig);
153 newConfig = NULL;
154 }
155
156 if (newConfig == NULL) {
157 ok = SCPreferencesPathRemoveValue(prefs, path);
158 } else {
159 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
160 }
161
162 if (newConfig != NULL) CFRelease(newConfig);
163 return ok;
164 }
165
166
167 #define SYSTEMCONFIGURATION_BUNDLE_ID CFSTR("com.apple.SystemConfiguration")
168 #define SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration.framework"
169
170
171 static CFDictionaryRef
172 __copyTemplates()
173 {
174 CFBundleRef bundle;
175 Boolean ok;
176 CFDictionaryRef templates;
177 CFURLRef url;
178 CFStringRef xmlError = NULL;
179 CFDataRef xmlTemplates = NULL;
180
181 bundle = CFBundleGetBundleWithIdentifier(SYSTEMCONFIGURATION_BUNDLE_ID);
182 if (bundle == NULL) {
183 return NULL;
184 }
185
186 url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL);
187 if (url == NULL) {
188 return NULL;
189 }
190
191 ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL);
192 CFRelease(url);
193 if (!ok || (xmlTemplates == NULL)) {
194 return NULL;
195 }
196
197 // convert the XML data into a property list
198 templates = CFPropertyListCreateFromXMLData(NULL, xmlTemplates, kCFPropertyListImmutable, &xmlError);
199 CFRelease(xmlTemplates);
200 if (templates == NULL) {
201 if (xmlError != NULL) {
202 SCLog(TRUE, LOG_DEBUG, CFSTR("could not load SCNetworkConfiguration templates: %@"), xmlError);
203 CFRelease(xmlError);
204 }
205 return NULL;
206 }
207
208 if (!isA_CFDictionary(templates)) {
209 CFRelease(templates);
210 return NULL;
211 }
212
213 return templates;
214 }
215
216
217 __private_extern__ CFDictionaryRef
218 __copyInterfaceTemplate(CFStringRef interfaceType,
219 CFStringRef childInterfaceType)
220 {
221 CFDictionaryRef interface = NULL;
222 CFDictionaryRef interfaces;
223 CFDictionaryRef templates;
224
225 templates = __copyTemplates();
226 if (templates == NULL) {
227 return NULL;
228 }
229
230 interfaces = CFDictionaryGetValue(templates, CFSTR("Interface"));
231 if (!isA_CFDictionary(interfaces)) {
232 CFRelease(templates);
233 return NULL;
234 }
235
236 if (childInterfaceType == NULL) {
237 interface = CFDictionaryGetValue(interfaces, interfaceType);
238 } else {
239 CFStringRef expandedType;
240
241 expandedType = CFStringCreateWithFormat(NULL,
242 NULL,
243 CFSTR("%@-%@"),
244 interfaceType,
245 childInterfaceType);
246 interface = CFDictionaryGetValue(interfaces, expandedType);
247 CFRelease(expandedType);
248 }
249
250 if (isA_CFDictionary(interface) && (CFDictionaryGetCount(interface) > 0)) {
251 CFRetain(interface);
252 } else {
253 interface = NULL;
254 }
255
256 CFRelease(templates);
257
258 return interface;
259 }
260
261
262 __private_extern__ CFDictionaryRef
263 __copyProtocolTemplate(CFStringRef interfaceType,
264 CFStringRef childInterfaceType,
265 CFStringRef protocolType)
266 {
267 CFDictionaryRef interface = NULL;
268 CFDictionaryRef protocol = NULL;
269 CFDictionaryRef protocols;
270 CFDictionaryRef templates;
271
272 templates = __copyTemplates();
273 if (templates == NULL) {
274 return NULL;
275 }
276
277 protocols = CFDictionaryGetValue(templates, CFSTR("Protocol"));
278 if (!isA_CFDictionary(protocols)) {
279 CFRelease(templates);
280 return NULL;
281 }
282
283 if (childInterfaceType == NULL) {
284 interface = CFDictionaryGetValue(protocols, interfaceType);
285 } else {
286 CFStringRef expandedType;
287
288 expandedType = CFStringCreateWithFormat(NULL,
289 NULL,
290 CFSTR("%@-%@"),
291 interfaceType,
292 childInterfaceType);
293 interface = CFDictionaryGetValue(protocols, expandedType);
294 CFRelease(expandedType);
295 }
296
297 if (isA_CFDictionary(interface)) {
298 protocol = CFDictionaryGetValue(interface, protocolType);
299 if (isA_CFDictionary(protocol) && (CFDictionaryGetCount(protocol) > 0)) {
300 CFRetain(protocol);
301 } else {
302 protocol = NULL;
303 }
304 }
305
306 CFRelease(templates);
307
308 return protocol;
309 }
310
311
312 __private_extern__ Boolean
313 __createInterface(int s, CFStringRef interface)
314 {
315 struct ifreq ifr;
316
317 bzero(&ifr, sizeof(ifr));
318 (void) _SC_cfstring_to_cstring(interface,
319 ifr.ifr_name,
320 sizeof(ifr.ifr_name),
321 kCFStringEncodingASCII);
322
323 if (ioctl(s, SIOCIFCREATE, &ifr) == -1) {
324 SCLog(TRUE,
325 LOG_ERR,
326 CFSTR("could not create interface \"%@\": %s"),
327 interface,
328 strerror(errno));
329 return FALSE;
330 }
331
332 return TRUE;
333 }
334
335
336 __private_extern__ Boolean
337 __destroyInterface(int s, CFStringRef interface)
338 {
339 struct ifreq ifr;
340
341 bzero(&ifr, sizeof(ifr));
342 (void) _SC_cfstring_to_cstring(interface,
343 ifr.ifr_name,
344 sizeof(ifr.ifr_name),
345 kCFStringEncodingASCII);
346
347 if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) {
348 SCLog(TRUE,
349 LOG_ERR,
350 CFSTR("could not destroy interface \"%@\": %s"),
351 interface,
352 strerror(errno));
353 return FALSE;
354 }
355
356 return TRUE;
357 }
358
359
360 __private_extern__ Boolean
361 __markInterfaceUp(int s, CFStringRef interface)
362 {
363 struct ifreq ifr;
364
365 bzero(&ifr, sizeof(ifr));
366 (void) _SC_cfstring_to_cstring(interface,
367 ifr.ifr_name,
368 sizeof(ifr.ifr_name),
369 kCFStringEncodingASCII);
370
371 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
372 SCLog(TRUE,
373 LOG_ERR,
374 CFSTR("could not get flags for interface \"%@\": %s"),
375 interface,
376 strerror(errno));
377 return FALSE;
378 }
379
380 ifr.ifr_flags |= IFF_UP;
381 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
382 SCLog(TRUE,
383 LOG_ERR,
384 CFSTR("could not set flags for interface \"%@\": %s"),
385 interface,
386 strerror(errno));
387 return FALSE;
388 }
389
390 return TRUE;
391 }