]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkConfigurationInternal.c
configd-130.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkConfigurationInternal.c
1 /*
2 * Copyright (c) 2004 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 = NULL;
76 Boolean ok = FALSE;
77
78 if (config != NULL) {
79 if (!isA_CFDictionary(config)) {
80 _SCErrorSet(kSCStatusInvalidArgument);
81 return FALSE;
82 }
83 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
84 } else {
85 newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
86 }
87
88 if (keepInactive) {
89 CFDictionaryRef curConfig;
90
91 /*
92 * preserve enabled/disabled state
93 */
94
95 curConfig = SCPreferencesPathGetValue(prefs, path);
96 if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) {
97 // if currently disabled
98 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
99 } else {
100 // if currently enabled
101 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
102 }
103 }
104
105 /*
106 * set new configuration
107 */
108
109 if (CFDictionaryGetCount(newConfig) == 0) {
110 CFRelease(newConfig);
111 newConfig = NULL;
112 }
113
114 if (newConfig == NULL) {
115 ok = SCPreferencesPathRemoveValue(prefs, path);
116 } else {
117 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
118 }
119
120 if (newConfig != NULL) CFRelease(newConfig);
121 return ok;
122 }
123
124
125 __private_extern__ Boolean
126 __getPrefsEnabled(SCPreferencesRef prefs, CFStringRef path)
127 {
128 CFDictionaryRef config;
129
130 config = SCPreferencesPathGetValue(prefs, path);
131 if (isA_CFDictionary(config) && CFDictionaryContainsKey(config, kSCResvInactive)) {
132 return FALSE;
133 }
134
135 return TRUE;
136 }
137
138
139 __private_extern__ Boolean
140 __setPrefsEnabled(SCPreferencesRef prefs,
141 CFStringRef path,
142 Boolean enabled)
143 {
144 CFDictionaryRef curConfig = NULL;
145 CFMutableDictionaryRef newConfig = NULL;
146 Boolean ok = FALSE;
147
148 /*
149 * preserve current configuration
150 */
151
152 curConfig = SCPreferencesPathGetValue(prefs, path);
153 if (curConfig != NULL) {
154 if (!isA_CFDictionary(curConfig)) {
155 _SCErrorSet(kSCStatusFailed);
156 return FALSE;
157 }
158 newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig);
159 } else {
160 newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
161 }
162
163 if (enabled) {
164 // enable
165 CFDictionaryRemoveValue(newConfig, kSCResvInactive);
166 } else {
167 // disable
168 CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue);
169 }
170
171 /*
172 * update configuration
173 */
174
175 if (CFDictionaryGetCount(newConfig) == 0) {
176 CFRelease(newConfig);
177 newConfig = NULL;
178 }
179
180 if (newConfig == NULL) {
181 ok = SCPreferencesPathRemoveValue(prefs, path);
182 } else {
183 ok = SCPreferencesPathSetValue(prefs, path, newConfig);
184 }
185
186 if (newConfig != NULL) CFRelease(newConfig);
187 return ok;
188 }
189
190
191 #define SYSTEMCONFIGURATION_BUNDLE_ID CFSTR("com.apple.SystemConfiguration")
192 #define SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration.framework"
193
194
195 static CFDictionaryRef
196 __copyTemplates()
197 {
198 CFBundleRef bundle;
199 Boolean ok;
200 CFDictionaryRef templates;
201 CFURLRef url;
202 CFStringRef xmlError = NULL;
203 CFDataRef xmlTemplates = NULL;
204
205 bundle = CFBundleGetBundleWithIdentifier(SYSTEMCONFIGURATION_BUNDLE_ID);
206 if (bundle == NULL) {
207 return NULL;
208 }
209
210 url = CFBundleCopyResourceURL(bundle, CFSTR("NetworkConfiguration"), CFSTR("plist"), NULL);
211 if (url == NULL) {
212 return NULL;
213 }
214
215 ok = CFURLCreateDataAndPropertiesFromResource(NULL, url, &xmlTemplates, NULL, NULL, NULL);
216 CFRelease(url);
217 if (!ok || (xmlTemplates == NULL)) {
218 return NULL;
219 }
220
221 /* convert the XML data into a property list */
222 templates = CFPropertyListCreateFromXMLData(NULL, xmlTemplates, kCFPropertyListImmutable, &xmlError);
223 CFRelease(xmlTemplates);
224 if (templates == NULL) {
225 if (xmlError != NULL) {
226 SCLog(TRUE, LOG_DEBUG, CFSTR("could not load SCNetworkConfiguration templates: %@"), xmlError);
227 CFRelease(xmlError);
228 }
229 return NULL;
230 }
231
232 if (!isA_CFDictionary(templates)) {
233 CFRelease(templates);
234 return NULL;
235 }
236
237 return templates;
238 }
239
240
241 __private_extern__ CFDictionaryRef
242 __copyInterfaceTemplate(CFStringRef interfaceType,
243 CFStringRef childInterfaceType)
244 {
245 CFDictionaryRef interface = NULL;
246 CFDictionaryRef interfaces;
247 CFDictionaryRef templates;
248
249 templates = __copyTemplates();
250 if (templates == NULL) {
251 return NULL;
252 }
253
254 interfaces = CFDictionaryGetValue(templates, CFSTR("Interface"));
255 if (!isA_CFDictionary(interfaces)) {
256 CFRelease(templates);
257 return NULL;
258 }
259
260 if (childInterfaceType == NULL) {
261 interface = CFDictionaryGetValue(interfaces, interfaceType);
262 } else {
263 CFStringRef expandedType;
264
265 expandedType = CFStringCreateWithFormat(NULL,
266 NULL,
267 CFSTR("%@-%@"),
268 interfaceType,
269 childInterfaceType);
270 interface = CFDictionaryGetValue(interfaces, expandedType);
271 CFRelease(expandedType);
272 }
273
274 if (isA_CFDictionary(interface) && (CFDictionaryGetCount(interface) > 0)) {
275 CFRetain(interface);
276 } else {
277 interface = NULL;
278 }
279
280 CFRelease(templates);
281
282 return interface;
283 }
284
285
286 __private_extern__ CFDictionaryRef
287 __copyProtocolTemplate(CFStringRef interfaceType,
288 CFStringRef childInterfaceType,
289 CFStringRef protocolType)
290 {
291 CFDictionaryRef interface = NULL;
292 CFDictionaryRef protocol = NULL;
293 CFDictionaryRef protocols;
294 CFDictionaryRef templates;
295
296 templates = __copyTemplates();
297 if (templates == NULL) {
298 return NULL;
299 }
300
301 protocols = CFDictionaryGetValue(templates, CFSTR("Protocol"));
302 if (!isA_CFDictionary(protocols)) {
303 CFRelease(templates);
304 return NULL;
305 }
306
307 if (childInterfaceType == NULL) {
308 interface = CFDictionaryGetValue(protocols, interfaceType);
309 } else {
310 CFStringRef expandedType;
311
312 expandedType = CFStringCreateWithFormat(NULL,
313 NULL,
314 CFSTR("%@-%@"),
315 interfaceType,
316 childInterfaceType);
317 interface = CFDictionaryGetValue(protocols, expandedType);
318 CFRelease(expandedType);
319 }
320
321 if (isA_CFDictionary(interface)) {
322 protocol = CFDictionaryGetValue(interface, protocolType);
323 if (isA_CFDictionary(protocol) && (CFDictionaryGetCount(protocol) > 0)) {
324 CFRetain(protocol);
325 } else {
326 protocol = NULL;
327 }
328 }
329
330 CFRelease(templates);
331
332 return protocol;
333 }
334
335
336 __private_extern__ Boolean
337 __createInterface(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, SIOCIFCREATE, &ifr) == -1) {
348 SCLog(TRUE,
349 LOG_ERR,
350 CFSTR("could not create interface \"%@\": %s"),
351 interface,
352 strerror(errno));
353 return FALSE;
354 }
355
356 return TRUE;
357 }
358
359
360 __private_extern__ Boolean
361 __destroyInterface(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, SIOCIFDESTROY, &ifr) == -1) {
372 SCLog(TRUE,
373 LOG_ERR,
374 CFSTR("could not destroy interface \"%@\": %s"),
375 interface,
376 strerror(errno));
377 return FALSE;
378 }
379
380 return TRUE;
381 }
382
383
384 __private_extern__ Boolean
385 __markInterfaceUp(int s, CFStringRef interface)
386 {
387 struct ifreq ifr;
388
389 bzero(&ifr, sizeof(ifr));
390 (void) _SC_cfstring_to_cstring(interface,
391 ifr.ifr_name,
392 sizeof(ifr.ifr_name),
393 kCFStringEncodingASCII);
394
395 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
396 SCLog(TRUE,
397 LOG_ERR,
398 CFSTR("could not get flags for interface \"%@\": %s"),
399 interface,
400 strerror(errno));
401 return FALSE;
402 }
403
404 ifr.ifr_flags |= IFF_UP;
405 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
406 SCLog(TRUE,
407 LOG_ERR,
408 CFSTR("could not set flags for interface \"%@\": %s"),
409 interface,
410 strerror(errno));
411 return FALSE;
412 }
413
414 return TRUE;
415 }