]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkMigration.c
configd-699.30.1.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkMigration.c
1 /*
2 * Copyright (c) 2014 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 // SCNetworkMigration.c
26 //
27 // Created by Ashish Kulkarni on 11/19/13.
28 //
29 //
30
31 #include <stdio.h>
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <SystemConfiguration/SystemConfiguration.h>
34 #include <SystemConfiguration/SCNetworkConfigurationPrivate.h>
35 #include <SystemConfiguration/SCNetworkConfigurationInternal.h>
36 #include "SCPreferencesInternal.h"
37 #include <IOKit/network/IONetworkInterface.h>
38 #include <IOKit/network/IONetworkController.h>
39 #include <SystemConfiguration/SCPrivate.h>
40 #include <sys/stat.h>
41 #include <copyfile.h>
42 #include <sys/param.h>
43 #include <pthread.h>
44
45 #define BACK_TO_MY_MAC CFSTR("BackToMyMac")
46 #define BACK_TO_MY_MAC_DSIDS CFSTR("BackToMyMacDSIDs")
47 #define PREFS_DEFAULT_DIR_PLIST "/Library/Preferences/SystemConfiguration"
48 #define PREFS_DEFAULT_DIR_RELATIVE CFSTR("Library/Preferences/SystemConfiguration/")
49 #define PREFS_DEFAULT_CONFIG_PLIST "preferences.plist"
50 #define NETWORK_INTERFACES_PREFS_PLIST "NetworkInterfaces.plist"
51 #define NUM_MIGRATION_PATHS 2
52 #define PLUGIN_ID CFSTR("System Migration")
53 #define PREFERENCES_PLIST_INDEX 0
54 #define NETWORK_INTERFACES_PLIST_INDEX 1
55
56
57 const CFStringRef kSCNetworkConfigurationMigrationActionKey = CFSTR("MigrationActionKey");
58 const CFStringRef kSCNetworkConfigurationRepair = CFSTR("ConfigurationRepair");
59 #if !TARGET_OS_IPHONE
60 static CFDictionaryRef
61 _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs);
62
63 static CFDictionaryRef
64 _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs);
65
66 static CFDictionaryRef
67 _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs);
68 #endif
69 static Boolean
70 _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1, SCNetworkInterfaceRef interface2, Boolean bypassActive);
71
72 static Boolean
73 _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetDir);
74
75 static void
76 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef *prefs, CFURLRef *interfaces)
77 {
78 if (baseURL != NULL) {
79 CFRetain(baseURL);
80 }
81 else {
82 baseURL = CFURLCreateFromFileSystemRepresentation(NULL,
83 (UInt8*)PREFS_DEFAULT_DIR_PLIST,
84 sizeof(PREFS_DEFAULT_DIR_PLIST),
85 TRUE);
86 }
87
88 *prefs = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
89 (UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
90 sizeof(PREFS_DEFAULT_CONFIG_PLIST) - 1,
91 FALSE, baseURL);
92
93 *interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
94 (UInt8*)NETWORK_INTERFACES_PREFS_PLIST,
95 sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1,
96 FALSE, baseURL);
97 CFRelease(baseURL);
98 return;
99 }
100
101 CFArrayRef
102 _SCNetworkConfigurationCopyMigrationPaths(CFDictionaryRef options)
103 {
104 CFURLRef interfaces;
105 CFMutableArrayRef migrationPaths = NULL;
106 CFURLRef prefs;
107
108 if (getenv(INSTALL_ENVIRONMENT) != NULL) {
109 _sc_debug = 1;
110 }
111 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(NULL, &prefs, &interfaces);
112
113 migrationPaths = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
114 CFArrayInsertValueAtIndex(migrationPaths, PREFERENCES_PLIST_INDEX, prefs);
115 CFArrayInsertValueAtIndex(migrationPaths, NETWORK_INTERFACES_PLIST_INDEX, interfaces);
116
117 CFRelease(prefs);
118 CFRelease(interfaces);
119 return migrationPaths;
120 }
121
122 static Boolean
123 _SCNetworkConfigurationRemoveConfigurationFiles(CFURLRef configDir)
124 {
125
126 char configPathString[PATH_MAX];
127 CFURLRef configPathURL = NULL;
128 char configNetworkInterfacesPathString[PATH_MAX];
129 CFURLRef configNetworkInterfacesPathURL = NULL;
130
131 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir, &configPathURL, &configNetworkInterfacesPathURL);
132
133 if(CFURLGetFileSystemRepresentation(configPathURL, TRUE, (UInt8*)configPathString, sizeof(configPathString)) == FALSE) {
134 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: configPathString is NULL"));
135 }
136 else {
137 if (remove(configPathString) != 0) {
138 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: Removing file failed from: %s. Error is %d"), configPathString, errno);
139 }
140 }
141
142 if(CFURLGetFileSystemRepresentation(configNetworkInterfacesPathURL, TRUE, (UInt8*)configNetworkInterfacesPathString, sizeof(configNetworkInterfacesPathString)) == FALSE) {
143 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: configNetwork"));
144 }
145 else {
146 if (remove(configNetworkInterfacesPathString) != 0) {
147 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: Removing file failed from: %s. Error is %d"), configNetworkInterfacesPathString, errno);
148 }
149 }
150
151 if (configPathURL != NULL) {
152 CFRelease(configPathURL);
153 }
154 if (configNetworkInterfacesPathURL != NULL) {
155 CFRelease(configNetworkInterfacesPathURL);
156 }
157
158 return TRUE;
159 }
160
161 static Boolean
162 SCNetworkConfigurationCopyConfigurationFiles(CFURLRef configDir,
163 CFURLRef targetDir) // TargetDir needs to exist
164 {
165 errno_t error;
166 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
167 char networkInterfacesPathString[PATH_MAX];
168 CFURLRef networkInterfacesPathURL = NULL;
169 copyfile_state_t networkInterfacesState;
170 char preferencesPathString[PATH_MAX];
171 CFURLRef preferencesPathURL = NULL;
172 Boolean removeTargetFiles = FALSE;
173 copyfile_state_t state;
174 Boolean success = FALSE;
175 char targetNetworkInterfacesPathString[PATH_MAX];
176 CFURLRef targetNetworkInterfacesPathURL = NULL;
177 char targetPathString[PATH_MAX];
178 CFURLRef targetPathURL = NULL;
179
180 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(targetDir, &targetPathURL, &targetNetworkInterfacesPathURL);
181
182 if (CFURLGetFileSystemRepresentation(targetPathURL, TRUE, (UInt8*)targetPathString, sizeof(targetPathString)) == FALSE) {
183 SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: targetPathString is NULL"));
184 goto done;
185 }
186
187 if (CFURLGetFileSystemRepresentation(targetNetworkInterfacesPathURL, TRUE, (UInt8*)targetNetworkInterfacesPathString, sizeof(targetNetworkInterfacesPathString)) == FALSE) {
188 SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: targetNetworkInterfacesPathString is NULL"));
189 goto done;
190 }
191
192 if (configDir == NULL) {
193 removeTargetFiles = TRUE;
194 success = TRUE;
195 goto done;
196 }
197 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir, &preferencesPathURL, &networkInterfacesPathURL);
198
199 if (CFURLGetFileSystemRepresentation(preferencesPathURL, TRUE, (UInt8*)preferencesPathString, sizeof(preferencesPathString)) == FALSE) {
200 SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: preferencesPathString is NULL"));
201 goto done;
202 }
203
204
205 if (CFURLGetFileSystemRepresentation(networkInterfacesPathURL, TRUE, (UInt8*)networkInterfacesPathString, sizeof(networkInterfacesPathString)) == FALSE) {
206 SCLog(_sc_debug, LOG_DEBUG, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: networkInterfacePathString is NULL"));
207 goto done;
208 }
209
210 state = copyfile_state_alloc();
211 if ((error = copyfile(preferencesPathString, targetPathString, state, COPYFILE_ALL)) != 0) {
212 SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: Copying failed from:%s to %s. Error is %d"), preferencesPathString, targetPathString, errno);
213 copyfile_state_free(state);
214 removeTargetFiles = TRUE;
215 goto done;
216 }
217 copyfile_state_free(state);
218 chmod(targetPathString, mode);
219
220 networkInterfacesState = copyfile_state_alloc();
221 if ((error = copyfile(networkInterfacesPathString, targetNetworkInterfacesPathString, networkInterfacesState, COPYFILE_ALL)) != 0) {
222 SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: Copying failed from:%s to %s. Error is %d"), networkInterfacesPathString, targetNetworkInterfacesPathString, errno);
223 copyfile_state_free(networkInterfacesState);
224 removeTargetFiles = TRUE;
225 goto done;
226 }
227 copyfile_state_free(networkInterfacesState);
228 chmod(targetNetworkInterfacesPathString, mode);
229
230 success = TRUE;
231 done:
232 if (removeTargetFiles == TRUE) {
233 _SCNetworkConfigurationRemoveConfigurationFiles(targetDir);
234 }
235 if (preferencesPathURL != NULL) {
236 CFRelease(preferencesPathURL);
237 }
238 if (networkInterfacesPathURL != NULL) {
239 CFRelease(networkInterfacesPathURL);
240 }
241 if (targetPathURL != NULL) {
242 CFRelease(targetPathURL);
243 }
244 if (targetNetworkInterfacesPathURL != NULL) {
245 CFRelease(targetNetworkInterfacesPathURL);
246 }
247 return success;
248 }
249
250
251 /* -----------------------------------------------------------------------------
252 Create directories and intermediate directories as required.
253 ----------------------------------------------------------------------------- */
254 static Boolean
255 _SCNetworkConfigurationMakePathIfNeeded(CFURLRef pathURL)
256 {
257 char *c;
258 mode_t newmask;
259 char path[PATH_MAX];
260 char thepath[PATH_MAX];
261 CFIndex slen=0;
262 struct stat sb;
263 Boolean success = FALSE;
264
265 if (CFURLGetFileSystemRepresentation(pathURL, TRUE, (UInt8 *)path, sizeof(path)) == FALSE) {
266 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMakePathIfNeeded: Could not get character array from target string"));
267 return success;
268 }
269 SCLog(TRUE, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMakePathIfNeeded: Creating path: %s"), path);
270
271 newmask = S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH;
272
273 slen = strlen(path);
274
275 strlcpy( thepath, path, slen+1);
276 c = thepath;
277 if ( *c == '/' )
278 c++;
279 for( ; !success; c++){
280 if ( (*c == '/') || ( *c == '\0' )){
281 if ( *c == '\0' )
282 success = TRUE;
283 else
284 *c = '\0';
285 if ( mkdir( thepath, newmask) ){
286 if ( errno == EEXIST || errno == EISDIR){
287 if ( stat(thepath, &sb) < 0){
288 printf("stat returned value < 0\n");
289 break;
290 }
291 } else {
292 printf("received error: %s\n", strerror(errno));
293 break;
294 }
295 }
296 *c = '/';
297 }
298 }
299 return success;
300 }
301
302 static SCPreferencesRef
303 __SCNetworkCreateDefaultPref(CFStringRef prefsID)
304 {
305 SCPreferencesRef prefs;
306 SCNetworkSetRef currentSet;
307 CFStringRef model;
308
309 prefs = SCPreferencesCreate(NULL, PLUGIN_ID, prefsID);
310 if (prefs == NULL) {
311 return NULL;
312 }
313
314 currentSet = SCNetworkSetCopyCurrent(prefs);
315 if (currentSet == NULL) {
316 CFBundleRef bundle;
317 CFStringRef setName = NULL;
318
319 currentSet = SCNetworkSetCreate(prefs);
320 bundle = _SC_CFBundleGet();
321 if (bundle != NULL) {
322 setName = CFBundleCopyLocalizedString(bundle,
323 CFSTR("DEFAULT_SET_NAME"),
324 CFSTR("Automatic"),
325 NULL);
326 }
327 SCNetworkSetSetName(currentSet, (setName != NULL) ? setName : CFSTR("Automatic"));
328 SCNetworkSetSetCurrent(currentSet);
329 if (setName != NULL) {
330 CFRelease(setName);
331 }
332 }
333 SCNetworkSetEstablishDefaultConfiguration(currentSet);
334 CFRelease(currentSet);
335
336 model = SCPreferencesGetValue(prefs, MODEL);
337 if (model == NULL) {
338 model = _SC_hw_model(FALSE);
339 SCPreferencesSetValue(prefs, MODEL, model);
340 }
341
342 return prefs;
343 }
344
345 __private_extern__
346 SCPreferencesRef
347 __SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID)
348 {
349 CFMutableArrayRef interfaces = NULL;
350 CFStringRef model;
351 CFArrayRef networkInterfaces;
352 SCPreferencesRef ni_prefs;
353 CFComparisonResult res;
354
355
356 networkInterfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
357
358 if (networkInterfaces == NULL) {
359 return NULL;
360 }
361 if (prefsID == NULL) {
362 prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
363 }
364 else {
365 CFRetain(prefsID);
366 }
367
368 ni_prefs = SCPreferencesCreate(NULL, PLUGIN_ID , prefsID);
369 CFRelease(prefsID);
370
371 if (ni_prefs == NULL) {
372 goto done;
373 }
374
375 interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
376
377 for (CFIndex idx = 0; idx < CFArrayGetCount(networkInterfaces); idx++) {
378 CFIndex idx2 = 0;
379 CFNumberRef if_type;
380 CFNumberRef if_unit;
381 SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(networkInterfaces, idx);
382 CFDictionaryRef interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface);
383
384 if (interfaceEntity == NULL) {
385 continue;
386 }
387
388 if_type = _SCNetworkInterfaceGetIOInterfaceType(interface);
389 if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
390
391 if ((if_type == NULL) || (if_unit == NULL)) {
392 CFRelease(interfaceEntity);
393 continue;
394 }
395
396 for (idx2 = 0; idx2 < CFArrayGetCount(interfaces); idx2++) {
397 CFNumberRef db_type;
398 CFNumberRef db_unit;
399 CFDictionaryRef dict = CFArrayGetValueAtIndex(interfaces, idx2);
400
401 db_type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
402 db_unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
403 res = CFNumberCompare(if_type, db_type, NULL);
404 if (res == kCFCompareLessThan
405 || (res == kCFCompareEqualTo
406 && (CFNumberCompare(if_unit, db_unit, NULL) == kCFCompareLessThan))) {
407 break;
408 }
409 }
410
411 CFArrayInsertValueAtIndex(interfaces, idx2, interfaceEntity);
412 CFRelease(interfaceEntity);
413
414 }
415 SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces);
416
417 model = SCPreferencesGetValue(ni_prefs, MODEL);
418 if (model == NULL) {
419 model = _SC_hw_model(FALSE);
420 SCPreferencesSetValue(ni_prefs, MODEL, model);
421 }
422 done:
423 if (interfaces != NULL) {
424 CFRelease(interfaces);
425 }
426 if (networkInterfaces != NULL) {
427 CFRelease(networkInterfaces);
428 }
429
430 return ni_prefs;
431 }
432
433
434 /*
435 * _SCNetworkConfigurationPerformMigration will migrate configuration between source and destination systems
436 */
437 CF_RETURNS_RETAINED
438 CFArrayRef
439 _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir, CFURLRef targetDir, CFDictionaryRef options)
440 {
441 CFURLRef currentDirConfig = NULL;
442 CFURLRef currentSystemPath = NULL;
443 Boolean migrationComplete = FALSE;
444 CFArrayRef paths = NULL;
445 Boolean removeTargetOnFailure = FALSE;
446 CFURLRef sourceDirConfig = NULL;
447 CFURLRef targetDirConfig = NULL;
448
449 if (getenv(INSTALL_ENVIRONMENT) != NULL) {
450 _sc_debug = 1;
451 }
452
453 // Both sourceDir and currentDir cannot be NULL because NULL value indicates using current system
454 if (sourceDir == NULL && currentDir == NULL) {
455 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Both sourceDir and currentDir are NULL"));
456 goto done;
457 }
458
459 currentSystemPath = CFURLCreateWithString(NULL,
460 PREFS_DEFAULT_DIR,
461 NULL);
462
463 // if either of the sourceDir or currentDir are NULL, then populate it with current system path
464 if (sourceDir == NULL) {
465 sourceDirConfig = CFRetain(currentSystemPath);
466 }
467 else {
468 sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, sourceDir);
469 }
470
471 if (currentDir != NULL) {
472 currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, currentDir);
473 }
474 // If the targetDir is not provided then migration will take place in currentDir
475 if (targetDir == NULL) {
476 targetDirConfig = CFRetain(currentSystemPath);
477 }
478 else {
479 targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, targetDir);
480 }
481 // Source directory cannot be the same as Target Directory
482 if (CFEqual(sourceDirConfig, targetDirConfig)) {
483 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Source directory cannot be the same as target directory"));
484 goto done;
485 }
486
487 if ((currentDirConfig == NULL) || (CFEqual(currentDirConfig, targetDirConfig) == FALSE)) {
488 if (_SCNetworkConfigurationMakePathIfNeeded(targetDirConfig) == FALSE) {
489 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Could not create target directory as expected"));
490 goto done;
491 }
492
493 if (SCNetworkConfigurationCopyConfigurationFiles(currentDirConfig, targetDirConfig) == FALSE) {
494 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Could not copy configuration files from %@ to %@"),
495 currentDirConfig, targetDirConfig);
496 }
497 else if (currentDirConfig != NULL) {
498 removeTargetOnFailure = TRUE; // Configuration files were copied over to target directory
499 // If migration failed, then we should remove those configuration
500 // files since current directory and target directory are not
501 // the same
502 }
503 }
504
505 // If both source and current configurations point to current system, then no migration needs to be done.
506 if ((currentDirConfig != NULL) && (CFEqual(sourceDirConfig, currentDirConfig) == TRUE)) {
507 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: both source and current configurations point to same path ... No migration needs to be done"));
508 migrationComplete = TRUE;
509 }
510 else {
511 migrationComplete = _SCNetworkConfigurationMigrateConfiguration(sourceDirConfig, targetDirConfig);
512 }
513 SCLog(TRUE, LOG_NOTICE, CFSTR("Migration %s"), migrationComplete ? "complete" : "failed");
514 if (migrationComplete == TRUE) {
515 paths = _SCNetworkConfigurationCopyMigrationPaths(NULL);
516 }
517 else {
518 // If migration fails, then remove configuration files from target config if they are
519 // copied from the current directory
520 if (removeTargetOnFailure == TRUE) {
521 _SCNetworkConfigurationRemoveConfigurationFiles(targetDirConfig);
522 }
523 }
524 done:
525 if (currentDirConfig != NULL) {
526 CFRelease(currentDirConfig);
527 }
528 if (currentSystemPath != NULL) {
529 CFRelease(currentSystemPath);
530 }
531 if (sourceDirConfig != NULL) {
532 CFRelease(sourceDirConfig);
533 }
534 if (targetDirConfig != NULL) {
535 CFRelease(targetDirConfig);
536 }
537 return paths;
538 }
539
540 static Boolean
541 _SCNetworkConfigurationMigrateIsFilePresent(CFURLRef filePath)
542 {
543 Boolean fileExists = false;
544 char filePathStr[PATH_MAX];
545 int statResult = 0;
546 struct stat statStruct = {0, };
547
548 if (filePath == NULL) {
549 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateIsFilePresent: filePath is NULL"));
550 goto done;
551 }
552
553 if (CFURLGetFileSystemRepresentation(filePath, TRUE, (UInt8*) filePathStr, sizeof(filePathStr)) == FALSE) {
554 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateIsFilePresent: Couldn't get file system representation\n"));
555 goto done;
556 }
557
558 statResult = stat(filePathStr, &statStruct);
559
560 if (statResult == 0) {
561 fileExists = TRUE;
562 }
563 done:
564 return fileExists;
565 }
566
567 static Boolean
568 __SCNetworkConfigurationMigrateConfigurationFilesPresent(CFURLRef baseURL, CFArrayRef* migrationPaths)
569 {
570 Boolean configFilesPresent = FALSE;
571 CFIndex count;
572 CFURLRef filePath = NULL;
573 CFURLRef interfaces;
574 CFMutableArrayRef migrationPathsMutable = NULL;
575 CFURLRef prefs;
576
577 if (baseURL == NULL) {
578 SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: baseURL is NULL"));
579 goto done;
580 }
581
582 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(baseURL, &prefs, &interfaces);
583
584 migrationPathsMutable = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
585 CFArrayInsertValueAtIndex(migrationPathsMutable, PREFERENCES_PLIST_INDEX, prefs);
586 CFArrayInsertValueAtIndex(migrationPathsMutable, NETWORK_INTERFACES_PLIST_INDEX, interfaces);
587
588 CFRelease(prefs);
589 CFRelease(interfaces);
590
591 *migrationPaths = migrationPathsMutable;
592
593 if ((*migrationPaths == NULL) ||
594 ((count = CFArrayGetCount(*migrationPaths)) == 0)) {
595 SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: migrationPath is NULL or number of elements in migrationPath array is 0"));
596 goto done;
597 }
598
599 for (CFIndex idx = 0; idx < count; idx++) {
600 filePath = CFArrayGetValueAtIndex(*migrationPaths, idx);
601 if (_SCNetworkConfigurationMigrateIsFilePresent(filePath) == FALSE) {
602 SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: File not present: %@"), filePath);
603 goto done;
604 }
605 }
606
607 configFilesPresent = TRUE; // all necessary configuration files present
608 done:
609 return configFilesPresent;
610 }
611
612
613 static CFMutableArrayRef
614 _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences (SCPreferencesRef ni_prefs, Boolean isBuiltin)
615 {
616 CFIndex count = 0;
617 SCNetworkInterfaceRef interface;
618 CFArrayRef interfaceList = NULL;
619 CFMutableArrayRef resultInterfaceList = NULL;
620
621 interfaceList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
622 if (interfaceList == NULL) {
623 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences: interfaceList is NULL"));
624 goto done;
625 }
626
627 count = CFArrayGetCount(interfaceList);
628 if (count > 0) {
629 resultInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
630 }
631
632 for (CFIndex i = 0; i < count; i++) {
633 interface = CFArrayGetValueAtIndex(interfaceList, i);
634
635 if (_SCNetworkInterfaceIsBuiltin(interface) == isBuiltin) {
636 CFArrayAppendValue(resultInterfaceList, interface);
637 }
638 }
639
640 done:
641 if (interfaceList != NULL) {
642 CFRelease(interfaceList);
643 }
644 return resultInterfaceList;
645 }
646
647 static CFMutableDictionaryRef
648 _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
649 {
650 CFNumberRef cfMaxUnit;
651 CFIndex count = 0;
652 CFArrayRef ifList = NULL;
653 SCNetworkInterfaceRef interface;
654 CFMutableDictionaryRef InterfaceTypeToMaxUnitMapping = NULL;
655 CFNumberRef type;
656 CFNumberRef unit;
657
658 ifList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
659
660 if (ifList == NULL) {
661 SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType: ifList is NULL"));
662 return 0;
663 }
664
665 InterfaceTypeToMaxUnitMapping = CFDictionaryCreateMutable(NULL, 0,
666 &kCFTypeDictionaryKeyCallBacks,
667 &kCFTypeDictionaryValueCallBacks);
668 count = CFArrayGetCount(ifList);
669
670 for (CFIndex idx = 0; idx < count; idx++) {
671 cfMaxUnit = NULL;
672 interface = CFArrayGetValueAtIndex(ifList, idx);
673
674 if (isA_SCNetworkInterface(interface) == NULL) {
675 continue;
676 }
677
678 type = _SCNetworkInterfaceGetIOInterfaceType(interface);
679
680 if (isA_CFNumber(type) == NULL) {
681 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType: type is NULL"));
682 continue;
683 }
684
685 if (CFDictionaryContainsKey(InterfaceTypeToMaxUnitMapping, type) == FALSE) {
686 int temp = 0;
687 cfMaxUnit = CFNumberCreate(NULL, kCFNumberIntType, &temp);
688 CFDictionaryAddValue(InterfaceTypeToMaxUnitMapping, type, cfMaxUnit);
689 CFRelease(cfMaxUnit);
690 }
691
692 if (cfMaxUnit == NULL) {
693 cfMaxUnit = CFDictionaryGetValue(InterfaceTypeToMaxUnitMapping, type);
694 }
695
696 unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
697
698 if (isA_CFNumber(unit) == NULL) {
699 continue;
700 }
701
702 if (CFNumberCompare(unit, cfMaxUnit, NULL) == kCFCompareGreaterThan) {
703 CFDictionarySetValue(InterfaceTypeToMaxUnitMapping, type, unit);
704 }
705 }
706 if (ifList != NULL) {
707 CFRelease(ifList);
708 }
709 return InterfaceTypeToMaxUnitMapping;
710 }
711
712 static CFMutableDictionaryRef
713 _SCNetworkConfigurationCopyBuiltinMapping (SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
714 {
715 CFMutableDictionaryRef builtinMapping = NULL;
716 CFIndex sourceBuiltinInterfaceCount = 0;
717 CFMutableArrayRef sourceBuiltinInterfaces = NULL;
718 SCNetworkInterfaceRef sourceInterface;
719 CFIndex targetBuiltinInterfaceCount = 0;
720 CFMutableArrayRef targetBuiltinInterfaces = NULL;
721 SCNetworkInterfaceRef targetInterface;
722
723 sourceBuiltinInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePrefs, TRUE);
724 if (isA_CFArray(sourceBuiltinInterfaces) == NULL) {
725 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyBuiltinMapping: sourceBuiltinInterfaces is NULL"));
726 goto done;
727 }
728 sourceBuiltinInterfaceCount = CFArrayGetCount(sourceBuiltinInterfaces);
729
730 targetBuiltinInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs, TRUE);
731 if (isA_CFArray(targetBuiltinInterfaces) == NULL) {
732 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyBuiltinMapping: targetBuiltinInterfaces is NULL"));
733 goto done;
734 }
735 targetBuiltinInterfaceCount = CFArrayGetCount(targetBuiltinInterfaces);
736
737 // Builtin Mapping will try to map all source interfaces into target interfaces
738 for (CFIndex idx = 0; idx < sourceBuiltinInterfaceCount; idx++) {
739 sourceInterface = CFArrayGetValueAtIndex(sourceBuiltinInterfaces, idx);
740 for (CFIndex idx2 = 0; idx2 < targetBuiltinInterfaceCount; idx2++) {
741 targetInterface = CFArrayGetValueAtIndex(targetBuiltinInterfaces, idx2);
742
743 if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, FALSE) == TRUE) {
744 if (builtinMapping == NULL) {
745 builtinMapping = CFDictionaryCreateMutable(NULL, 0,
746 &kCFTypeDictionaryKeyCallBacks,
747 &kCFTypeDictionaryValueCallBacks);
748 }
749 CFDictionaryAddValue(builtinMapping, sourceInterface, targetInterface);
750 CFArrayRemoveValueAtIndex(targetBuiltinInterfaces, idx2);
751 break;
752 }
753 }
754 targetBuiltinInterfaceCount = CFArrayGetCount(targetBuiltinInterfaces);
755 }
756
757 done:
758 if (sourceBuiltinInterfaces != NULL) {
759 CFRelease(sourceBuiltinInterfaces);
760 }
761 if (targetBuiltinInterfaces != NULL) {
762 CFRelease(targetBuiltinInterfaces);
763 }
764 return builtinMapping;
765 }
766
767 static CFMutableDictionaryRef
768 _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref, SCPreferencesRef targetPrefs)
769 {
770 CFNumberRef cfMaxTargetUnit = NULL;
771 CFNumberRef currentInterfaceUnit = NULL;
772 CFMutableDictionaryRef externalMapping = NULL;
773 CFMutableDictionaryRef InterfaceTypeToMaxUnitMapping = NULL;
774 int maxTargetUnit;
775 int newTargetUnit;
776 CFIndex sourceExternalInterfaceCount = 0;
777 CFMutableArrayRef sourceExternalInterfaces = NULL;
778 SCNetworkInterfaceRef sourceInterface = NULL;
779 CFIndex targetExternalInterfaceCount = 0;
780 CFMutableArrayRef targetExternalInterfaces = NULL;
781 SCNetworkInterfaceRef targetInterface = NULL;
782 CFNumberRef type;
783
784 sourceExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePref, FALSE);
785 if (isA_CFArray(sourceExternalInterfaces) == NULL) {
786 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceExternalInterfaces is NULL"));
787 goto done;
788 }
789 sourceExternalInterfaceCount = CFArrayGetCount(sourceExternalInterfaces);
790
791 if (sourceExternalInterfaceCount == 0) {
792 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceExternalInterfaceCount is 0"));
793 goto done;
794 }
795
796 targetExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs, FALSE);
797 if (isA_CFArray(targetExternalInterfaces) == NULL) {
798 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: targetExternalInterfaces is NULL"));
799 goto done;
800 }
801
802 InterfaceTypeToMaxUnitMapping = _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(targetPrefs);
803 externalMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
804
805 // Map all external interfaces which exist in both source and target
806 for (CFIndex idx = 0; idx < sourceExternalInterfaceCount; idx++) {
807 sourceInterface = CFArrayGetValueAtIndex(sourceExternalInterfaces, idx);
808 targetExternalInterfaceCount = CFArrayGetCount(targetExternalInterfaces);
809 currentInterfaceUnit = NULL;
810
811 for (CFIndex idx2 = 0; idx2 < targetExternalInterfaceCount; idx2++) {
812 targetInterface = CFArrayGetValueAtIndex(targetExternalInterfaces, idx2);
813
814 if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, TRUE) == TRUE) {
815 CFDictionaryAddValue(externalMapping, sourceInterface, targetInterface);
816 CFArrayRemoveValueAtIndex(targetExternalInterfaces, idx2);
817 break;
818 }
819 }
820
821 if (CFDictionaryContainsKey(externalMapping, sourceInterface) == FALSE) {
822 // Create new mappings for external source interfaces which don't exist in the target
823 type = _SCNetworkInterfaceGetIOInterfaceType(sourceInterface);
824
825 cfMaxTargetUnit = CFDictionaryGetValue(InterfaceTypeToMaxUnitMapping, type);
826 if (cfMaxTargetUnit != NULL) {
827 CFNumberGetValue(cfMaxTargetUnit, kCFNumberIntType, &maxTargetUnit);
828 newTargetUnit = maxTargetUnit + 1;
829 }
830 else {
831 newTargetUnit = 0;
832 }
833
834 cfMaxTargetUnit = CFNumberCreate(NULL, kCFNumberIntType, &newTargetUnit);
835 CFDictionarySetValue(InterfaceTypeToMaxUnitMapping, type, cfMaxTargetUnit);
836
837 targetInterface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL, sourceInterface, NULL, NULL);
838
839 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceInterface: %p, target Interface: %p"), sourceInterface, targetInterface);
840
841 currentInterfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(targetInterface);
842
843 if ((isA_CFNumber(currentInterfaceUnit) == NULL) ||
844 (CFEqual(currentInterfaceUnit, cfMaxTargetUnit) == FALSE)) {
845 // Update the interface unit
846 __SCNetworkInterfaceSetIOInterfaceUnit(targetInterface, cfMaxTargetUnit);
847 }
848
849 CFDictionaryAddValue(externalMapping, sourceInterface, targetInterface);
850
851 CFRelease(targetInterface);
852 targetInterface = NULL;
853 CFRelease(cfMaxTargetUnit);
854 cfMaxTargetUnit = NULL;
855 }
856 }
857 done:
858 if (sourceExternalInterfaces != NULL) {
859 CFRelease(sourceExternalInterfaces);
860 }
861 if (targetExternalInterfaces != NULL) {
862 CFRelease(targetExternalInterfaces);
863 }
864 if (InterfaceTypeToMaxUnitMapping != NULL) {
865 CFRelease(InterfaceTypeToMaxUnitMapping);
866 }
867 return externalMapping;
868 }
869 static Boolean
870 __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStringRef interfaceName2);
871
872 static Boolean
873 _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1, SCNetworkInterfaceRef interface2, Boolean bypassActive)
874 {
875 Boolean interface1IsBuiltin;
876 CFStringRef interface1Prefix;
877 CFStringRef interface1Type;
878 CFStringRef interface1UserDefinedName;
879 Boolean interface2IsBuiltin;
880 CFStringRef interface2Prefix;
881 CFStringRef interface2Type;
882 CFStringRef interface2UserDefinedName;
883
884 if (interface1 == interface2) {
885 // No work needs to be done
886 return TRUE;
887 }
888 interface1IsBuiltin = _SCNetworkInterfaceIsBuiltin(interface1);
889 interface2IsBuiltin = _SCNetworkInterfaceIsBuiltin(interface2);
890
891 interface1UserDefinedName = SCNetworkInterfaceGetLocalizedDisplayName(interface1);
892 interface2UserDefinedName = SCNetworkInterfaceGetLocalizedDisplayName(interface2);
893
894 interface1Type = SCNetworkInterfaceGetInterfaceType(interface1);
895 interface2Type = SCNetworkInterfaceGetInterfaceType(interface2);
896
897 interface1Prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface1);
898 interface2Prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface2);
899
900 // Check if have same builtin values.
901 // Check if User Defined name matches
902 // Check if SCNetwork Interface Type matches
903
904 if (interface1IsBuiltin != interface2IsBuiltin) {
905 return FALSE;
906 }
907
908 if (_SC_CFEqual(interface1Type, interface2Type) == FALSE) {
909 return FALSE;
910 }
911
912 if (_SC_CFEqual(interface1Prefix, interface2Prefix) == FALSE) {
913 return FALSE;
914 }
915
916 if (_SC_CFEqual(interface1UserDefinedName, interface2UserDefinedName) == FALSE) {
917 // Checking if we have a mismatch because of the name Ethernet and Ethernet 1
918 // Checking if we have a mismatch because of the name Airport and WiFi
919 if ((interface1IsBuiltin == TRUE) &&
920 (interface2IsBuiltin == TRUE) &&
921 (__SCNetworkConfigurationInterfaceNameIsEquiv(interface1UserDefinedName, interface2UserDefinedName) == TRUE)) {
922 return TRUE;
923 }
924 return FALSE;
925 }
926 return TRUE;
927 }
928
929 static Boolean
930 __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStringRef interfaceName2)
931 {
932 CFStringRef interfaceArray[] = { CFSTR("iPhone"), CFSTR("iPad"), CFSTR("iPod"), CFSTR("AppleTV") };
933 const int interfaceCount = sizeof(interfaceArray) / sizeof(CFStringRef);
934 CFStringRef portSuffix = CFSTR(", Port 1");
935
936 if ((isA_CFString(interfaceName1) != NULL) &&
937 (isA_CFString(interfaceName2) != NULL)) {
938 if (CFEqual(interfaceName1, interfaceName2) == FALSE) {
939 // Check if we are looking at the WiFi interface
940 if ((CFEqual(interfaceName1, CFSTR("AirPort")) ||
941 (CFEqual(interfaceName1, CFSTR("Wi-Fi")))) &&
942 (CFEqual(interfaceName2, CFSTR("AirPort")) ||
943 (CFEqual(interfaceName2, CFSTR("Wi-Fi"))))) {
944 return TRUE;
945 }
946
947 if (((CFEqual(interfaceName1, CFSTR("Ethernet"))) ||
948 (CFEqual(interfaceName1, CFSTR("Ethernet 1")))) &&
949 ((CFEqual(interfaceName2, CFSTR("Ethernet"))) ||
950 (CFEqual(interfaceName2, CFSTR("Ethernet 1"))))) {
951 return TRUE;
952 }
953
954 if (((CFStringHasSuffix(interfaceName1, portSuffix) == TRUE) &&
955 (CFStringCompareWithOptions(interfaceName1, interfaceName2, CFRangeMake(0, (CFStringGetLength(interfaceName1) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo)) ||
956 ((CFStringHasSuffix(interfaceName2, portSuffix) == TRUE) &&
957 (CFStringCompareWithOptions(interfaceName2, interfaceName1, CFRangeMake(0, (CFStringGetLength(interfaceName2) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo))) {
958 return TRUE;
959 }
960
961 for (CFIndex idx = 0; idx < interfaceCount; idx++) {
962 CFStringRef tempInterfaceName = interfaceArray[idx];
963 if ((CFEqual(interfaceName1, tempInterfaceName) == TRUE ||
964 __SCNetworkInterfaceMatchesName(interfaceName1, tempInterfaceName) == TRUE) &&
965 (CFEqual(interfaceName2, tempInterfaceName) == TRUE ||
966 __SCNetworkInterfaceMatchesName(interfaceName2, tempInterfaceName) == TRUE)) {
967 return TRUE;
968 }
969 }
970 }
971 else {
972 return TRUE;
973 }
974 }
975
976 return FALSE;
977 }
978
979 typedef struct {
980 CFDictionaryRef interfaceMapping;
981 CFMutableArrayRef interfacesMissingServices;
982 } SCNetworkConfigurationMissingServiceContext;
983
984 typedef struct {
985 CFDictionaryRef bsdNameToBridgeServices; // Mapping of BSD Name to SCBridgeInterfaceRef
986 CFDictionaryRef bsdNameToBondServices; // Mapping of BSD Name to SCBondInterfaceRef
987 CFDictionaryRef bsdNameToVLANServices; // Mapping of BSD Name to SCVLANInterfaceRef
988 CFDictionaryRef interfaceMapping;
989 Boolean* isValid;
990 CFMutableArrayRef interfaceToBeRemoved; // SCNetworkInterfaceRef. Services containing the interface will be removed
991 CFMutableArrayRef interfaceToBeReplaced;// SCNetworkInterfaceRef. Services containing the interface will be replaced with default service
992 Boolean repair;
993 } SCNetworkConfigurationValidityContext;
994
995 static void
996 _SCNetworkConfigurationValidateInterface (const void *key, const void *value, void *context)
997 {
998 CFStringRef bsdName = (CFStringRef)key;
999 SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext*)context;
1000 CFDictionaryRef bsdNameToBridgeServices = ctx->bsdNameToBridgeServices;
1001 CFDictionaryRef bsdNameToBondServices = ctx->bsdNameToBondServices;
1002 CFDictionaryRef bsdNameToVLANServices = ctx->bsdNameToVLANServices;
1003 SCNetworkInterfaceRef interface = NULL;
1004 CFDictionaryRef interfaceMapping = ctx->interfaceMapping;
1005 CFStringRef interfaceUserDefinedName = NULL;
1006 Boolean repair = ctx->repair;
1007 SCNetworkInterfaceRef serviceInterface = (SCNetworkInterfaceRef)value;
1008 CFStringRef serviceInterfaceUserDefinedName = NULL;
1009 CFMutableArrayRef interfaceToBeRemoved = ctx->interfaceToBeRemoved;
1010 CFMutableArrayRef interfaceToBeReplaced = ctx->interfaceToBeReplaced;
1011
1012 // No work needs to be done if we have already made determination that configuration somewhere is not valid,
1013 // or we don't intend to repair invalid configuration.
1014 if ((*ctx->isValid == FALSE) && (repair == FALSE)) {
1015 return;
1016 }
1017
1018 // There is no interface present for the service
1019 interface = CFDictionaryGetValue(interfaceMapping, bsdName);
1020 if (interface == NULL) {
1021 if ((((bsdNameToBridgeServices != NULL) && (CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName) == FALSE))) &&
1022 (((bsdNameToBondServices != NULL) && (CFDictionaryContainsKey(bsdNameToBondServices, bsdName) == FALSE))) &&
1023 (((bsdNameToVLANServices != NULL) && (CFDictionaryContainsKey(bsdNameToVLANServices, bsdName) == FALSE)))) {
1024 // Not a virtual interface
1025 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationValidateInterface: There is no real interface with bsd name: %@ for service"), bsdName);
1026
1027 if (repair == TRUE) {
1028 CFArrayAppendValue(interfaceToBeRemoved, serviceInterface);
1029 }
1030 *ctx->isValid = FALSE;
1031 }
1032 return;
1033 }
1034
1035 // TODO: Need to compare between both SCNetworkInterfaceRefs
1036 interfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
1037 serviceInterfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(serviceInterface);
1038
1039 if (__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName, serviceInterfaceUserDefinedName) == FALSE) {
1040 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationValidateInterface: Interface user defined name: %@ doesn't match service interface user defined name: %@"), interfaceUserDefinedName, serviceInterfaceUserDefinedName);
1041 *ctx->isValid = FALSE;
1042 // Add service interface to the interfaceToBeReplaced list
1043 if (isA_CFArray(interfaceToBeReplaced) != NULL) {
1044 CFArrayAppendValue(interfaceToBeReplaced, interface);
1045 }
1046 if (isA_CFArray(interfaceToBeRemoved) != NULL) {
1047 CFArrayAppendValue(interfaceToBeRemoved, serviceInterface);
1048 }
1049 return;
1050 }
1051 }
1052
1053 static void
1054 _SCNetworkConfigurationCollectMissingService(const void *key, const void *value, void *context)
1055 {
1056 CFStringRef bsdName = (CFStringRef)key;
1057 SCNetworkConfigurationMissingServiceContext *ctx = (SCNetworkConfigurationMissingServiceContext*)context;
1058 SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
1059 CFMutableArrayRef interfacesMissingServices = ctx->interfacesMissingServices;
1060 CFDictionaryRef serviceInterfaceMapping = ctx->interfaceMapping;
1061
1062 if ((isA_SCNetworkInterface(interface) == NULL) ||
1063 (_SCNetworkInterfaceIsBuiltin(interface) == FALSE)) {
1064 return;
1065 }
1066
1067 // Check if services have mapping for the BSD name of the interface
1068 if (CFDictionaryContainsKey(serviceInterfaceMapping, bsdName) == FALSE) {
1069 CFArrayAppendValue(interfacesMissingServices, interface); // Adding interface since the corresponding service seems to be missing
1070 }
1071 }
1072
1073 static Boolean
1074 _SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref,
1075 SCPreferencesRef ni_pref)
1076 {
1077 SCNetworkConfigurationMissingServiceContext context;
1078 SCNetworkInterfaceRef interface = NULL;
1079 CFArrayRef interfaces = NULL;
1080 CFMutableArrayRef interfacesWithoutService = NULL;
1081 CFDictionaryRef mappingBSDNameToInterface = NULL;
1082 CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
1083 CFIndex missingServiceCount = 0;
1084 Boolean success = FALSE;
1085
1086 interfaces = __SCNetworkInterfaceCopyStoredWithPreferences(ni_pref);
1087 if (interfaces == NULL) {
1088 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: interfaces is NULL or not of the correct type"));
1089 goto done;
1090 }
1091
1092 mappingBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
1093 CFRelease(interfaces);
1094 if (isA_CFDictionary(mappingBSDNameToInterface) == NULL) {
1095 goto done;
1096 }
1097
1098 interfaces = __SCNetworkServiceCopyAllInterfaces(pref);
1099 if (interfaces == NULL) {
1100 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: interfaces is NULL for configPref or not of the correct type"));
1101 goto done;
1102 }
1103 mappingServiceBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
1104 CFRelease(interfaces);
1105 if (isA_CFDictionary(mappingServiceBSDNameToInterface) == NULL) {
1106 goto done;
1107 }
1108
1109 interfacesWithoutService = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1110
1111 context.interfaceMapping = mappingServiceBSDNameToInterface;
1112 context.interfacesMissingServices = interfacesWithoutService;
1113
1114 CFDictionaryApplyFunction(mappingBSDNameToInterface, _SCNetworkConfigurationCollectMissingService, &context);
1115 missingServiceCount = CFArrayGetCount(interfacesWithoutService);
1116
1117 success = TRUE;
1118
1119 for (CFIndex idx = 0; idx < missingServiceCount; idx++) {
1120 interface = CFArrayGetValueAtIndex(interfacesWithoutService, idx);
1121
1122 if (__SCNetworkServiceCreate(pref, interface, NULL) == FALSE) {
1123 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: Could not add service for interface: %@"), interface);
1124 success = FALSE;
1125 }
1126 }
1127 done:
1128 if (mappingBSDNameToInterface != NULL) {
1129 CFRelease(mappingBSDNameToInterface);
1130 }
1131 if (mappingServiceBSDNameToInterface != NULL) {
1132 CFRelease(mappingServiceBSDNameToInterface);
1133 }
1134 if (interfacesWithoutService != NULL) {
1135 CFRelease(interfacesWithoutService);
1136 }
1137
1138 return success;
1139 }
1140
1141 static void
1142 add_default_service(const void *value, void *context)
1143 {
1144 SCNetworkSetRef currentSet = NULL;
1145 SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
1146 SCPreferencesRef prefs = (SCPreferencesRef)context;
1147 SCNetworkServiceRef service;
1148
1149 service = SCNetworkServiceCreate(prefs, interface);
1150
1151 if (service == NULL) {
1152 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not create new service"));
1153 goto done;
1154 }
1155
1156 if (SCNetworkServiceEstablishDefaultConfiguration(service) == FALSE) {
1157 SCNetworkServiceRemove(service);
1158 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: SCNetworkServiceEstablishDefaultConfiguration failed"));
1159 goto done;
1160 }
1161
1162 // Add Service to current set
1163 currentSet = SCNetworkSetCopyCurrent(prefs);
1164 if (currentSet == NULL) {
1165 SCNetworkServiceRemove(service);
1166 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not find current set"));
1167 goto done;
1168 }
1169
1170 if (SCNetworkSetAddService(currentSet, service) == FALSE) {
1171 SCNetworkServiceRemove(service);
1172 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not add service to current set"));
1173 goto done;
1174 }
1175 done:
1176 if (service != NULL) {
1177 CFRelease(service);
1178 }
1179 if (currentSet != NULL) {
1180 CFRelease(currentSet);
1181 }
1182 }
1183
1184 static void
1185 remove_service(const void *value, void *context)
1186 {
1187 SCNetworkInterfaceRef interface;
1188 SCNetworkServiceRef service = (SCNetworkServiceRef)value;
1189 CFArrayRef toBeRemoved = (CFArrayRef)context;
1190
1191 interface = SCNetworkServiceGetInterface(service);
1192
1193 if (CFArrayContainsValue(toBeRemoved, CFRangeMake(0, CFArrayGetCount(toBeRemoved)), interface)) {
1194 SCNetworkServiceRemove(service);
1195 }
1196 }
1197
1198 static void
1199 _SCNetworkConfigurationSaveOldConfiguration(SCPreferencesRef prefs)
1200 {
1201 CFAbsoluteTime absoluteTime;
1202 CFCalendarRef currentCalendar;
1203 int day;
1204 int hour;
1205 CFStringRef keyList[] = {
1206 kSCPrefCurrentSet,
1207 MODEL,
1208 kSCPrefNetworkServices,
1209 kSCPrefSets,
1210 kSCPrefSystem,
1211 kSCPrefVirtualNetworkInterfaces
1212 };
1213 CFIndex keyListCount;
1214 int minute;
1215 int month;
1216 int second;
1217 int year;
1218
1219 currentCalendar = CFCalendarCopyCurrent();
1220 absoluteTime = CFAbsoluteTimeGetCurrent();
1221
1222 if (CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms",
1223 &year, &month, &day, &hour, &minute, &second) == FALSE) {
1224 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationSaveOldConfiguration: Cannot decompose absolute time"));
1225 }
1226 keyListCount = (CFIndex)sizeof(keyList)/sizeof(CFStringRef);
1227
1228 for (CFIndex idx = 0; idx < keyListCount; idx++) {
1229 CFStringRef newKey;
1230 CFTypeRef value = SCPreferencesGetValue(prefs, keyList[idx]);
1231
1232 if (value != NULL) {
1233 newKey = CFStringCreateWithFormat(NULL, NULL,
1234 CFSTR("%d-%d-%d %d:%d:%d : %@"),
1235 year, month, day, hour,
1236 minute, second, keyList[idx]);
1237 SCPreferencesSetValue(prefs, newKey, value);
1238 CFRelease(newKey);
1239 }
1240 }
1241 CFRelease(currentCalendar);
1242 }
1243
1244 static Boolean
1245 _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
1246 CFArrayRef interfaceToBeRemoved,
1247 CFArrayRef interfaceToBeReplaced)
1248 {
1249 CFIndex removeCount;
1250 CFIndex replaceCount;
1251 CFArrayRef serviceList;
1252
1253 removeCount = CFArrayGetCount(interfaceToBeRemoved);
1254 replaceCount = CFArrayGetCount(interfaceToBeReplaced);
1255 if (removeCount == 0 &&
1256 replaceCount == 0) {
1257 // We don't have any information to repair
1258 return FALSE;
1259 }
1260 // Backup current preferences before making changes
1261 _SCNetworkConfigurationSaveOldConfiguration(prefs);
1262
1263 serviceList = SCNetworkServiceCopyAll(prefs);
1264 CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), remove_service, (void*)interfaceToBeRemoved);
1265
1266 CFArrayApplyFunction(interfaceToBeReplaced, CFRangeMake(0, replaceCount), add_default_service, (void*)prefs);
1267 CFRelease(serviceList);
1268 return TRUE;
1269 }
1270
1271 static void
1272 validate_bridge(const void *value, void *context)
1273 {
1274 SCBridgeInterfaceRef bridge = (SCBridgeInterfaceRef) value;
1275 CFArrayRef memberInterfaces = SCBridgeInterfaceGetMemberInterfaces(bridge);
1276 CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1277 SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
1278
1279 for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
1280 CFStringRef bsdName;
1281 SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
1282 SCNetworkInterfaceRef memberInterface;
1283
1284 bsdName = SCNetworkInterfaceGetBSDName(interface);
1285 if (bsdName == NULL) {
1286 continue;
1287 }
1288
1289 // Check if member interface is present
1290 memberInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
1291 if (memberInterface != NULL) {
1292 CFArrayAppendValue(memberInterfacesMutable, memberInterface);
1293 CFRelease(memberInterface);
1294 }
1295 }
1296
1297 if (CFArrayGetCount(memberInterfacesMutable) == 0) {
1298 SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_bridge: Removing invalid bridge configuration: %@"), bridge);
1299 SCBridgeInterfaceRemove(bridge);
1300 }
1301 else {
1302 SCBridgeInterfaceSetMemberInterfaces(bridge, memberInterfacesMutable);
1303 }
1304 CFRelease(memberInterfacesMutable);
1305 }
1306 #if !TARGET_OS_IPHONE
1307 static void
1308 validate_bond(const void *value, void *context)
1309 {
1310 SCBondInterfaceRef bond = (SCBondInterfaceRef)value;
1311 CFArrayRef memberInterfaces = SCBondInterfaceGetMemberInterfaces(bond);
1312 CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1313 SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
1314
1315 for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
1316 CFStringRef bsdName;
1317 SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
1318 SCNetworkInterfaceRef memberInterface;
1319
1320 bsdName = SCNetworkInterfaceGetBSDName(interface);
1321 if (bsdName == NULL) {
1322 continue;
1323 }
1324
1325 // Check if member interface is present
1326 memberInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
1327 if (memberInterface != NULL) {
1328 CFArrayAppendValue(memberInterfacesMutable, memberInterface);
1329 CFRelease(memberInterface);
1330 }
1331 }
1332
1333 if (CFArrayGetCount(memberInterfacesMutable) == 0) {
1334 SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_bond: Removing invalid bond configuration: %@"), bond);
1335 SCBondInterfaceRemove(bond);
1336 }
1337 else {
1338 SCBondInterfaceSetMemberInterfaces(bond, memberInterfacesMutable);
1339 }
1340 CFRelease(memberInterfacesMutable);
1341 }
1342 #endif
1343
1344 static void
1345 validate_vlan(const void *value, void *context)
1346 {
1347 CFStringRef bsdName;
1348 SCNetworkInterfaceRef interface;
1349 Boolean isValid = TRUE;
1350 SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
1351 SCNetworkInterfaceRef physicalInterface;
1352 SCVLANInterfaceRef vlan = (SCVLANInterfaceRef)value;
1353
1354 physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlan);
1355 bsdName = SCNetworkInterfaceGetBSDName(physicalInterface);
1356
1357 if (bsdName == NULL) {
1358 isValid = FALSE;
1359 goto done;
1360 }
1361
1362 // Check if the physical interface is present
1363 interface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
1364 if (interface == NULL) {
1365 isValid = FALSE;
1366 goto done;
1367 }
1368 CFRelease(interface);
1369
1370 done:
1371 if (isValid == FALSE) {
1372 SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_vlan: Removing invalid VLAN configuration: %@"), vlan);
1373 SCVLANInterfaceRemove(vlan);
1374 }
1375 }
1376
1377 static Boolean
1378 _SCNetworkConfigurationCheckValidityUsingPreferences(SCPreferencesRef prefs,
1379 SCPreferencesRef ni_prefs,
1380 CFDictionaryRef options)
1381 {
1382 CFArrayRef allServices = NULL;
1383 CFArrayRef allSets = NULL;
1384 CFDictionaryRef bsdNameToBridgeServices = NULL;
1385 CFDictionaryRef bsdNameToBondServices = NULL;
1386 CFDictionaryRef bsdNameToVLANServices = NULL;
1387 SCNetworkConfigurationValidityContext context;
1388 CFArrayRef interfaces = NULL;
1389 Boolean isValid = TRUE;
1390 CFDictionaryRef mappingBSDNameToInterface = NULL;
1391 CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
1392 Boolean repairConfiguration = FALSE;
1393 CFArrayRef setServiceOrder = NULL;
1394 CFArrayRef setServices = NULL;
1395 CFMutableArrayRef interfaceToBeRemoved = NULL;
1396 CFMutableArrayRef interfaceToBeReplaced = NULL;
1397
1398
1399 if ((isA_CFDictionary(options) != NULL)) {
1400 CFBooleanRef repair = CFDictionaryGetValue(options, kSCNetworkConfigurationRepair);
1401 if (isA_CFBoolean(repair) != NULL) {
1402 repairConfiguration = CFBooleanGetValue(repair);
1403 }
1404 }
1405
1406 /*
1407 Check the validity by:
1408 1) Comparing if the interfaces names mentioned in NetworkInterfaces.plist and preferences.plist match
1409 Use the functions
1410 CFDictionaryRef
1411 __SCNetworkInterfaceCreateMappingUsingBSDName(SCPreferencesRef prefs);
1412 */
1413 interfaces = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
1414 if (isA_CFArray(interfaces) == NULL) {
1415 isValid = FALSE;
1416 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: interfaces is NULL or not of the correct type"));
1417 goto done;
1418 }
1419 mappingBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
1420 CFRelease(interfaces);
1421 if (isA_CFDictionary(mappingBSDNameToInterface) == NULL) {
1422 isValid = FALSE;
1423 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: mappingBSDNameToInterface is NULL"));
1424 goto done;
1425 }
1426
1427 interfaces = __SCNetworkServiceCopyAllInterfaces(prefs);
1428 if (isA_CFArray(interfaces) == NULL) {
1429 isValid = FALSE;
1430 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: interfaces is NULL for configPref or not of the correct type"));
1431 goto done;
1432 }
1433 mappingServiceBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
1434 CFRelease(interfaces);
1435 if (isA_CFDictionary(mappingServiceBSDNameToInterface) == NULL) {
1436 isValid = FALSE;
1437 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: mappingServiceBSDNameToInterface is NULL"));
1438 goto done;
1439 }
1440
1441 if (repairConfiguration) {
1442 interfaceToBeRemoved = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1443 interfaceToBeReplaced = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1444 #if !TARGET_OS_IPHONE
1445 bsdNameToBridgeServices = _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(prefs);
1446 bsdNameToBondServices = _SCNetworkMigrationCopyMappingBSDNameToBondServices(prefs);
1447 bsdNameToVLANServices = _SCNetworkMigrationCopyMappingBSDNameToVLANServices(prefs);
1448 #endif
1449 }
1450 context.interfaceMapping = mappingBSDNameToInterface;
1451 context.isValid = &isValid;
1452 context.interfaceToBeRemoved = interfaceToBeRemoved;
1453 context.interfaceToBeReplaced = interfaceToBeReplaced;
1454 context.bsdNameToBridgeServices = bsdNameToBridgeServices;
1455 context.bsdNameToBondServices = bsdNameToBondServices;
1456 context.bsdNameToVLANServices = bsdNameToVLANServices;
1457 context.repair = repairConfiguration;
1458
1459 CFDictionaryApplyFunction(mappingServiceBSDNameToInterface, _SCNetworkConfigurationValidateInterface, &context);
1460
1461 if (isValid == FALSE) {
1462 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: Found mismatch between interface names in NetworkInterfaces.plist and preferences.plist"));
1463 if (repairConfiguration) {
1464 isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, interfaceToBeRemoved, interfaceToBeReplaced);
1465 if (isValid == FALSE) {
1466 goto done;
1467 }
1468 // Save the changes if repair fixed an invalid configuration
1469 if (SCPreferencesCommitChanges(prefs) == FALSE) {
1470 SCLog(_sc_debug, LOG_NOTICE, CFSTR("Failed to commit changes from the repaired configuration"));
1471 }
1472 }
1473 else {
1474 goto done;
1475 }
1476 }
1477 /*
1478
1479 2) Check if all the network services mentioned in the SCNetworkSet are actually present in the SCNetworkService array
1480 */
1481
1482 allServices = SCNetworkServiceCopyAll(prefs);
1483 if (isA_CFArray(allServices) == NULL) {
1484 isValid = FALSE;
1485 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: allServices is NULL"));
1486 goto done;
1487 }
1488
1489 allSets = SCNetworkSetCopyAll(prefs);
1490 if (isA_CFArray(allSets) == NULL) {
1491 isValid = FALSE;
1492 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: allSets is NULL"));
1493 goto done;
1494 }
1495
1496 for (CFIndex idx = 0; ((idx < CFArrayGetCount(allSets)) && isValid); idx++) {
1497 SCNetworkSetRef set = CFArrayGetValueAtIndex(allSets, idx);
1498
1499 if (isA_SCNetworkSet(set) == NULL) {
1500 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: set is NULL"));
1501 continue;
1502 }
1503 setServices = SCNetworkSetCopyServices(set);
1504 if (setServices == NULL) {
1505 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: setServices is NULL"));
1506 continue;
1507 }
1508 for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServices); idx2++) {
1509 SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServices, idx2);
1510
1511 if (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE) {
1512 isValid = FALSE;
1513 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: All network services in the network set are not present in SCNetworkService array"));
1514 break;
1515 }
1516 }
1517 if (isValid == FALSE) {
1518 break;
1519 }
1520
1521 /*
1522 3) Check if service IDs in service order do exist in the SET
1523 */
1524 setServiceOrder = SCNetworkSetGetServiceOrder(set);
1525 if (setServiceOrder != NULL) {
1526 for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServiceOrder); idx2++) {
1527 SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServiceOrder, idx2);
1528 if ((CFArrayContainsValue(setServiceOrder, CFRangeMake(0, CFArrayGetCount(setServiceOrder)), service) == FALSE) &&
1529 (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE)) {
1530 SCLog(_sc_debug, LOG_NOTICE, CFSTR("Service: %@ is not present in the service order for set %@"), service, set);
1531 break;
1532 }
1533 }
1534 }
1535 if (setServices != NULL) {
1536 CFRelease(setServices);
1537 setServices = NULL;
1538 }
1539 }
1540
1541 /*
1542 4) Check if the virtual network interfaces have valid member interfaces
1543 */
1544 CFArrayRef bridges = SCBridgeInterfaceCopyAll(prefs);
1545 if (bridges != NULL) {
1546 CFArrayApplyFunction(bridges, CFRangeMake(0, CFArrayGetCount(bridges)), validate_bridge, (void*)ni_prefs);
1547 CFRelease(bridges);
1548 }
1549 #if !TARGET_OS_IPHONE
1550 CFArrayRef bonds = SCBondInterfaceCopyAll(prefs);
1551 if (bonds != NULL) {
1552 CFArrayApplyFunction(bonds, CFRangeMake(0, CFArrayGetCount(bonds)), validate_bond, (void*)ni_prefs);
1553 CFRelease(bonds);
1554 }
1555 #endif
1556 CFArrayRef vlans = SCVLANInterfaceCopyAll(prefs);
1557 if (vlans != NULL) {
1558 CFArrayApplyFunction(vlans, CFRangeMake(0, CFArrayGetCount(vlans)), validate_vlan, (void*)ni_prefs);
1559 CFRelease(vlans);
1560 }
1561
1562
1563 done:
1564 if (mappingBSDNameToInterface != NULL) {
1565 CFRelease(mappingBSDNameToInterface);
1566 }
1567 if (mappingServiceBSDNameToInterface != NULL) {
1568 CFRelease(mappingServiceBSDNameToInterface);
1569 }
1570 if (allServices != NULL) {
1571 CFRelease(allServices);
1572 }
1573 if (allSets != NULL) {
1574 CFRelease(allSets);
1575 }
1576 if (bsdNameToBridgeServices != NULL) {
1577 CFRelease(bsdNameToBridgeServices);
1578 }
1579 if (bsdNameToBondServices != NULL) {
1580 CFRelease(bsdNameToBondServices);
1581 }
1582 if (bsdNameToVLANServices != NULL) {
1583 CFRelease(bsdNameToVLANServices);
1584 }
1585 if (setServices != NULL) {
1586 CFRelease(setServices);
1587 }
1588 if (interfaceToBeRemoved != NULL) {
1589 CFRelease(interfaceToBeRemoved);
1590 }
1591 if (interfaceToBeReplaced != NULL) {
1592 CFRelease(interfaceToBeReplaced);
1593 }
1594 return isValid;
1595 }
1596
1597 Boolean
1598 _SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options)
1599 {
1600 CFURLRef baseURL = NULL;
1601 CFURLRef configNetworkInterfaceFile = NULL;
1602 CFStringRef configNetworkInterfaceFileString = NULL;
1603 SCPreferencesRef configNetworkInterfacePref = NULL;
1604 SCPreferencesRef configPref = NULL;
1605 CFURLRef configPreferenceFile = NULL;
1606 CFStringRef configPreferencesFileString = NULL;
1607 CFArrayRef configurationFiles = NULL;
1608 Boolean isValid = FALSE;
1609 char networkInterfaceStr[PATH_MAX];
1610 char prefsStr[PATH_MAX];
1611
1612 if (configDir == NULL) {
1613 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Migration files not found in directory: %@"), ((configDir == NULL) ? CFSTR("NULL") : CFURLGetString(configDir)));
1614 goto done;
1615 }
1616 baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE,
1617 kCFURLPOSIXPathStyle, TRUE, configDir);
1618
1619 configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseURL);
1620 configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseURL);
1621
1622 if (CFURLGetFileSystemRepresentation(configPreferenceFile, TRUE, (UInt8*)prefsStr, sizeof(prefsStr)) == FALSE) {
1623 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Could not extract preferences information"));
1624 goto done;
1625 }
1626 if (CFURLGetFileSystemRepresentation(configNetworkInterfaceFile, TRUE, (UInt8*)networkInterfaceStr, sizeof(networkInterfaceStr)) == FALSE) {
1627 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Could not extract network interface information"));
1628 goto done;
1629 }
1630
1631 configPreferencesFileString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsStr);
1632 configNetworkInterfaceFileString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceStr);
1633
1634 configPref = SCPreferencesCreate(NULL,
1635 PLUGIN_ID,
1636 configPreferencesFileString);
1637
1638 configNetworkInterfacePref = SCPreferencesCreate(NULL,
1639 PLUGIN_ID,
1640 configNetworkInterfaceFileString);
1641 if ((configPref == NULL) || (configNetworkInterfacePref == NULL)) {
1642 goto done;
1643 }
1644
1645 // This function compares preferences.plist and NetworkInterfaces.plist and verifies if the values are correct
1646 // Checking interface mismatch for validity
1647 isValid = _SCNetworkConfigurationCheckValidityUsingPreferences(configPref, configNetworkInterfacePref, options);
1648
1649 done:
1650 if (baseURL != NULL) {
1651 CFRelease(baseURL);
1652 }
1653 if (configurationFiles != NULL) {
1654 CFRelease(configurationFiles);
1655 }
1656 if (configPreferencesFileString != NULL) {
1657 CFRelease(configPreferencesFileString);
1658 }
1659 if (configNetworkInterfaceFileString != NULL) {
1660 CFRelease(configNetworkInterfaceFileString);
1661 }
1662 if (configPref != NULL) {
1663 CFRelease(configPref);
1664 }
1665 if (configNetworkInterfacePref != NULL) {
1666 CFRelease(configNetworkInterfacePref);
1667 }
1668 if (configPreferenceFile != NULL) {
1669 CFRelease(configPreferenceFile);
1670 }
1671 if (configNetworkInterfaceFile != NULL) {
1672 CFRelease(configNetworkInterfaceFile);
1673 }
1674 return isValid;
1675 }
1676
1677
1678 typedef struct {
1679 CFMutableArrayRef externalInterfaceList;
1680 CFMutableArrayRef networkInterfaceList;
1681 } SCExternalMappingContext;
1682
1683 static void
1684 _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void *value, void *context)
1685 {
1686 SCExternalMappingContext* ctx = context;
1687 CFDictionaryRef interface_entity = NULL;
1688 SCNetworkInterfaceRef targetInterface = (SCNetworkInterfaceRef)value;
1689
1690 if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface) == TRUE) {
1691 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCollectInterfaceStorageEntity: Target Interface %@ already exists, thus do no add it to NetworkInterfaces.plist"), targetInterface);
1692 return; // If the target interface already exists then do not add it to NetworkInterfaces.plist
1693 }
1694 interface_entity = __SCNetworkInterfaceCopyStorageEntity(targetInterface);
1695
1696 if (interface_entity != NULL) {
1697 CFArrayAppendValue(ctx->networkInterfaceList, interface_entity);
1698 CFRelease(interface_entity);
1699 }
1700 }
1701
1702 static CFArrayRef // CFDictionaryRef
1703 _SCNetworkMigrationCreateNetworkInterfaceArray(SCPreferencesRef ni_prefs, CFDictionaryRef externalMapping)
1704 {
1705 SCExternalMappingContext context;
1706 CFIndex count = 0;
1707 CFMutableArrayRef externalInterfaceList = NULL;
1708 CFArrayRef if_list = NULL;
1709 CFDictionaryRef interface_entity = NULL;
1710 CFMutableArrayRef networkInterfaceList = NULL;
1711
1712 if (ni_prefs == NULL) {
1713 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: ni_prefs are NULL"));
1714 return NULL;
1715 }
1716
1717 if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
1718
1719 if ((isA_CFArray(if_list) == NULL) ||
1720 ((count = CFArrayGetCount(if_list)) == 0)) {
1721 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: if_list is NULL or interface count is 0"));
1722 return NULL;
1723 }
1724
1725 networkInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1726
1727 // Keep the same builtin and external interfaces
1728 for (CFIndex idx = 0; idx < count; idx++) {
1729 interface_entity = CFArrayGetValueAtIndex(if_list, idx);
1730 if (isA_CFDictionary(interface_entity) == NULL) {
1731 continue;
1732 }
1733 CFArrayAppendValue(networkInterfaceList, interface_entity);
1734 }
1735
1736 if (isA_CFDictionary(externalMapping) == NULL) {
1737 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: externalMapping is NULL or not of the correct type"));
1738 goto done;
1739 }
1740 // Add any new external interfaces found
1741 externalInterfaceList = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(ni_prefs, FALSE);
1742 context.externalInterfaceList = externalInterfaceList;
1743 context.networkInterfaceList = networkInterfaceList;
1744
1745 CFDictionaryApplyFunction(externalMapping, _SCNetworkConfigurationCollectInterfaceStorageEntity, &context);
1746
1747 done:
1748 if (externalInterfaceList != NULL) {
1749 CFRelease(externalInterfaceList);
1750 }
1751 return networkInterfaceList;
1752 }
1753
1754 static void
1755 SCNetworkMigrationMapSourceToTargetName(const void *key, const void *value, void *context)
1756 {
1757 SCNetworkInterfaceRef interfaceKey = (SCNetworkInterfaceRef)key;
1758 SCNetworkInterfaceRef interfaceValue = (SCNetworkInterfaceRef)value;
1759 CFMutableDictionaryRef mapping = (CFMutableDictionaryRef)context;
1760 CFStringRef sourceBSDName = NULL;
1761 CFStringRef targetBSDName = NULL;
1762
1763 sourceBSDName = SCNetworkInterfaceGetBSDName(interfaceKey);
1764 if (isA_CFString(sourceBSDName) == NULL) {
1765 return;
1766 }
1767
1768 targetBSDName = SCNetworkInterfaceGetBSDName(interfaceValue);
1769 if (isA_CFString(targetBSDName) == NULL) {
1770 return;
1771 }
1772
1773 if (CFDictionaryContainsKey(mapping, sourceBSDName) == FALSE) {
1774 CFDictionaryAddValue(mapping, sourceBSDName, targetBSDName);
1775 }
1776 return;
1777 }
1778
1779 static CFDictionaryRef
1780 _SCNetworkMigrationCreateBSDNameMapping(CFDictionaryRef internalMapping, CFDictionaryRef externalMapping)
1781 {
1782 CFMutableDictionaryRef bsdNameMapping = CFDictionaryCreateMutable(NULL, 0,
1783 &kCFTypeDictionaryKeyCallBacks,
1784 &kCFTypeDictionaryValueCallBacks);
1785
1786 if ((internalMapping == NULL) && externalMapping == NULL) {
1787 goto done;
1788 }
1789
1790 if (internalMapping != NULL) {
1791 CFDictionaryApplyFunction(internalMapping, SCNetworkMigrationMapSourceToTargetName, bsdNameMapping);
1792 }
1793
1794 if (externalMapping != NULL) {
1795 CFDictionaryApplyFunction(externalMapping, SCNetworkMigrationMapSourceToTargetName, bsdNameMapping);
1796 }
1797
1798 done:
1799 return bsdNameMapping;
1800 }
1801
1802 typedef struct {
1803 CFMutableArrayRef mutableServiceArray;
1804 SCPreferencesRef prefs;
1805 } SCNetworkServiceArrayCopyContext;
1806
1807 static CFDictionaryRef
1808 _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs)
1809 {
1810 CFMutableDictionaryRef serviceSetMapping = CFDictionaryCreateMutable(NULL, 0,
1811 &kCFTypeDictionaryKeyCallBacks,
1812 &kCFTypeDictionaryValueCallBacks);
1813 SCNetworkServiceRef service = NULL;
1814 CFArrayRef services = NULL;
1815 CFMutableArrayRef setList = NULL;
1816 CFArrayRef sets = NULL;
1817
1818 services = SCNetworkServiceCopyAll(prefs);
1819 if (services == NULL) {
1820 goto done;
1821 }
1822 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
1823 service = CFArrayGetValueAtIndex(services, idx);
1824
1825 if (CFDictionaryContainsKey(serviceSetMapping, service) == FALSE) {
1826 setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1827 CFDictionaryAddValue(serviceSetMapping, service, setList);
1828 CFRelease(setList);
1829 }
1830 }
1831 CFRelease(services);
1832
1833 sets = SCNetworkSetCopyAll(prefs);
1834 if (sets == NULL) {
1835 goto done;
1836 }
1837
1838 for (CFIndex idx = 0; idx < CFArrayGetCount(sets); idx++) {
1839 SCNetworkSetRef set = CFArrayGetValueAtIndex(sets, idx);
1840 services = SCNetworkSetCopyServices(set);
1841
1842 for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(services); idx2++) {
1843 service = CFArrayGetValueAtIndex(services, idx2);
1844 setList = (CFMutableArrayRef)CFDictionaryGetValue(serviceSetMapping, service);
1845 if (setList != NULL) {
1846 CFArrayAppendValue(setList, set);
1847 }
1848 }
1849 CFRelease(services);
1850 }
1851
1852 done:
1853 if (sets != NULL) {
1854 CFRelease(sets);
1855 }
1856 return serviceSetMapping;
1857 }
1858
1859 static CFDictionaryRef
1860 _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs,
1861 SCPreferencesRef targetPrefs)
1862 {
1863 SCNetworkSetRef currentSourceSet = NULL;
1864 CFMutableDictionaryRef setMapping = NULL;
1865 CFStringRef setName;
1866 CFArrayRef sourceSets = NULL;
1867 CFArrayRef targetSets = NULL;
1868 CFMutableArrayRef targetSetsMutable = NULL;
1869
1870 sourceSets = SCNetworkSetCopyAll(sourcePrefs);
1871 targetSets = SCNetworkSetCopyAll(targetPrefs);
1872
1873 if (sourceSets == NULL ||
1874 targetSets == NULL) {
1875 goto done;
1876 }
1877 targetSetsMutable = CFArrayCreateMutableCopy(NULL, 0, targetSets);
1878
1879 setMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1880
1881 currentSourceSet = SCNetworkSetCopyCurrent(sourcePrefs);
1882
1883 for (CFIndex idx = 0; idx < CFArrayGetCount(sourceSets); idx++) {
1884 SCNetworkSetRef sourceSet = CFArrayGetValueAtIndex(sourceSets, idx);
1885 CFIndex targetCount = CFArrayGetCount(targetSetsMutable);
1886 SCNetworkSetRef targetSet;
1887
1888 setName = SCNetworkSetGetName(sourceSet);
1889 if (targetCount > 0) {
1890 targetSet = CFArrayGetValueAtIndex(targetSetsMutable, 0);
1891 CFRetain(targetSet);
1892 CFArrayRemoveValueAtIndex(targetSetsMutable, 0);
1893 }
1894 else {
1895 targetSet = SCNetworkSetCreate(targetPrefs);
1896 }
1897
1898 SCNetworkSetSetName(targetSet, setName);
1899 CFDictionaryAddValue(setMapping, sourceSet, targetSet);
1900
1901 if (CFEqual(sourceSet, currentSourceSet) == TRUE) {
1902 SCNetworkSetSetCurrent(targetSet);
1903 }
1904 CFRelease(targetSet);
1905 }
1906
1907 done:
1908 if (sourceSets != NULL) {
1909 CFRelease(sourceSets);
1910 }
1911 if (targetSets != NULL) {
1912 CFRelease(targetSets);
1913 }
1914 if (targetSetsMutable != NULL) {
1915 CFRelease(targetSetsMutable);
1916 }
1917 if (currentSourceSet != NULL) {
1918 CFRelease(currentSourceSet);
1919 }
1920 return setMapping;
1921 }
1922
1923 // This function finds the mapping between source and target preferences (SCNetworkServicesRef -> SCNetworkServicesRef)
1924 // If there is no mapping found between source and target preferences, then the CFBooleanRef value indicating no value is found is stored (SCNetworkServicesRef -> kCFBooleanFalse)
1925 static CFDictionaryRef
1926 _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePrefs,
1927 SCPreferencesRef targetPrefs,
1928 CFDictionaryRef bsdNameMapping)
1929 {
1930 CFStringRef bsdNameMapTarget = NULL;
1931 CFMutableDictionaryRef serviceMapping = NULL; // Mapping of services between source and target configurations
1932 CFStringRef sourceBSDName = NULL;
1933 CFIndex sourceCount = 0;
1934 SCNetworkInterfaceRef sourceInterface = NULL;
1935 CFStringRef sourceInterfaceSubType = NULL; // Check interface type and subtype to be able to transfer VPN
1936 CFStringRef sourceInterfaceType = NULL;
1937 CFArrayRef sourceSCNetworkServices = NULL;
1938 CFMutableArrayRef sourceSCNetworkServicesMutable = NULL; // Source SCNetworkServiceRef mutable array
1939 SCNetworkServiceRef sourceService = NULL;
1940 CFStringRef targetBSDName = NULL;
1941 CFIndex targetCount = 0; // Count of Source and Target Services
1942 SCNetworkInterfaceRef targetInterface = NULL;
1943 CFStringRef targetInterfaceSubType = NULL; // services during migration
1944 CFStringRef targetInterfaceType = NULL;
1945 CFArrayRef targetSCNetworkServices = NULL;
1946 CFMutableArrayRef targetSCNetworkServicesMutable = NULL; // Target SCNetworkServiceRef mutable array
1947 SCNetworkServiceRef targetService = NULL;
1948
1949 // We need BSD Mapping to successfully create service mapping
1950 if (bsdNameMapping == NULL) {
1951 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: BSD Name Mapping is NULL"));
1952 goto done;
1953 }
1954 sourceSCNetworkServices = SCNetworkServiceCopyAll(sourcePrefs);
1955 if (isA_CFArray(sourceSCNetworkServices) == NULL) {
1956 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceSCNetworkServices is NULL or not of the correct CFType"));
1957 goto done;
1958 }
1959 targetSCNetworkServices = SCNetworkServiceCopyAll(targetPrefs);
1960 if (isA_CFArray(targetSCNetworkServices) == NULL) {
1961 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetSCNetworkServices is NULL or not of the correct CFType"));
1962 goto done;
1963 }
1964
1965 sourceCount = CFArrayGetCount(sourceSCNetworkServices);
1966
1967 sourceSCNetworkServicesMutable = CFArrayCreateMutableCopy(NULL, 0, sourceSCNetworkServices);
1968 targetSCNetworkServicesMutable = CFArrayCreateMutableCopy(NULL, 0, targetSCNetworkServices);
1969
1970 serviceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1971
1972 for (CFIndex idx = 0; idx < sourceCount; idx++) {
1973 sourceBSDName = NULL;
1974 sourceService = NULL;
1975 sourceInterface = NULL;
1976 sourceInterfaceType = NULL;
1977 sourceInterfaceSubType = NULL;
1978 bsdNameMapTarget = NULL;
1979
1980 targetCount = CFArrayGetCount(targetSCNetworkServicesMutable);
1981 sourceService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(sourceSCNetworkServicesMutable, idx);
1982
1983 sourceInterface = SCNetworkServiceGetInterface(sourceService);
1984
1985 if (sourceInterface == NULL) {
1986 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceInterface is NULL or not of the correct type"));
1987 continue;
1988 }
1989
1990 sourceInterfaceType = __SCNetworkInterfaceGetEntityType(sourceInterface);
1991 if ((isA_CFString(sourceInterfaceType) != NULL) &&
1992 ((CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeVPN) == TRUE) ||
1993 (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypePPP) == TRUE))) {
1994 sourceInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(sourceInterface);
1995 if (isA_CFString(sourceInterfaceSubType) == NULL) {
1996 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceInterfaceSubType is NULL or not of the correct type"));
1997 continue;
1998 }
1999 }
2000 else if (((isA_CFString(sourceInterfaceType) != NULL) &&
2001 (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeIPSec) == FALSE) &&
2002 (CFEqual(sourceInterfaceType, kSCValNetInterfaceType6to4) == FALSE) &&
2003 (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeLoopback) == FALSE)) ||
2004 (isA_CFString(sourceInterfaceType) == NULL)) {
2005 sourceBSDName = SCNetworkInterfaceGetBSDName(sourceInterface);
2006 if ((isA_CFString(sourceBSDName) == NULL) ||
2007 (CFDictionaryContainsKey(bsdNameMapping, sourceBSDName)) == FALSE) {
2008 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: bsdNameMapping doesn't contain sourceBSDName: %@"), (sourceBSDName == NULL) ? CFSTR("NULL") : sourceBSDName);
2009 continue;
2010 }
2011
2012 bsdNameMapTarget = CFDictionaryGetValue(bsdNameMapping, sourceBSDName);
2013 if (isA_CFString(bsdNameMapTarget) == NULL) {
2014 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: bsdNameMapTarget is NULL or not of the correct CFType"));
2015 continue;
2016 }
2017 }
2018 // Find the bsd name in target service
2019 for (CFIndex idx2 = 0; idx2 < targetCount; idx2++) {
2020 targetService = NULL;
2021 targetInterface = NULL;
2022 targetBSDName = NULL;
2023 targetInterfaceType = NULL;
2024 targetInterfaceSubType = NULL;
2025
2026 targetService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(targetSCNetworkServicesMutable, idx2);
2027
2028 targetInterface = SCNetworkServiceGetInterface(targetService);
2029 if (targetInterface == NULL) {
2030 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterface is NULL or not of the correct type"));
2031 continue;
2032 }
2033 SCLog(_sc_debug, LOG_NOTICE, CFSTR("targetInterface: %@"), targetInterface);
2034 if (sourceBSDName != NULL) {
2035 targetBSDName = SCNetworkInterfaceGetBSDName(targetInterface);
2036 if (isA_CFString(targetBSDName) == NULL) {
2037 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetBSDName is NULL or not of the correct type"));
2038 continue;
2039 }
2040
2041 if (CFEqual(targetBSDName, bsdNameMapTarget) == TRUE) {
2042 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Removing target BSD Name: %@"), targetBSDName);
2043 CFDictionaryAddValue(serviceMapping, sourceService, targetService);
2044 CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
2045 break;
2046 }
2047 }
2048 else {
2049 // Source Interface Type should be VPN
2050 targetInterfaceType = __SCNetworkInterfaceGetEntityType(targetInterface);
2051 if ((isA_CFString(targetInterfaceType) == NULL) ||
2052 ((CFEqual(targetInterfaceType, kSCValNetInterfaceTypeVPN) == FALSE) &&
2053 (CFEqual(targetInterfaceType, kSCValNetInterfaceTypePPP) == FALSE))) {
2054 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterfaceType is NULL or not of the correct type : %@"), (targetInterfaceType != NULL) ? targetInterfaceType : CFSTR("NULL"));
2055 continue;
2056 }
2057 targetInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(targetInterface);
2058 if (isA_CFString(targetInterfaceSubType) == NULL) {
2059 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterfaceSubType is NULL or not of the correct type: %@"), (targetInterfaceSubType != NULL) ? targetInterfaceSubType : CFSTR("NULL"));
2060 continue;
2061 }
2062
2063 // Check if the target interface type and the target interface sub type match
2064 if ((CFEqual(targetInterfaceType, sourceInterfaceType) == TRUE) &&
2065 (CFEqual(targetInterfaceSubType, sourceInterfaceSubType) == TRUE)) {
2066 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Removing target BSD Name: %@ for VPN"), targetBSDName);
2067 CFDictionaryAddValue(serviceMapping, sourceService, targetService);
2068 CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
2069 break;
2070 }
2071 }
2072 }
2073 // Check if sourceService has found a mapping or not, if not the create a NULL mapping to indicate
2074 // the this service needs to be added and not replaced
2075 if (CFDictionaryContainsKey(serviceMapping, sourceService) == FALSE) {
2076 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Service needs to be added: %@"), sourceService);
2077 CFDictionaryAddValue(serviceMapping, sourceService, kCFBooleanFalse);
2078 }
2079 }
2080 done:
2081 if (sourceSCNetworkServices != NULL) {
2082 CFRelease(sourceSCNetworkServices);
2083 }
2084 if (targetSCNetworkServices != NULL) {
2085 CFRelease(targetSCNetworkServices);
2086 }
2087 if (sourceSCNetworkServicesMutable != NULL) {
2088 CFRelease(sourceSCNetworkServicesMutable);
2089 }
2090 if (targetSCNetworkServicesMutable != NULL) {
2091 CFRelease(targetSCNetworkServicesMutable);
2092 }
2093 return serviceMapping;
2094 }
2095
2096 typedef struct {
2097 SCPreferencesRef targetPrefs;
2098 CFDictionaryRef bsdMapping;
2099 CFDictionaryRef setMapping;
2100 CFDictionaryRef serviceSetMapping;
2101 } ServiceMigrationContext;
2102
2103 // value can be:
2104 // SCNetworkServiceRef: if target service needs replacement
2105 // CFBooleanRef: if target service is not present
2106 static void
2107 ServiceMigrationAddOrReplace(const void *key, const void *value, void *context)
2108 {
2109 CFDictionaryRef bsdMapping = NULL;
2110 ServiceMigrationContext *ctx = (ServiceMigrationContext*)context;
2111 CFDictionaryRef setMapping;
2112 CFDictionaryRef sourceServiceSetMapping;
2113 SCNetworkServiceRef sourceService = (SCNetworkServiceRef)key;
2114 SCPreferencesRef targetPrefs = NULL;
2115 SCNetworkServiceRef targetService = (SCNetworkServiceRef)value;
2116
2117 targetPrefs = ctx->targetPrefs;
2118 bsdMapping = ctx->bsdMapping;
2119 setMapping = ctx->setMapping;
2120 sourceServiceSetMapping = ctx->serviceSetMapping;
2121
2122 if (isA_SCNetworkService(targetService) != NULL) {
2123 SCLog(_sc_debug, LOG_NOTICE, CFSTR("ServiceMigrationAddOrReplace: Removing target service: %@"), targetService);
2124 SCNetworkServiceRemove(targetService);
2125 }
2126 SCLog(_sc_debug, LOG_NOTICE, CFSTR("ServiceMigrationAddOrReplace: Adding service with %@"), sourceService);
2127 if (__SCNetworkServiceMigrateNew(targetPrefs, sourceService, bsdMapping, setMapping, sourceServiceSetMapping) == FALSE) {
2128 SCLog(_sc_debug, LOG_NOTICE, CFSTR("Could not Add Service: %@"), sourceService);
2129 }
2130 }
2131
2132 static Boolean
2133 _SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs,
2134 CFDictionaryRef serviceMapping, CFDictionaryRef bsdMapping,
2135 CFDictionaryRef setMapping, CFDictionaryRef serviceSetMapping)
2136 {
2137 ServiceMigrationContext context;
2138 Boolean success = FALSE;
2139
2140 if ((sourcePrefs == NULL) ||
2141 (targetPrefs == NULL) ||
2142 (isA_CFDictionary(serviceMapping) == NULL) ||
2143 (isA_CFDictionary(bsdMapping) == NULL)) {
2144 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoServiceMigration: targetPrefs or serviceMapping or bsdMapping is NULL"));
2145 goto done;
2146 }
2147 context.targetPrefs = targetPrefs;
2148 context.bsdMapping = bsdMapping;
2149 context.setMapping = setMapping;
2150 context.serviceSetMapping = serviceSetMapping;
2151
2152 CFDictionaryApplyFunction(serviceMapping, ServiceMigrationAddOrReplace, &context);
2153
2154 success = TRUE;
2155 done:
2156 return success;
2157 }
2158
2159 static Boolean
2160 _SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
2161 {
2162 CFStringEncoding nameEncoding;
2163 CFStringRef computerName;
2164 CFStringRef hostname;
2165 CFStringRef localHostname;
2166 CFDictionaryRef btmm = NULL;
2167 CFDictionaryRef btmmDSID = NULL;
2168 CFStringRef btmmDSIDPath;
2169 CFStringRef btmmPath;
2170
2171
2172 if ((sourcePrefs == NULL) ||
2173 (targetPrefs == NULL)) {
2174 return FALSE;
2175 }
2176
2177 hostname = SCPreferencesGetHostName(sourcePrefs);
2178 if (hostname != NULL) {
2179 SCPreferencesSetHostName(targetPrefs, hostname);
2180 }
2181
2182 localHostname = _SCPreferencesCopyLocalHostName(sourcePrefs);
2183 if (localHostname != NULL) {
2184 SCPreferencesSetLocalHostName(targetPrefs, localHostname);
2185 CFRelease(localHostname);
2186 }
2187
2188 computerName = _SCPreferencesCopyComputerName(sourcePrefs, &nameEncoding);
2189
2190 if (computerName != NULL) {
2191 SCPreferencesSetComputerName(targetPrefs, computerName, nameEncoding);
2192 CFRelease(computerName);
2193 }
2194
2195 btmmPath = CFStringCreateWithFormat(NULL, NULL,
2196 CFSTR("/%@/%@/%@"),
2197 kSCPrefSystem,
2198 kSCCompNetwork,
2199 BACK_TO_MY_MAC);
2200 btmm = SCPreferencesPathGetValue(sourcePrefs, btmmPath);
2201
2202 if (btmm != NULL) {
2203 SCPreferencesPathSetValue(targetPrefs, btmmPath, btmm);
2204 }
2205 CFRelease(btmmPath);
2206
2207 btmmDSIDPath = CFStringCreateWithFormat(NULL, NULL,
2208 CFSTR("/%@/%@/%@"),
2209 kSCPrefSystem,
2210 kSCCompNetwork,
2211 BACK_TO_MY_MAC_DSIDS);
2212
2213 btmmDSID = SCPreferencesPathGetValue(sourcePrefs, btmmDSIDPath);
2214 if (btmmDSID != NULL) {
2215 SCPreferencesPathSetValue(targetPrefs, btmmDSIDPath, btmmDSID);
2216 }
2217 CFRelease(btmmDSIDPath);
2218
2219 return TRUE;
2220 }
2221 #if !TARGET_OS_IPHONE
2222
2223 typedef struct {
2224 CFMutableArrayRef interfaceList;
2225 SCPreferencesRef ni_prefs;
2226 CFDictionaryRef bsdMapping;
2227 } SCVirtualInterfaceMemberListContext;
2228
2229 typedef struct {
2230 SCPreferencesRef prefs;
2231 SCPreferencesRef ni_prefs;
2232 CFDictionaryRef bsdMapping;
2233 CFDictionaryRef virtualBSDMapping;
2234 CFDictionaryRef mappingBSDNameToService;
2235 CFDictionaryRef setMapping;
2236 CFDictionaryRef serviceSetMapping;
2237 } SCVirtualInterfaceContext;
2238
2239 static void
2240 add_virtual_interface(const void *value, void *context)
2241 {
2242 SCVirtualInterfaceMemberListContext *ctx = (SCVirtualInterfaceMemberListContext*)context;
2243 CFMutableArrayRef interfaceList = ctx->interfaceList;
2244 CFDictionaryRef bsdMapping = ctx->bsdMapping;
2245 CFStringRef oldInterfaceBSDName = (CFStringRef)value;
2246 SCNetworkInterfaceRef newInterface;
2247 CFStringRef newInterfaceBSDName;
2248
2249 SCLog(_sc_debug, LOG_NOTICE, CFSTR("old interface BSD name is %@"), oldInterfaceBSDName);
2250 newInterfaceBSDName = CFDictionaryGetValue(bsdMapping, oldInterfaceBSDName);
2251 if (newInterfaceBSDName == NULL) {
2252 return;
2253 }
2254
2255 SCLog(_sc_debug, LOG_NOTICE, CFSTR("new interface BSD name is %@"), newInterfaceBSDName);
2256 newInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ctx->ni_prefs, newInterfaceBSDName);
2257
2258 if (newInterface != NULL) {
2259 SCLog(_sc_debug, LOG_NOTICE, CFSTR("Adding interface to interfaceList: %@"), newInterface);
2260 CFArrayAppendValue(interfaceList, newInterface);
2261 CFRelease(newInterface);
2262 }
2263 return;
2264 }
2265
2266 static void
2267 add_target_bridge(const void *key, const void *value, void *context)
2268 {
2269 CFStringRef bridgeName;
2270 CFDictionaryRef bridgeOptions;
2271 SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
2272 CFDictionaryRef bridgeBSDNameMapping = ctx->virtualBSDMapping;
2273 CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
2274 SCVirtualInterfaceMemberListContext memberListContext;
2275 CFMutableArrayRef newInterfaceList;
2276 SCBridgeInterfaceRef newBridge;
2277 SCBridgeInterfaceRef oldBridge = (SCBridgeInterfaceRef)key;
2278 CFStringRef oldBSDName;
2279 CFArrayRef oldInterfaceList = (CFArrayRef)value;
2280 CFArrayRef oldServiceList;
2281 SCPreferencesRef prefs = ctx->prefs;
2282 CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
2283 CFDictionaryRef setMapping = ctx->setMapping;
2284
2285 newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2286
2287 memberListContext.bsdMapping = ctx->bsdMapping;
2288 memberListContext.interfaceList = newInterfaceList;
2289 memberListContext.ni_prefs = ctx->ni_prefs;
2290
2291 CFArrayApplyFunction(oldInterfaceList, CFRangeMake(0, CFArrayGetCount(oldInterfaceList)), add_virtual_interface, &memberListContext);
2292
2293 newBridge = SCBridgeInterfaceCreate(prefs);
2294
2295 if (__SCBridgeInterfaceSetMemberInterfaces(newBridge, newInterfaceList) == FALSE) {
2296 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bridge: Adding Member Interfaces failed"));
2297 }
2298 CFRelease(newInterfaceList);
2299
2300 bridgeOptions = SCBridgeInterfaceGetOptions(oldBridge);
2301 if (bridgeOptions != NULL) {
2302 SCBridgeInterfaceSetOptions(newBridge, bridgeOptions);
2303 }
2304
2305 bridgeName = SCNetworkInterfaceGetLocalizedDisplayName(oldBridge);
2306
2307 if (bridgeName != NULL) {
2308 SCBridgeInterfaceSetLocalizedDisplayName(newBridge, bridgeName);
2309 }
2310
2311 oldBSDName = SCNetworkInterfaceGetBSDName(oldBridge);
2312 if (oldBSDName == NULL) {
2313 goto done;
2314 }
2315
2316 oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
2317 if (oldServiceList == NULL) {
2318 goto done;
2319 }
2320
2321 for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
2322 SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
2323 if (__SCNetworkServiceMigrateNew(prefs, oldService, bridgeBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
2324 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bridge: Could not migrate service: %@"), oldService);
2325 }
2326 }
2327 done:
2328 CFRelease(newBridge);
2329 }
2330
2331 static void
2332 _SCNetworkMigrationRemoveBridgeServices(SCPreferencesRef prefs)
2333 {
2334 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2335
2336 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2337 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2338 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2339 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2340
2341 if ((bsdName != NULL) &&
2342 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBridge) {
2343 SCLog(TRUE, LOG_NOTICE, CFSTR("_SCNetworkMigrationRemoveBridgeServices: Removing services: %@"), service);
2344 SCNetworkServiceRemove(service);
2345 }
2346 }
2347 CFRelease(services);
2348 }
2349
2350
2351 static CFDictionaryRef
2352 _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs)
2353 {
2354 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2355 CFMutableDictionaryRef bridgeServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2356
2357 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2358 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2359 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2360 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2361
2362 if ((bsdName != NULL) &&
2363 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBridge) {
2364 CFMutableArrayRef serviceList;
2365 if (CFDictionaryContainsKey(bridgeServices, bsdName) == FALSE) {
2366 serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2367 CFDictionaryAddValue(bridgeServices, bsdName, serviceList);
2368 CFRelease(serviceList);
2369 }
2370 serviceList = (CFMutableArrayRef)CFDictionaryGetValue(bridgeServices, bsdName);
2371 CFArrayAppendValue(serviceList, service);
2372 }
2373 }
2374 CFRelease(services);
2375 return bridgeServices;
2376 }
2377
2378
2379 static Boolean
2380 _SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
2381 SCPreferencesRef sourceNIPrefs,
2382 SCPreferencesRef targetPrefs,
2383 SCPreferencesRef targetNIPrefs,
2384 CFDictionaryRef bsdMapping,
2385 CFDictionaryRef setMapping,
2386 CFDictionaryRef serviceSetMapping)
2387 {
2388 CFArrayRef allSourceBridges;
2389 CFArrayRef allTargetBridges;
2390 SCBridgeInterfaceRef bridge;
2391 CFMutableDictionaryRef bridgeInterfaceMapping = NULL;
2392 CFMutableDictionaryRef bridgeMapping;
2393 CFDictionaryRef bsdNameToBridgeServices;
2394 SCVirtualInterfaceContext context;
2395 CFIndex count = 0;
2396 Boolean success = FALSE;
2397
2398 allSourceBridges = SCBridgeInterfaceCopyAll(sourcePrefs);
2399 allTargetBridges = SCBridgeInterfaceCopyAll(targetPrefs);
2400
2401 bsdNameToBridgeServices = _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(sourcePrefs);
2402
2403 bridgeInterfaceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2404 bridgeMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2405
2406 // Create Bridge Interface Mapping
2407 for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceBridges); idx++) {
2408 bridge = CFArrayGetValueAtIndex(allSourceBridges, idx);
2409 CFArrayRef bridgeMembers = SCBridgeInterfaceGetMemberInterfaces(bridge);
2410 CFMutableArrayRef interfaceList;
2411
2412 interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2413 for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(bridgeMembers); idx2++) {
2414 CFStringRef interfaceName = NULL;
2415 SCNetworkInterfaceRef interface = NULL;
2416
2417 interface = CFArrayGetValueAtIndex(bridgeMembers, idx2);
2418 interfaceName = SCNetworkInterfaceGetBSDName(interface);
2419
2420 if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
2421 CFStringRef bridgeNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bridge%ld"), count);
2422 CFDictionaryAddValue(bridgeMapping, interfaceName, bridgeNewName);
2423 CFArrayAppendValue(interfaceList, interfaceName);
2424 CFRelease(bridgeNewName);
2425 count++;
2426 }
2427 }
2428 if (CFArrayGetCount(interfaceList) > 0) {
2429 CFDictionaryAddValue(bridgeInterfaceMapping, bridge, interfaceList);
2430 }
2431 CFRelease(interfaceList);
2432 }
2433 // Remove bridge services from target
2434 _SCNetworkMigrationRemoveBridgeServices(targetPrefs);
2435
2436 // Remove Target Bridges
2437 for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBridges); idx++) {
2438 bridge = CFArrayGetValueAtIndex(allTargetBridges, idx);
2439 if (SCBridgeInterfaceRemove(bridge) == FALSE) {
2440 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoBridgeMigration: Could not remove bridge: %@"), bridge);
2441 goto done;
2442 }
2443 }
2444
2445 context.prefs = targetPrefs;
2446 context.ni_prefs = targetNIPrefs;
2447 context.bsdMapping = bsdMapping;
2448 context.virtualBSDMapping = bridgeMapping;
2449 context.mappingBSDNameToService = bsdNameToBridgeServices;
2450 context.setMapping = setMapping;
2451 context.serviceSetMapping = serviceSetMapping;
2452
2453 // Add Bridge configurations at the target using mapping
2454 CFDictionaryApplyFunction(bridgeInterfaceMapping, add_target_bridge, &context);
2455
2456 success = TRUE;
2457 done:
2458 CFRelease(allSourceBridges);
2459 CFRelease(allTargetBridges);
2460 CFRelease(bridgeInterfaceMapping);
2461 CFRelease(bridgeMapping);
2462 CFRelease(bsdNameToBridgeServices);
2463 return success;
2464 }
2465
2466
2467 static void
2468 add_target_bond(const void *key, const void *value, void *context)
2469 {
2470 CFNumberRef bondMode;
2471 CFStringRef bondName;
2472 CFDictionaryRef bondOptions;
2473 SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
2474 CFDictionaryRef bondBSDNameMapping = ctx->virtualBSDMapping;
2475 CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
2476 SCVirtualInterfaceMemberListContext memberListContext;
2477 CFMutableArrayRef newInterfaceList;
2478 SCBondInterfaceRef newBond;
2479 SCBondInterfaceRef oldBond = (SCBondInterfaceRef)key;
2480 CFStringRef oldBSDName;
2481 CFArrayRef oldInterfaceList = (CFArrayRef)value;
2482 CFArrayRef oldServiceList;
2483 SCPreferencesRef prefs = ctx->prefs;
2484 CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
2485 CFDictionaryRef setMapping = ctx->setMapping;
2486
2487 newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2488
2489 memberListContext.bsdMapping = ctx->bsdMapping;
2490 memberListContext.interfaceList = newInterfaceList;
2491 memberListContext.ni_prefs = ctx->ni_prefs;
2492
2493 CFArrayApplyFunction(oldInterfaceList, CFRangeMake(0, CFArrayGetCount(oldInterfaceList)), add_virtual_interface, &memberListContext);
2494
2495 newBond = SCBondInterfaceCreate(prefs);
2496 if (__SCBondInterfaceSetMemberInterfaces(newBond, newInterfaceList) == FALSE) {
2497 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bond: Adding member interface failed."));
2498 }
2499 CFRelease(newInterfaceList);
2500
2501 bondOptions = SCBondInterfaceGetOptions(oldBond);
2502 if (bondOptions != NULL) {
2503 SCBondInterfaceSetOptions(newBond, bondOptions);
2504 }
2505
2506 bondName = SCNetworkInterfaceGetLocalizedDisplayName(oldBond);
2507 if (bondName != NULL) {
2508 SCBondInterfaceSetLocalizedDisplayName(newBond, bondName);
2509 }
2510
2511 bondMode = SCBondInterfaceGetMode(oldBond);
2512 if (bondMode != NULL) {
2513 SCBondInterfaceSetMode(newBond, bondMode);
2514 }
2515 oldBSDName = SCNetworkInterfaceGetBSDName(oldBond);
2516 if (oldBSDName == NULL) {
2517 goto done;
2518 }
2519
2520 oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
2521 if (oldServiceList == NULL) {
2522 goto done;
2523 }
2524
2525 for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
2526 SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
2527 if (__SCNetworkServiceMigrateNew(prefs, oldService, bondBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
2528 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bond: Could not migrate service: %@"), oldService);
2529 }
2530 }
2531 done:
2532 CFRelease(newBond);
2533 }
2534
2535 static void
2536 _SCNetworkMigrationRemoveBondServices(SCPreferencesRef prefs)
2537 {
2538 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2539
2540 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2541 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2542 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2543 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2544
2545 if ((bsdName != NULL) &&
2546 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBond) {
2547 SCNetworkServiceRemove(service);
2548 }
2549 }
2550 CFRelease(services);
2551 }
2552
2553
2554 static CFDictionaryRef
2555 _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs)
2556 {
2557 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2558 CFMutableDictionaryRef bondServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2559
2560 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2561 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2562 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2563 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2564
2565 if ((bsdName != NULL) &&
2566 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBond) {
2567 CFMutableArrayRef serviceList;
2568 if (CFDictionaryContainsKey(bondServices, bsdName) == FALSE) {
2569 serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2570 CFDictionaryAddValue(bondServices, bsdName, serviceList);
2571 CFRelease(serviceList);
2572 }
2573 serviceList = (CFMutableArrayRef)CFDictionaryGetValue(bondServices, bsdName);
2574 CFArrayAppendValue(serviceList, service);
2575 }
2576 }
2577 CFRelease(services);
2578 return bondServices;
2579 }
2580
2581
2582 static Boolean
2583 _SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
2584 SCPreferencesRef sourceNIPrefs,
2585 SCPreferencesRef targetPrefs,
2586 SCPreferencesRef targetNIPrefs,
2587 CFDictionaryRef bsdMapping,
2588 CFDictionaryRef setMapping,
2589 CFDictionaryRef serviceSetMapping)
2590 {
2591 CFArrayRef allSourceBonds;
2592 CFArrayRef allTargetBonds;
2593 SCBondInterfaceRef bond;
2594 CFMutableDictionaryRef bondInterfaceMapping = NULL;
2595 CFMutableDictionaryRef bondMapping;
2596 CFDictionaryRef bsdNameToBondServices;
2597 SCVirtualInterfaceContext context;
2598 CFIndex count = 0;
2599 Boolean success = FALSE;
2600
2601 allSourceBonds = SCBondInterfaceCopyAll(sourcePrefs);
2602 allTargetBonds = SCBondInterfaceCopyAll(targetPrefs);
2603
2604 bsdNameToBondServices = _SCNetworkMigrationCopyMappingBSDNameToBondServices(sourcePrefs);
2605
2606 bondInterfaceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2607 bondMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2608 // Create Bond Interface mapping
2609 for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceBonds); idx++) {
2610 bond = CFArrayGetValueAtIndex(allSourceBonds, idx);
2611 CFArrayRef bondMembers = SCBondInterfaceGetMemberInterfaces(bond);
2612 CFMutableArrayRef interfaceList;
2613
2614 interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2615 for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(bondMembers); idx2++) {
2616 CFStringRef interfaceName;
2617 SCNetworkInterfaceRef interface;
2618
2619 interface = CFArrayGetValueAtIndex(bondMembers, idx2);
2620 interfaceName = SCNetworkInterfaceGetBSDName(interface);
2621
2622 if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
2623 CFStringRef bondNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bond%ld"), count);
2624 CFDictionaryAddValue(bondMapping, interfaceName, bondNewName);
2625 CFArrayAppendValue(interfaceList, interfaceName);
2626 CFRelease(bondNewName);
2627 count++;
2628 }
2629 }
2630 if (CFArrayGetCount(interfaceList) > 0) {
2631 CFDictionaryAddValue(bondInterfaceMapping, bond, interfaceList);
2632 }
2633 CFRelease(interfaceList);
2634 }
2635 // Remove bond services from target
2636 _SCNetworkMigrationRemoveBondServices(targetPrefs);
2637
2638 // Remove Target Bonds
2639 for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBonds); idx++) {
2640 bond = CFArrayGetValueAtIndex(allTargetBonds, idx);
2641 if (SCBondInterfaceRemove(bond) == FALSE) {
2642 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoBondMigration: Could not remove bond: %@"), bond);
2643 goto done;
2644 }
2645 }
2646
2647 context.prefs = targetPrefs;
2648 context.ni_prefs = targetNIPrefs;
2649 context.bsdMapping = bsdMapping;
2650 context.virtualBSDMapping = bondMapping;
2651 context.mappingBSDNameToService = bsdNameToBondServices;
2652 context.setMapping = setMapping;
2653 context.serviceSetMapping = serviceSetMapping;
2654
2655 // Add Bond configurations at the target using mapping
2656 CFDictionaryApplyFunction(bondInterfaceMapping, add_target_bond, &context);
2657
2658 success = TRUE;
2659 done:
2660 CFRelease(allSourceBonds);
2661 CFRelease(allTargetBonds);
2662 CFRelease(bondInterfaceMapping);
2663 CFRelease(bondMapping);
2664 CFRelease(bsdNameToBondServices);
2665 return success;
2666 }
2667
2668 static void
2669 add_target_vlan(const void *value, void *context)
2670 {
2671 CFDictionaryRef bsdMapping;
2672 SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
2673 CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
2674 SCPreferencesRef prefs = ctx->prefs;
2675 SCVLANInterfaceRef newVLAN = NULL;
2676 SCNetworkInterfaceRef newPhysicalInterface = NULL;
2677 CFStringRef newPhysicalInterfaceName;
2678 SCVLANInterfaceRef oldVLAN = (SCVLANInterfaceRef)value;
2679 CFStringRef oldBSDName;
2680 SCNetworkInterfaceRef oldPhysicalInterface;
2681 CFStringRef oldPhysicalInterfaceName;
2682 SCNetworkServiceRef oldService;
2683 CFArrayRef oldServiceList;
2684 CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
2685 CFDictionaryRef setMapping = ctx->setMapping;
2686 CFDictionaryRef vlanBSDMapping = ctx->virtualBSDMapping;
2687 CFNumberRef vlanTag;
2688 CFStringRef vlanName;
2689 CFDictionaryRef vlanOptions;
2690
2691 bsdMapping = ctx->bsdMapping;
2692 oldPhysicalInterface = SCVLANInterfaceGetPhysicalInterface(oldVLAN);
2693
2694 if (oldPhysicalInterface == NULL) {
2695 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: oldPhysicalInterface is NULL"));
2696 goto done;
2697 }
2698 oldPhysicalInterfaceName = SCNetworkInterfaceGetBSDName(oldPhysicalInterface);
2699
2700 if (oldPhysicalInterfaceName == NULL) {
2701 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: oldPhysicalInterfaceName is NULL"));
2702 goto done;
2703 }
2704
2705 newPhysicalInterfaceName = CFDictionaryGetValue(bsdMapping, oldPhysicalInterfaceName);
2706 if (newPhysicalInterfaceName == NULL) {
2707 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: newPhysicalInterfaceName is NULL"));
2708 goto done;
2709 }
2710 newPhysicalInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ctx->ni_prefs, newPhysicalInterfaceName);
2711 if (newPhysicalInterface == NULL) {
2712 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: newPhysicalInterface is NULL"));
2713 goto done;
2714 }
2715
2716 vlanTag = SCVLANInterfaceGetTag(oldVLAN);
2717 if (vlanTag == NULL) {
2718 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: vlanTag is NULL"));
2719 goto done;
2720 }
2721
2722 newVLAN = SCVLANInterfaceCreate(prefs, newPhysicalInterface, vlanTag);
2723 if (newVLAN == NULL) {
2724 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: Could not create newVLAN"));
2725 }
2726
2727 vlanName = SCNetworkInterfaceGetLocalizedDisplayName(oldVLAN);
2728 if (vlanName != NULL) {
2729 SCVLANInterfaceSetLocalizedDisplayName(newVLAN, vlanName);
2730 }
2731
2732 vlanOptions = SCVLANInterfaceGetOptions(oldVLAN);
2733 if (vlanOptions != NULL) {
2734 SCVLANInterfaceSetOptions(newVLAN, vlanOptions);
2735 }
2736 oldBSDName = SCNetworkInterfaceGetBSDName(oldVLAN);
2737
2738 if (oldBSDName == NULL) {
2739 goto done;
2740 }
2741
2742 oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
2743 if (oldServiceList == NULL) {
2744 goto done;
2745 }
2746
2747 for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
2748 oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
2749 if (__SCNetworkServiceMigrateNew(prefs, oldService, vlanBSDMapping, setMapping, serviceSetMapping) == FALSE) {
2750 SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: Could not migrate service: %@"), oldService);
2751 }
2752 }
2753
2754 done:
2755 if (newPhysicalInterface != NULL) {
2756 CFRelease(newPhysicalInterface);
2757 }
2758 if (newVLAN != NULL) {
2759 CFRelease(newVLAN);
2760 }
2761 }
2762
2763 static void
2764 _SCNetworkMigrationRemoveVLANServices(SCPreferencesRef prefs)
2765 {
2766 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2767
2768 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2769 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2770 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2771 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2772
2773 if ((bsdName != NULL) &&
2774 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeVLAN) {
2775 SCNetworkServiceRemove(service);
2776 }
2777 }
2778
2779 CFRelease(services);
2780 }
2781
2782
2783 static CFDictionaryRef
2784 _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs)
2785 {
2786 CFArrayRef services = SCNetworkServiceCopyAll(prefs);
2787 CFMutableDictionaryRef vlanServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2788
2789 for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
2790 SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
2791 SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
2792 CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
2793
2794 if ((bsdName != NULL) &&
2795 SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeVLAN) {
2796 CFMutableArrayRef serviceList;
2797 if (CFDictionaryContainsKey(vlanServices, bsdName) == FALSE) {
2798 serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2799 CFDictionaryAddValue(vlanServices, bsdName, serviceList);
2800 CFRelease(serviceList);
2801 }
2802 serviceList = (CFMutableArrayRef)CFDictionaryGetValue(vlanServices, bsdName);
2803 CFArrayAppendValue(serviceList, service);
2804 }
2805 }
2806 CFRelease(services);
2807 return vlanServices;
2808 }
2809
2810 static Boolean
2811 _SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
2812 SCPreferencesRef sourceNIPrefs,
2813 SCPreferencesRef targetPrefs,
2814 SCPreferencesRef targetNIPrefs,
2815 CFDictionaryRef bsdMapping,
2816 CFDictionaryRef setMapping,
2817 CFDictionaryRef serviceSetMapping)
2818 {
2819 CFArrayRef allSourceVLAN;
2820 CFArrayRef allTargetVLAN;
2821 SCVirtualInterfaceContext context;
2822 CFIndex count = 0;
2823 Boolean success = FALSE;
2824 SCVLANInterfaceRef vlan;
2825 CFMutableArrayRef vlanList;
2826 CFMutableDictionaryRef vlanMapping;
2827 CFDictionaryRef bsdNameToVLANServices;
2828
2829 allSourceVLAN = SCVLANInterfaceCopyAll(sourcePrefs);
2830 allTargetVLAN = SCVLANInterfaceCopyAll(targetPrefs);
2831
2832 bsdNameToVLANServices = _SCNetworkMigrationCopyMappingBSDNameToVLANServices(sourcePrefs);
2833
2834 vlanList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2835 vlanMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2836
2837 for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceVLAN); idx++) {
2838 vlan = CFArrayGetValueAtIndex(allSourceVLAN, idx);
2839 CFStringRef vlanBSDName = SCNetworkInterfaceGetBSDName(vlan);
2840 SCNetworkInterfaceRef physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlan);
2841 CFStringRef physicalInterfaceName;
2842
2843 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: physical interface is %@"), physicalInterface);
2844
2845 physicalInterfaceName = SCNetworkInterfaceGetBSDName(physicalInterface);
2846 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: Physical Interface name is %@"), physicalInterfaceName);
2847
2848 // Add VLAN to be migrated if the mapping between interfaces exists
2849 if (CFDictionaryContainsKey(bsdMapping, physicalInterfaceName) == TRUE) {
2850 CFStringRef vlanNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("vlan%ld"), count);
2851 CFDictionaryAddValue(vlanMapping, vlanBSDName, vlanNewName);
2852 CFArrayAppendValue(vlanList, vlan);
2853 CFRelease(vlanNewName);
2854 count++;
2855 }
2856 }
2857 // Remove vlan services from target
2858 _SCNetworkMigrationRemoveVLANServices(targetPrefs);
2859
2860 // Remove Target VLANs
2861 for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetVLAN); idx++) {
2862 vlan = CFArrayGetValueAtIndex(allTargetVLAN, idx);
2863 if (SCVLANInterfaceRemove(vlan) == FALSE) {
2864 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: Could not remove VLAN: %@"), vlan);
2865 goto done;
2866 }
2867 }
2868
2869 context.prefs = targetPrefs;
2870 context.ni_prefs = targetNIPrefs;
2871 context.bsdMapping = bsdMapping;
2872 context.virtualBSDMapping = vlanMapping;
2873 context.mappingBSDNameToService = bsdNameToVLANServices;
2874 context.setMapping = setMapping;
2875 context.serviceSetMapping = serviceSetMapping;
2876
2877 // Add VLAN configurations at the target using vlanList
2878 CFArrayApplyFunction(vlanList, CFRangeMake(0, CFArrayGetCount(vlanList)), add_target_vlan, &context);
2879
2880 success = TRUE;
2881 done:
2882 CFRelease(allSourceVLAN);
2883 CFRelease(allTargetVLAN);
2884 CFRelease(vlanList);
2885 CFRelease(vlanMapping);
2886 CFRelease(bsdNameToVLANServices);
2887 return success;
2888 }
2889
2890 static Boolean
2891 _SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePrefs,
2892 SCPreferencesRef sourceNIPrefs,
2893 SCPreferencesRef targetPrefs,
2894 SCPreferencesRef targetNIPrefs,
2895 CFDictionaryRef bsdMapping,
2896 CFDictionaryRef setMapping,
2897 CFDictionaryRef serviceSetMapping)
2898 {
2899 // Handle Bridges
2900 if (_SCNetworkMigrationDoBridgeMigration(sourcePrefs, sourceNIPrefs,
2901 targetPrefs, targetNIPrefs,
2902 bsdMapping, setMapping, serviceSetMapping) == FALSE) {
2903 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: Bridge migration failed"));
2904 }
2905
2906 // Handle Bonds
2907 if (_SCNetworkMigrationDoBondMigration(sourcePrefs, sourceNIPrefs,
2908 targetPrefs, targetNIPrefs,
2909 bsdMapping, setMapping, serviceSetMapping) == FALSE) {
2910 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: Bond migration failed"));
2911 }
2912
2913 // Handle VLANs
2914 if (_SCNetworkMigrationDoVLANMigration(sourcePrefs, sourceNIPrefs,
2915 targetPrefs, targetNIPrefs,
2916 bsdMapping, setMapping, serviceSetMapping) == FALSE) {
2917 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: VLAN migration failed"));
2918 }
2919 return TRUE;
2920 }
2921 #endif
2922
2923 typedef struct {
2924 SCPreferencesRef prefs;
2925 CFArrayRef serviceOrder;
2926 CFMutableArrayRef serviceListMutable;
2927 Boolean* success;
2928 } migrated_service_context;
2929
2930 static void
2931 create_migrated_order(const void *value, void *context)
2932 {
2933 migrated_service_context *ctx = (migrated_service_context*)context;
2934 CFMutableArrayRef migratedServiceOrder = ctx->serviceListMutable;
2935 CFArrayRef targetServiceOrder = ctx->serviceOrder;
2936 CFStringRef migratedServiceID = (CFStringRef)value;
2937 Boolean *success = ctx->success;
2938
2939 if (*success == FALSE) {
2940 return;
2941 }
2942 // Preserving the service order in the source configuration for the services
2943 // which were migrated into the target configuration
2944 for (CFIndex idx = 0; idx < CFArrayGetCount(targetServiceOrder); idx++) {
2945 CFStringRef targetServiceID = CFArrayGetValueAtIndex(targetServiceOrder, idx);
2946 if (CFEqual(migratedServiceID, targetServiceID) == TRUE) {
2947 CFArrayAppendValue(migratedServiceOrder, migratedServiceID);
2948 return;
2949 }
2950 }
2951 }
2952
2953 static void
2954 create_non_migrated_service_list(const void *value, void *context)
2955 {
2956 migrated_service_context *ctx = (migrated_service_context*)context;
2957 CFArrayRef migratedServiceOrder = ctx->serviceOrder;
2958 CFMutableArrayRef nonMigratedService = ctx->serviceListMutable;
2959 SCPreferencesRef prefs = ctx->prefs;
2960 SCNetworkServiceRef service;
2961 Boolean *success = ctx->success;
2962 CFStringRef targetServiceID = (CFStringRef)value;
2963
2964 if (*success == FALSE) {
2965 return;
2966 }
2967 // Adding all services not present in migratedServiceOrder into nonMigrated service
2968 for (CFIndex idx = 0; idx < CFArrayGetCount(migratedServiceOrder); idx++) {
2969 CFStringRef migratedServiceID = CFArrayGetValueAtIndex(migratedServiceOrder, idx);
2970
2971 if (CFEqual(targetServiceID, migratedServiceID) == TRUE) {
2972 return;
2973 }
2974 }
2975 service = SCNetworkServiceCopy(prefs, targetServiceID);
2976 if (service == NULL) {
2977 *success = FALSE;
2978 return;
2979 }
2980
2981 CFArrayAppendValue(nonMigratedService, service);
2982 CFRelease(service);
2983 }
2984
2985 static void
2986 preserve_service_order(const void *key, const void *value, void *context)
2987 {
2988 migrated_service_context migrated_context;
2989 CFMutableArrayRef migratedServiceOrder;
2990 migrated_service_context non_migrated_context;
2991 CFMutableArrayRef nonMigratedServices;
2992 SCNetworkSetRef sourceSet = (SCNetworkSetRef)key;
2993 CFArrayRef sourceServiceOrder = NULL;
2994 Boolean *success = (Boolean*)context;
2995 SCNetworkSetRef targetSet = (SCNetworkSetRef)value;
2996 SCNetworkSetPrivateRef targetPrivate = (SCNetworkSetPrivateRef)targetSet;
2997 CFArrayRef targetServiceOrder = NULL;
2998
2999 if (*success == FALSE) {
3000 return;
3001 }
3002 migratedServiceOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
3003 nonMigratedServices = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
3004
3005 sourceServiceOrder = SCNetworkSetGetServiceOrder(sourceSet);
3006 if (sourceServiceOrder == NULL) {
3007 goto done;
3008 }
3009 targetServiceOrder = SCNetworkSetGetServiceOrder(targetSet);
3010 if (targetServiceOrder == NULL) {
3011 goto done;
3012 }
3013
3014 migrated_context.prefs = NULL;
3015 migrated_context.serviceOrder = targetServiceOrder;
3016 migrated_context.serviceListMutable = migratedServiceOrder;
3017 migrated_context.success = success;
3018
3019 // Creating a list of service IDs which were migrated in the target set
3020 // while maintaining the service order or the source set
3021 CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context);
3022
3023 if (success == FALSE) {
3024 goto done;
3025 }
3026
3027 non_migrated_context.prefs = targetPrivate->prefs;
3028 non_migrated_context.serviceOrder = migratedServiceOrder;
3029 non_migrated_context.serviceListMutable = nonMigratedServices;
3030 non_migrated_context.success = success;
3031
3032 // Creating a list of all the services which were not migrated from the source set to the
3033 // target set
3034 CFArrayApplyFunction(targetServiceOrder, CFRangeMake(0, CFArrayGetCount(targetServiceOrder)), create_non_migrated_service_list, &non_migrated_context);
3035
3036 // Remove non migrated service
3037 for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
3038 SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
3039 SCNetworkSetRemoveService(targetSet, service);
3040 }
3041 // Set migrated service order
3042 SCNetworkSetSetServiceOrder(targetSet, migratedServiceOrder);
3043
3044 // Add non migrated services
3045 for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
3046 SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
3047 SCNetworkSetAddService(targetSet, service);
3048 }
3049
3050 done:
3051 CFRelease(migratedServiceOrder);
3052 CFRelease(nonMigratedServices);
3053 return;
3054
3055 }
3056
3057 static Boolean
3058 _SCNetworkMigrationDoServiceOrderMigration(SCPreferencesRef sourcePrefs,
3059 SCPreferencesRef targetPrefs,
3060 CFDictionaryRef setMapping)
3061 {
3062 Boolean success = TRUE;
3063
3064 if (isA_CFDictionary(setMapping) == NULL) {
3065 success = FALSE;
3066 goto done;
3067 }
3068
3069 CFDictionaryApplyFunction(setMapping, preserve_service_order, &success);
3070 done:
3071 return success;
3072 }
3073
3074
3075 // This is a function that looks at source and target network configuration
3076 // and determines what network configurations can be transferred from source to
3077 // target
3078 static Boolean
3079 _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetDir)
3080 {
3081 CFDictionaryRef bsdNameMapping = NULL; // Mapping between BSD name and SCNetworkInterfaceRef to help with mapping services
3082 CFMutableDictionaryRef builtinMapping = NULL; // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
3083 CFMutableDictionaryRef externalMapping = NULL; // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
3084 Boolean migrationSuccess = FALSE;
3085 CFArrayRef newTargetNetworkInterfaceEntity = NULL; // Array of Interface Entity which used to create new target interfaces created during migration
3086 CFDictionaryRef serviceMapping = NULL; // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef)
3087 CFDictionaryRef setMapping = NULL;
3088 CFDictionaryRef sourceServiceSetMapping = NULL;
3089 CFArrayRef sourceConfigurationFiles = NULL; // Path to the source configuration files which need to be migrated
3090 CFURLRef sourceNetworkInterfaceFile = NULL; // Source CFURLRef for preferences.plist and NetworkInterfaces.plist
3091 char sourceNetworkInterfaceFileStr[PATH_MAX];
3092 CFStringRef sourceNetworkInterfaceFileString = NULL; // Source CFStringRef for preferences.plist and NetworkInterfaces.plist
3093 SCPreferencesRef sourceNetworkInterfacePrefs = NULL; // Source SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
3094 CFURLRef sourcePreferencesFile = NULL;
3095 char sourcePreferencesFileStr[PATH_MAX];
3096 CFStringRef sourcePreferencesFileString = NULL;
3097 SCPreferencesRef sourcePrefs = NULL;
3098 CFArrayRef targetConfigurationFiles = NULL; // Path to the target configuration files where migration will take place to
3099 Boolean targetConfigurationFilesPresent;
3100 CFURLRef targetNetworkInterfaceFile = NULL; // Target CFURLRef for preferences.plist and NetworkInterfaces.plist
3101 char targetNetworkInterfaceFileStr[PATH_MAX];
3102 CFStringRef targetNetworkInterfaceFileString = NULL; // Target CFStringRef for preferences.plist and NetworkInterfaces.plist
3103 SCPreferencesRef targetNetworkInterfacePrefs = NULL; // Target SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
3104 CFURLRef targetPreferencesFile = NULL;
3105 char targetPreferencesFileStr[PATH_MAX];
3106 CFStringRef targetPreferencesFileString = NULL;
3107 SCPreferencesRef targetPrefs = NULL;
3108 CFMutableDictionaryRef validityOptions = NULL;
3109
3110 // Check if configuration files exist in sourceDir
3111 if (__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir, &sourceConfigurationFiles) == FALSE) {
3112 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: sourceDir: (%@) doesn't contain configuration files"), sourceDir);
3113 goto done;
3114 }
3115
3116 sourcePreferencesFile = CFArrayGetValueAtIndex(sourceConfigurationFiles, PREFERENCES_PLIST_INDEX);
3117 if (CFURLGetFileSystemRepresentation(sourcePreferencesFile, TRUE, (UInt8*)sourcePreferencesFileStr, sizeof(sourcePreferencesFileStr)) == FALSE) {
3118 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), sourcePreferencesFile);
3119 goto done;
3120 }
3121
3122 sourceNetworkInterfaceFile = CFArrayGetValueAtIndex(sourceConfigurationFiles, NETWORK_INTERFACES_PLIST_INDEX);
3123 if (CFURLGetFileSystemRepresentation(sourceNetworkInterfaceFile, TRUE, (UInt8*)sourceNetworkInterfaceFileStr, sizeof(sourceNetworkInterfaceFileStr)) == FALSE) {
3124 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), sourceNetworkInterfaceFile);
3125 goto done;
3126 }
3127
3128 sourcePreferencesFileString = CFStringCreateWithCString(NULL, sourcePreferencesFileStr, kCFStringEncodingUTF8);
3129 sourceNetworkInterfaceFileString = CFStringCreateWithCString(NULL, sourceNetworkInterfaceFileStr, kCFStringEncodingUTF8);
3130
3131 sourcePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, sourcePreferencesFileString);
3132 sourceNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, sourceNetworkInterfaceFileString);
3133 if ((sourcePrefs == NULL) || (sourceNetworkInterfacePrefs == NULL)) {
3134 goto done;
3135 }
3136
3137 if ((targetConfigurationFilesPresent = __SCNetworkConfigurationMigrateConfigurationFilesPresent(targetDir, &targetConfigurationFiles)) == FALSE) {
3138 if (targetConfigurationFiles == NULL) {
3139 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: targetConfigurationFiles is NULL"));
3140 goto done;
3141 }
3142 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: targetDir: (%@) doesn't contain configuration files ... Need to create default configuration"), targetDir);
3143 }
3144
3145 targetPreferencesFile = CFArrayGetValueAtIndex(targetConfigurationFiles, PREFERENCES_PLIST_INDEX);
3146 if (CFURLGetFileSystemRepresentation(targetPreferencesFile, TRUE, (UInt8*)targetPreferencesFileStr, sizeof(targetPreferencesFileStr)) == FALSE) {
3147 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), targetPreferencesFile);
3148 goto done;
3149 }
3150 targetNetworkInterfaceFile = CFArrayGetValueAtIndex(targetConfigurationFiles, NETWORK_INTERFACES_PLIST_INDEX);
3151 if (CFURLGetFileSystemRepresentation(targetNetworkInterfaceFile, TRUE, (UInt8*)targetNetworkInterfaceFileStr, sizeof(targetNetworkInterfaceFileStr)) == FALSE) {
3152 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), targetNetworkInterfaceFile);
3153 goto done;
3154 }
3155
3156 targetPreferencesFileString = CFStringCreateWithCString(NULL, targetPreferencesFileStr, kCFStringEncodingUTF8);
3157 targetNetworkInterfaceFileString = CFStringCreateWithCString(NULL, targetNetworkInterfaceFileStr, kCFStringEncodingUTF8);
3158
3159 if (targetConfigurationFilesPresent == TRUE) {
3160 targetPrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetPreferencesFileString);
3161 targetNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetNetworkInterfaceFileString);
3162 if ((targetPrefs == NULL) || (targetNetworkInterfacePrefs == NULL)) {
3163 goto done;
3164 }
3165 }
3166 else {
3167 targetPrefs = __SCNetworkCreateDefaultPref(targetPreferencesFileString);
3168 targetNetworkInterfacePrefs = __SCNetworkCreateDefaultNIPrefs(targetNetworkInterfaceFileString);
3169
3170 if (targetPrefs == NULL ||
3171 targetNetworkInterfacePrefs == NULL) {
3172 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Could not create default configuration."));
3173 goto done;
3174 }
3175 }
3176 validityOptions = CFDictionaryCreateMutable(NULL, 0,
3177 &kCFTypeDictionaryKeyCallBacks,
3178 &kCFTypeDictionaryValueCallBacks);
3179 CFDictionaryAddValue(validityOptions, kSCNetworkConfigurationRepair, kCFBooleanTrue);
3180
3181 SCLog(_sc_debug, LOG_NOTICE, CFSTR("sourcePreferenceFileString: %@\n sourceNetworkInterfaceFileString:%@\n targetPreferencesFileString:%@\ntargetNetworkInterfaceFileString:%@"), sourcePreferencesFileString, sourceNetworkInterfaceFileString,
3182 targetPreferencesFileString, targetNetworkInterfaceFileString);
3183
3184 // Setting Bypass Interface to avoid looking at system interfaces
3185 __SCPreferencesSetLimitSCNetworkConfiguration(sourcePrefs, TRUE);
3186 __SCPreferencesSetLimitSCNetworkConfiguration(targetPrefs, TRUE);
3187
3188 // Create services for builtin interfaces at source if they don't exist
3189 (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(sourcePrefs, sourceNetworkInterfacePrefs);
3190 // Checking validity of the source and destination preferences before continuing
3191 if (_SCNetworkConfigurationCheckValidityUsingPreferences(sourcePrefs,
3192 sourceNetworkInterfacePrefs,
3193 validityOptions) == FALSE) {
3194 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Source configuration is not valid"));
3195 goto skipServiceMigration;
3196 }
3197 // Only call this function if configuration files were not created by default
3198 if (targetConfigurationFilesPresent == TRUE) {
3199 // Create services for builtin interfaces at target if they don't exist
3200 (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(targetPrefs, targetNetworkInterfacePrefs);
3201 if (_SCNetworkConfigurationCheckValidityUsingPreferences(targetPrefs,
3202 targetNetworkInterfacePrefs,
3203 validityOptions) == FALSE) {
3204 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Target configuration is not valid"));
3205 goto skipServiceMigration;
3206 }
3207 }
3208
3209 builtinMapping = _SCNetworkConfigurationCopyBuiltinMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
3210 externalMapping = _SCNetworkConfigurationCopyExternalInterfaceMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
3211
3212 /*
3213 TODO:
3214 Now builtin and external interface mapping is complete, work needs to be done on updating the preferences.plist and NetworkInterface.plist.
3215
3216 Also, work needs to be done to check the validity of the data in preferences in source and target destinations, and after migration
3217 */
3218
3219 newTargetNetworkInterfaceEntity = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping);
3220 if (isA_CFArray(newTargetNetworkInterfaceEntity) == NULL) {
3221 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: newTargetNetworkInterfaceEntity is NULL or not of correct type"));
3222 goto done;
3223 }
3224 // Write new interface mapping to NetworkInterfaces.plist
3225 if (__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity) == FALSE)
3226 {
3227 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: SCNetworkInterfaceSaveStoreWithPreferences failed to update NetworkInterface.plist"));
3228 goto done;
3229 }
3230 // Create BSD Name Mapping to facilitate mapping of services
3231 bsdNameMapping = _SCNetworkMigrationCreateBSDNameMapping(builtinMapping, externalMapping);
3232
3233 if (isA_CFDictionary(bsdNameMapping) == NULL) {
3234 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: BSD Name Mapping is NULL"));
3235 goto done;
3236 }
3237 SCLog(_sc_debug, LOG_NOTICE, CFSTR("BSD Name Mapping: %@"), bsdNameMapping);
3238 serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(sourcePrefs, targetPrefs, bsdNameMapping);
3239
3240 if (isA_CFDictionary(serviceMapping) == NULL) {
3241 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Service Mapping is NULL"));
3242 goto done;
3243 }
3244 SCLog(_sc_debug, LOG_NOTICE, CFSTR("Service Mapping: %@"), serviceMapping);
3245
3246 setMapping = _SCNetworkMigrationCreateSetMapping(sourcePrefs, targetPrefs);
3247 sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs);
3248
3249 // Perform the migration of services
3250 if (_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs,
3251 serviceMapping, bsdNameMapping,
3252 setMapping, sourceServiceSetMapping) == FALSE) {
3253 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: SCNetworkMigrationDoServiceMigration failed to complete successfully"));
3254 goto done;
3255 }
3256
3257 #if !TARGET_OS_IPHONE
3258 // Migrating Virtual Network Interface
3259 if (_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs, sourceNetworkInterfacePrefs,
3260 targetPrefs, targetNetworkInterfacePrefs,
3261 bsdNameMapping, setMapping, sourceServiceSetMapping) == FALSE) {
3262 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoVirtualNetworkInterfaceMigration failed to complete successfully"));
3263 }
3264 #endif
3265 // Migrate Service Order
3266 if (_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping) == FALSE) {
3267 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoServiceOrderMigration failed to complete successfully"));
3268 }
3269
3270 skipServiceMigration:
3271 // Migrating System Information
3272 if (_SCNetworkMigrationDoSystemMigration(sourcePrefs, targetPrefs) == FALSE) {
3273 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoSystemMigration failed to complete successfully"));
3274 }
3275
3276 if (_SCNetworkConfigurationCheckValidityUsingPreferences(targetPrefs, targetNetworkInterfacePrefs, NULL) == FALSE) {
3277 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Migrated configuration is not valid"));
3278 goto done;
3279 }
3280 if (SCPreferencesCommitChanges(targetPrefs) == FALSE) {
3281 SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Error commiting targetPrefs, %s"), SCErrorString(SCError()));
3282 goto done;
3283 }
3284
3285 if (SCPreferencesCommitChanges(targetNetworkInterfacePrefs) == FALSE) {
3286 SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Error commiting targetNetworkInterfacePrefs, %s"), SCErrorString(SCError()));
3287 goto done;
3288 }
3289 migrationSuccess = TRUE;
3290
3291 done:
3292 if (setMapping != NULL) {
3293 CFRelease(setMapping);
3294 }
3295 if (sourceServiceSetMapping != NULL) {
3296 CFRelease(sourceServiceSetMapping);
3297 }
3298 if (sourceConfigurationFiles != NULL) {
3299 CFRelease(sourceConfigurationFiles);
3300 }
3301 if (targetConfigurationFiles != NULL) {
3302 CFRelease(targetConfigurationFiles);
3303 }
3304 if (sourcePreferencesFileString != NULL) {
3305 CFRelease(sourcePreferencesFileString);
3306 }
3307 if (sourceNetworkInterfaceFileString != NULL) {
3308 CFRelease(sourceNetworkInterfaceFileString);
3309 }
3310 if (targetPreferencesFileString != NULL) {
3311 CFRelease(targetPreferencesFileString);
3312 }
3313 if (targetNetworkInterfaceFileString != NULL) {
3314 CFRelease(targetNetworkInterfaceFileString);
3315 }
3316 if (newTargetNetworkInterfaceEntity != NULL) {
3317 CFRelease(newTargetNetworkInterfaceEntity);
3318 }
3319 if (builtinMapping != NULL) {
3320 CFRelease(builtinMapping);
3321 }
3322 if (externalMapping != NULL) {
3323 CFRelease(externalMapping);
3324 }
3325 if (bsdNameMapping != NULL) {
3326 CFRelease(bsdNameMapping);
3327 }
3328 if (serviceMapping != NULL) {
3329 CFRelease(serviceMapping);
3330 }
3331 if (targetPrefs != NULL) {
3332 CFRelease(targetPrefs);
3333 }
3334 if (sourcePrefs != NULL) {
3335 CFRelease(sourcePrefs);
3336 }
3337 if (sourceNetworkInterfacePrefs != NULL) {
3338 CFRelease(sourceNetworkInterfacePrefs);
3339 }
3340 if (targetNetworkInterfacePrefs != NULL) {
3341 CFRelease(targetNetworkInterfacePrefs);
3342 }
3343 if (validityOptions != NULL) {
3344 CFRelease(validityOptions);
3345 }
3346 return migrationSuccess;
3347 }
3348
3349 #define N_QUICK 64
3350
3351 static Boolean
3352 _SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferencesRef expectedConfigPref)
3353 {
3354 const void * expected_vals_q[N_QUICK];
3355 const void ** expected_vals = expected_vals_q;
3356 CFMutableArrayRef expectedServiceArray = NULL;
3357 CFIndex expectedServiceArrayCount = 0;
3358 CFDictionaryRef expectedServiceDict = NULL;
3359 CFIndex expectedServiceDictCount = 0;
3360 CFDictionaryRef expectedServiceEntity = 0;
3361 Boolean foundMatch = FALSE;
3362 CFMutableArrayRef serviceArray = NULL;
3363 CFIndex serviceArrayCount = 0;
3364 CFDictionaryRef serviceDict = NULL;
3365 CFIndex serviceDictCount = 0;
3366 CFDictionaryRef serviceEntity = NULL;
3367 Boolean success = FALSE;
3368 const void * vals_q[N_QUICK];
3369 const void ** vals = vals_q;
3370
3371 serviceDict = SCPreferencesGetValue(configPref, kSCPrefNetworkServices);
3372 if (isA_CFDictionary(serviceDict) == NULL) {
3373 goto done;
3374 }
3375 serviceDictCount = CFDictionaryGetCount(serviceDict);
3376
3377 expectedServiceDict = SCPreferencesGetValue(expectedConfigPref, kSCPrefNetworkServices);
3378 if (isA_CFDictionary(expectedServiceDict) == NULL) {
3379 goto done;
3380 }
3381 expectedServiceDictCount = CFDictionaryGetCount(expectedServiceDict);
3382
3383 if (serviceDictCount != expectedServiceDictCount) {
3384 goto done;
3385 }
3386
3387 if (serviceDictCount > (sizeof(vals_q) / sizeof(CFTypeRef))) {
3388 vals = CFAllocatorAllocate(NULL, serviceDictCount * sizeof(CFPropertyListRef), 0);
3389 }
3390
3391 CFDictionaryGetKeysAndValues(serviceDict, NULL, vals);
3392 serviceArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
3393
3394 for (CFIndex idx=0; idx < serviceDictCount; idx++) {
3395 serviceEntity = vals[idx];
3396 if (isA_CFDictionary(serviceEntity) == FALSE) {
3397 continue;
3398 }
3399 CFArrayAppendValue(serviceArray, serviceEntity);
3400 }
3401
3402 serviceArrayCount = CFArrayGetCount(serviceArray);
3403
3404 if (expectedServiceDictCount > (sizeof(expected_vals_q) / sizeof(CFTypeRef))) {
3405 expected_vals = CFAllocatorAllocate(NULL, expectedServiceDictCount, 0);
3406 }
3407
3408 CFDictionaryGetKeysAndValues(expectedServiceDict, NULL, expected_vals);
3409 expectedServiceArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
3410
3411 for (CFIndex idx = 0; idx < expectedServiceDictCount; idx++) {
3412 serviceEntity = expected_vals[idx];
3413
3414 if (isA_CFDictionary(serviceEntity) == FALSE) {
3415 continue;
3416 }
3417 CFArrayAppendValue(expectedServiceArray, serviceEntity);
3418 }
3419 expectedServiceArrayCount = CFArrayGetCount(expectedServiceArray);
3420
3421 if (serviceArrayCount != expectedServiceArrayCount) {
3422 goto done;
3423 }
3424
3425 for (CFIndex idx = 0; idx < expectedServiceArrayCount; idx++) {
3426 foundMatch = FALSE;
3427 expectedServiceEntity = CFArrayGetValueAtIndex(expectedServiceArray, idx);
3428 serviceArrayCount = CFArrayGetCount(serviceArray);
3429
3430 for (CFIndex idx2 = 0; idx2 < serviceArrayCount; idx2++) {
3431 serviceEntity = CFArrayGetValueAtIndex(serviceArray, idx2);
3432
3433 if (CFEqual(expectedServiceEntity, serviceEntity) == TRUE) {
3434 foundMatch = TRUE;
3435 break;
3436 }
3437 }
3438
3439 if (foundMatch == FALSE) {
3440 break;
3441 }
3442 }
3443
3444 success = foundMatch;
3445 done:
3446 if (vals != vals_q) {
3447 CFAllocatorDeallocate(NULL, vals);
3448 }
3449 if (expected_vals != expected_vals_q) {
3450 CFAllocatorDeallocate(NULL, expected_vals);
3451 }
3452 return success;
3453 }
3454
3455 static Boolean
3456 _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical (SCPreferencesRef configNetworkInterfacePref, SCPreferencesRef expectedNetworkInterfacePref)
3457 {
3458 CFDictionaryRef expectedInterfaceEntity = NULL;
3459 CFArrayRef expectedInterfaceList = NULL;
3460 CFIndex expectedInterfaceListCount;
3461 Boolean foundMatch = FALSE;
3462 CFDictionaryRef interfaceEntity = NULL;
3463 CFArrayRef interfaceList = NULL;
3464 CFIndex interfaceListCount;
3465 CFMutableArrayRef interfaceListMutable = NULL;
3466 Boolean success = FALSE;
3467
3468 interfaceList = SCPreferencesGetValue(configNetworkInterfacePref, INTERFACES);
3469 if (isA_CFArray(interfaceList) == NULL) {
3470 goto done;
3471 }
3472 interfaceListMutable = CFArrayCreateMutableCopy(NULL, 0, interfaceList);
3473 interfaceListCount = CFArrayGetCount(interfaceListMutable);
3474
3475 expectedInterfaceList = SCPreferencesGetValue(expectedNetworkInterfacePref, INTERFACES);
3476 if (isA_CFArray(expectedInterfaceList) == NULL) {
3477 goto done;
3478 }
3479 expectedInterfaceListCount = CFArrayGetCount(expectedInterfaceList);
3480
3481 if (interfaceListCount != expectedInterfaceListCount) {
3482 goto done;
3483 }
3484
3485 for (CFIndex idx = 0; idx < expectedInterfaceListCount; idx++) {
3486 foundMatch = FALSE;
3487 expectedInterfaceEntity = CFArrayGetValueAtIndex(expectedInterfaceList, idx);
3488 interfaceListCount = CFArrayGetCount(interfaceListMutable);
3489
3490 for (CFIndex idx2 = 0; idx2 < interfaceListCount; idx2++) {
3491 interfaceEntity = CFArrayGetValueAtIndex(interfaceList, idx2);
3492 if (CFEqual(expectedInterfaceEntity, interfaceEntity) == TRUE) {
3493 foundMatch = TRUE;
3494 break;
3495 }
3496 }
3497 if (foundMatch == FALSE) {
3498 break;
3499 }
3500 }
3501 success = foundMatch;
3502
3503 done:
3504 if (interfaceListMutable != NULL) {
3505 CFRelease(interfaceListMutable);
3506 }
3507
3508 return success;
3509 }
3510
3511 Boolean
3512 _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
3513 CFURLRef expectedConfigurationURL)
3514 {
3515 CFURLRef baseConfigURL = NULL;
3516 CFURLRef baseExpectedConfigURL = NULL;
3517 CFURLRef configPreferencesURL = NULL;
3518 CFURLRef configNetworkInterfacesURL = NULL;
3519 SCPreferencesRef configPref = NULL;
3520 SCPreferencesRef configNetworkInterfacePref = NULL;
3521 SCPreferencesRef expectedConfigPref = NULL;
3522 SCPreferencesRef expectedNetworkInterfacePref = NULL;
3523 CFURLRef expectedNetworkInterfaceURL = NULL;
3524 CFURLRef expectedPreferencesURL = NULL;
3525 Boolean isIdentical = FALSE;
3526 CFStringRef networkInterfaceConfigString = NULL;
3527 CFStringRef networkInterfaceExpectedString = NULL;
3528 CFStringRef prefsConfigString = NULL;
3529 CFStringRef prefsExpectedString = NULL;
3530 char networkInterfaceConfigStr[PATH_MAX];
3531 char networkInterfaceExpectedStr[PATH_MAX];
3532 char prefsConfigStr[PATH_MAX];
3533 char prefsExpectedStr[PATH_MAX];
3534
3535 if (configurationURL == NULL ||
3536 expectedConfigurationURL == NULL) {
3537 return FALSE;
3538 }
3539 baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, configurationURL);
3540 configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*) PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseConfigURL);
3541
3542 if (CFURLResourceIsReachable(configPreferencesURL, NULL) == FALSE) {
3543 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: preferences.plist file is not present."));
3544 goto done;
3545 }
3546
3547 configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseConfigURL);
3548
3549 if (CFURLResourceIsReachable(configNetworkInterfacesURL, NULL) == FALSE) {
3550 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: NetworkInterfaces.plist file is not present."));
3551 goto done;
3552 }
3553
3554 if (CFURLGetFileSystemRepresentation(configPreferencesURL, TRUE, (UInt8*)prefsConfigStr, sizeof(prefsConfigStr)) == FALSE) {
3555 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract preferences information"));
3556 goto done;
3557 }
3558 if (CFURLGetFileSystemRepresentation(configNetworkInterfacesURL, TRUE, (UInt8*)networkInterfaceConfigStr, sizeof(networkInterfaceConfigStr)) == FALSE) {
3559 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract network interfaces information"));
3560 goto done;
3561 }
3562
3563 baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, expectedConfigurationURL);
3564 expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseExpectedConfigURL);
3565
3566 if (CFURLResourceIsReachable(expectedPreferencesURL, NULL) == FALSE) {
3567 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: preferences.plist file is not present in the expected configuration."));
3568 goto done;
3569 }
3570
3571 expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseExpectedConfigURL);
3572
3573 if (CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL) == FALSE) {
3574 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: NetworkInterfaces.plist file is not present in the expected configuration."));
3575 goto done;
3576 }
3577
3578 if (CFURLGetFileSystemRepresentation(expectedPreferencesURL, TRUE, (UInt8*)prefsExpectedStr, sizeof(prefsExpectedStr)) == FALSE) {
3579 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract preferences information"));
3580 goto done;
3581 }
3582 if (CFURLGetFileSystemRepresentation(expectedNetworkInterfaceURL, TRUE, (UInt8*)networkInterfaceExpectedStr, sizeof(networkInterfaceExpectedStr)) == FALSE) {
3583 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract network interfaces information"));
3584 goto done;
3585 }
3586
3587 prefsConfigString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsConfigStr);
3588 networkInterfaceConfigString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceConfigStr);
3589 prefsExpectedString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsExpectedStr);
3590 networkInterfaceExpectedString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceExpectedStr);
3591
3592 configPref = SCPreferencesCreate(NULL, PLUGIN_ID, prefsConfigString);
3593 expectedConfigPref = SCPreferencesCreate(NULL, PLUGIN_ID, prefsExpectedString);
3594 configNetworkInterfacePref = SCPreferencesCreate(NULL, PLUGIN_ID, networkInterfaceConfigString);
3595 expectedNetworkInterfacePref = SCPreferencesCreate(NULL, PLUGIN_ID, networkInterfaceExpectedString);
3596 done:
3597 if (configPref == NULL ||
3598 expectedConfigPref == NULL ||
3599 configNetworkInterfacePref == NULL ||
3600 expectedNetworkInterfacePref == NULL) {
3601 SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: One of the preferences is NULL"));
3602 isIdentical = FALSE;
3603 }
3604 else {
3605 isIdentical = (_SCNetworkMigrationAreServicesIdentical(configPref, expectedConfigPref) &&
3606 _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical(configNetworkInterfacePref, expectedNetworkInterfacePref));
3607 }
3608 if (baseConfigURL != NULL) {
3609 CFRelease(baseConfigURL);
3610 }
3611 if (configPreferencesURL != NULL) {
3612 CFRelease(configPreferencesURL);
3613 }
3614 if (configNetworkInterfacesURL != NULL) {
3615 CFRelease(configNetworkInterfacesURL);
3616 }
3617 if (baseExpectedConfigURL != NULL) {
3618 CFRelease(baseExpectedConfigURL);
3619 }
3620 if (expectedPreferencesURL != NULL) {
3621 CFRelease(expectedPreferencesURL);
3622 }
3623 if (expectedNetworkInterfaceURL != NULL) {
3624 CFRelease(expectedNetworkInterfaceURL);
3625 }
3626 if (prefsConfigString != NULL) {
3627 CFRelease(prefsConfigString);
3628 }
3629 if (networkInterfaceConfigString != NULL) {
3630 CFRelease(networkInterfaceConfigString);
3631 }
3632 if (prefsExpectedString != NULL) {
3633 CFRelease(prefsExpectedString);
3634 }
3635 if (networkInterfaceExpectedString != NULL) {
3636 CFRelease(networkInterfaceExpectedString);
3637 }
3638 if (configPref != NULL) {
3639 CFRelease(configPref);
3640 }
3641 if (expectedConfigPref != NULL) {
3642 CFRelease(expectedConfigPref);
3643 }
3644 if (configNetworkInterfacePref != NULL) {
3645 CFRelease(configNetworkInterfacePref);
3646 }
3647 if (expectedNetworkInterfacePref != NULL) {
3648 CFRelease(expectedNetworkInterfacePref);
3649 }
3650 return isIdentical;
3651 }
3652
3653 CFArrayRef
3654 _SCNetworkConfigurationCopyMigrationRemovePaths (CFArrayRef targetPaths,
3655 CFURLRef targetDir)
3656 {
3657 CFURLRef affectedURL;
3658 char filePath[PATH_MAX];
3659 CFURLRef targetFile;
3660 CFMutableArrayRef toBeRemoved = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
3661
3662 for (CFIndex idx = 0; idx < CFArrayGetCount(targetPaths); idx++) {
3663 affectedURL = CFArrayGetValueAtIndex(targetPaths, idx);
3664
3665 if (CFURLGetFileSystemRepresentation(affectedURL, TRUE, (UInt8*)filePath, sizeof(filePath)) == FALSE) {
3666 SCLog(_sc_debug, LOG_NOTICE, CFSTR("filesToBeRemoved: Could not get file system representation"));
3667 continue;
3668 }
3669 targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)filePath,
3670 strnlen(filePath, sizeof(filePath)), FALSE, targetDir);
3671
3672 if (CFURLResourceIsReachable(targetFile, NULL) == FALSE) {
3673 CFArrayAppendValue(toBeRemoved, affectedURL);
3674 }
3675 CFRelease(targetFile);
3676 }
3677 // If number of files to be removed is 0, return NULL
3678 if (CFArrayGetCount(toBeRemoved) == 0) {
3679 CFRelease(toBeRemoved);
3680 toBeRemoved = NULL;
3681 }
3682 return toBeRemoved;
3683 }