2 * Copyright (c) 2014-2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 // SCNetworkMigration.c
27 // Created by Ashish Kulkarni on 11/19/13.
32 #include <CoreFoundation/CoreFoundation.h>
33 #include "SCNetworkConfigurationInternal.h"
34 #include "SCPreferencesInternal.h"
35 #include <IOKit/network/IONetworkInterface.h>
36 #include <IOKit/network/IONetworkController.h>
37 #if !TARGET_OS_SIMULATOR
38 #include <IOKit/usb/USB.h>
39 #endif // !TARGET_OS_SIMULATOR
42 #include <sys/param.h>
45 #define BACK_TO_MY_MAC CFSTR("BackToMyMac")
46 #define BACK_TO_MY_MAC_DSIDS CFSTR("BackToMyMacDSIDs")
47 #define NUM_MIGRATION_PATHS 2
48 #define PLUGIN_ID CFSTR("System Migration")
49 #define PREFERENCES_PLIST_INDEX 0
50 #define NETWORK_INTERFACES_PLIST_INDEX 1
52 #define kProtocolType CFSTR("Protocol Type")
53 #define kProtocolConfiguration CFSTR("Protocol Configuration")
54 #define kProtocolEnabled CFSTR("Protocol Enabled")
57 const CFStringRef kSCNetworkConfigurationMigrationActionKey
= CFSTR("MigrationActionKey");
58 const CFStringRef kSCNetworkConfigurationRepair
= CFSTR("ConfigurationRepair");
61 static CFDictionaryRef
62 _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs
);
64 static CFDictionaryRef
65 _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs
);
67 static CFDictionaryRef
68 _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs
);
69 #endif // !TARGET_OS_IPHONE
72 _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1
, SCNetworkInterfaceRef interface2
, Boolean bypassActive
);
75 _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir
, CFURLRef targetDir
);
78 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL
, CFURLRef
*prefs
, CFURLRef
*interfaces
)
80 if (baseURL
!= NULL
) {
83 baseURL
= CFURLCreateFromFileSystemRepresentation(NULL
,
84 (UInt8
*)PREFS_DEFAULT_DIR_PATH
,
85 sizeof(PREFS_DEFAULT_DIR_PATH
) - 1,
89 *prefs
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
90 (UInt8
*)PREFS_DEFAULT_CONFIG_PLIST
,
91 sizeof(PREFS_DEFAULT_CONFIG_PLIST
) - 1,
95 *interfaces
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
96 (UInt8
*)INTERFACES_DEFAULT_CONFIG_PLIST
,
97 sizeof(INTERFACES_DEFAULT_CONFIG_PLIST
) - 1,
105 _SCNetworkConfigurationCopyMigrationPaths(CFDictionaryRef options
)
107 #pragma unused(options)
109 CFMutableArrayRef migrationPaths
= NULL
;
112 migrationPaths
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
113 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(NULL
, &prefs
, &interfaces
);
114 CFArrayAppendValue(migrationPaths
, prefs
);
115 CFArrayAppendValue(migrationPaths
, interfaces
);
117 CFRelease(interfaces
);
119 return migrationPaths
;
123 _SCNetworkConfigurationRemoveConfigurationFiles(CFURLRef configDir
)
126 char configPathString
[PATH_MAX
];
127 CFURLRef configPathURL
= NULL
;
128 char configNetworkInterfacesPathString
[PATH_MAX
];
129 CFURLRef configNetworkInterfacesPathURL
= NULL
;
131 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir
, &configPathURL
, &configNetworkInterfacesPathURL
);
133 if(!CFURLGetFileSystemRepresentation(configPathURL
,
135 (UInt8
*)configPathString
,
136 sizeof(configPathString
))) {
137 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configPathURL
);
139 if ((remove(configPathString
) != 0) && (errno
!= ENOENT
)) {
140 SC_log(LOG_NOTICE
, "remove(\"%s\") failed: %s", configPathString
, strerror(errno
));
143 CFRelease(configPathURL
);
145 if(!CFURLGetFileSystemRepresentation(configNetworkInterfacesPathURL
,
147 (UInt8
*)configNetworkInterfacesPathString
,
148 sizeof(configNetworkInterfacesPathString
))) {
149 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configNetworkInterfacesPathURL
);
151 if ((remove(configNetworkInterfacesPathString
) != 0) && (errno
!= ENOENT
)) {
152 SC_log(LOG_NOTICE
, "remove(\"%s\") failed: %s", configNetworkInterfacesPathString
, strerror(errno
));
155 CFRelease(configNetworkInterfacesPathURL
);
161 SCNetworkConfigurationCopyConfigurationFiles(CFURLRef configDir
,
162 CFURLRef targetDir
) // TargetDir needs to exist
165 mode_t mode
= S_IRWXU
| S_IRGRP
| S_IXGRP
| S_IROTH
| S_IXOTH
;
166 char networkInterfacesPathString
[PATH_MAX
];
167 CFURLRef networkInterfacesPathURL
= NULL
;
168 copyfile_state_t networkInterfacesState
;
169 char preferencesPathString
[PATH_MAX
];
170 CFURLRef preferencesPathURL
= NULL
;
171 Boolean removeTargetFiles
= FALSE
;
172 copyfile_state_t state
;
173 Boolean success
= FALSE
;
174 char targetNetworkInterfacesPathString
[PATH_MAX
];
175 CFURLRef targetNetworkInterfacesPathURL
= NULL
;
176 char targetPathString
[PATH_MAX
];
177 CFURLRef targetPathURL
= NULL
;
179 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(targetDir
, &targetPathURL
, &targetNetworkInterfacesPathURL
);
181 if (!CFURLGetFileSystemRepresentation(targetPathURL
,
183 (UInt8
*)targetPathString
,
184 sizeof(targetPathString
))) {
185 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", targetPathURL
);
188 if (!CFURLGetFileSystemRepresentation(targetNetworkInterfacesPathURL
,
190 (UInt8
*)targetNetworkInterfacesPathString
,
191 sizeof(targetNetworkInterfacesPathString
))) {
192 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", targetNetworkInterfacesPathURL
);
196 if (configDir
== NULL
) {
197 removeTargetFiles
= TRUE
;
202 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir
, &preferencesPathURL
, &networkInterfacesPathURL
);
204 if (!CFURLGetFileSystemRepresentation(preferencesPathURL
,
206 (UInt8
*)preferencesPathString
,
207 sizeof(preferencesPathString
))) {
208 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", preferencesPathURL
);
211 if (!CFURLGetFileSystemRepresentation(networkInterfacesPathURL
,
213 (UInt8
*)networkInterfacesPathString
,
214 sizeof(networkInterfacesPathString
))) {
215 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", networkInterfacesPathURL
);
219 state
= copyfile_state_alloc();
220 error
= copyfile(preferencesPathString
, targetPathString
, state
, COPYFILE_ALL
);
222 SC_log(LOG_NOTICE
, "copyFile(\"%s\", \"%s\", ...) failed: %s",
223 preferencesPathString
,
226 copyfile_state_free(state
);
227 removeTargetFiles
= TRUE
;
230 copyfile_state_free(state
);
231 (void)chmod(targetPathString
, mode
);
233 networkInterfacesState
= copyfile_state_alloc();
234 error
= copyfile(networkInterfacesPathString
, targetNetworkInterfacesPathString
, networkInterfacesState
, COPYFILE_ALL
);
236 SC_log(LOG_NOTICE
, "copyFile(\"%s\", \"%s\", ...) failed: %s",
237 networkInterfacesPathString
,
238 targetNetworkInterfacesPathString
,
240 copyfile_state_free(networkInterfacesState
);
241 removeTargetFiles
= TRUE
;
244 copyfile_state_free(networkInterfacesState
);
245 (void)chmod(targetNetworkInterfacesPathString
, mode
);
249 if (removeTargetFiles
) {
250 _SCNetworkConfigurationRemoveConfigurationFiles(targetDir
);
252 if (preferencesPathURL
!= NULL
) {
253 CFRelease(preferencesPathURL
);
255 if (networkInterfacesPathURL
!= NULL
) {
256 CFRelease(networkInterfacesPathURL
);
258 if (targetPathURL
!= NULL
) {
259 CFRelease(targetPathURL
);
261 if (targetNetworkInterfacesPathURL
!= NULL
) {
262 CFRelease(targetNetworkInterfacesPathURL
);
268 /* -----------------------------------------------------------------------------
269 Create directories and intermediate directories as required.
270 ----------------------------------------------------------------------------- */
272 _SCNetworkConfigurationMakePathIfNeeded(CFURLRef pathURL
)
276 Boolean success
= FALSE
;
278 if (!CFURLGetFileSystemRepresentation(pathURL
, TRUE
, (UInt8
*)path
, sizeof(path
))) {
279 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", pathURL
);
283 SC_log(LOG_INFO
, "creating path: %s", path
);
287 c
++; // skip leading /
289 for(; !success
; c
++) {
290 if ((*c
== '/') || (*c
== '\0')){
296 if (mkdir(path
, (S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
)) != 0) {
297 if ((errno
!= EEXIST
) && (errno
!= EISDIR
)) {
298 SC_log(LOG_NOTICE
, "mkdir(%s) failed: %s", path
, strerror(errno
));
310 __SCNetworkPopulateDefaultPrefs(SCPreferencesRef prefs
)
312 SCNetworkSetRef currentSet
;
317 "Populating preferences.plist"
321 currentSet
= SCNetworkSetCopyCurrent(prefs
);
322 if (currentSet
== NULL
) {
323 currentSet
= _SCNetworkSetCreateDefault(prefs
);
325 SCNetworkSetEstablishDefaultConfiguration(currentSet
);
326 CFRelease(currentSet
);
328 model
= SCPreferencesGetValue(prefs
, MODEL
);
330 model
= _SC_hw_model(FALSE
);
331 SCPreferencesSetValue(prefs
, MODEL
, model
);
334 version
= SCPreferencesGetValue(prefs
, kSCPrefVersion
);
335 if (version
== NULL
) {
336 const int new_version
= NETWORK_CONFIGURATION_VERSION
;
338 version
= CFNumberCreate(NULL
, kCFNumberIntType
, &new_version
);
339 SCPreferencesSetValue(prefs
, kSCPrefVersion
, version
);
347 __SCNetworkPopulateDefaultNIPrefs(SCPreferencesRef ni_prefs
)
349 CFMutableArrayRef interfaces
= NULL
;
351 CFArrayRef networkInterfaces
;
352 CFComparisonResult res
;
355 interfaces
= (CFMutableArrayRef
)SCPreferencesGetValue(ni_prefs
, INTERFACES
);
356 if (isA_CFArray(interfaces
)) {
357 // if already populated
362 "Populating NetworkInterfaces.plist"
366 networkInterfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(TRUE
);
367 if (networkInterfaces
== NULL
) {
368 SC_log(LOG_NOTICE
, "Cannot populate NetworkInterfaces.plist, no network interfaces");
372 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
374 for (CFIndex idx
= 0; idx
< CFArrayGetCount(networkInterfaces
); idx
++) {
378 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(networkInterfaces
, idx
);
379 CFDictionaryRef interfaceEntity
;
381 interfaceEntity
= __SCNetworkInterfaceCopyStorageEntity(interface
);
382 if (interfaceEntity
== NULL
) {
386 if_type
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
387 if_unit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
388 if ((if_type
== NULL
) || (if_unit
== NULL
)) {
389 CFRelease(interfaceEntity
);
393 for (idx2
= 0; idx2
< CFArrayGetCount(interfaces
); idx2
++) {
396 CFDictionaryRef dict
= CFArrayGetValueAtIndex(interfaces
, idx2
);
398 db_type
= CFDictionaryGetValue(dict
, CFSTR(kIOInterfaceType
));
399 db_unit
= CFDictionaryGetValue(dict
, CFSTR(kIOInterfaceUnit
));
400 res
= CFNumberCompare(if_type
, db_type
, NULL
);
401 if (res
== kCFCompareLessThan
402 || (res
== kCFCompareEqualTo
403 && (CFNumberCompare(if_unit
, db_unit
, NULL
) == kCFCompareLessThan
))) {
408 CFArrayInsertValueAtIndex(interfaces
, idx2
, interfaceEntity
);
409 CFRelease(interfaceEntity
);
413 SCPreferencesSetValue(ni_prefs
, INTERFACES
, interfaces
);
414 CFRelease(interfaces
);
416 model
= SCPreferencesGetValue(ni_prefs
, MODEL
);
418 model
= _SC_hw_model(FALSE
);
419 SCPreferencesSetValue(ni_prefs
, MODEL
, model
);
422 version
= SCPreferencesGetValue(ni_prefs
, kSCPrefVersion
);
423 if (version
== NULL
) {
424 const int new_version
= NETWORK_CONFIGURATION_VERSION
;
426 version
= CFNumberCreate(NULL
, kCFNumberIntType
, &new_version
);
427 SCPreferencesSetValue(ni_prefs
, kSCPrefVersion
, version
);
431 CFRelease(networkInterfaces
);
438 * _SCNetworkConfigurationPerformMigration will migrate configuration between source and destination systems
442 _SCNetworkConfigurationPerformMigration(CFURLRef sourceDir
, CFURLRef currentDir
, CFURLRef targetDir
, CFDictionaryRef options
)
444 #pragma unused(options)
445 CFURLRef currentDirConfig
= NULL
;
446 CFURLRef currentSystemPath
= NULL
;
447 Boolean migrationComplete
= FALSE
;
448 CFArrayRef paths
= NULL
;
449 Boolean removeTargetOnFailure
= FALSE
;
450 CFURLRef sourceDirConfig
= NULL
;
451 CFURLRef targetDirConfig
= NULL
;
454 "Perform Migration%s"
459 _SC_isInstallEnvironment() ? " (INSTALLER ENVIRONMENT)" : "",
463 options
!= NULL
? options
: (CFDictionaryRef
)CFSTR("None"));
465 if ((sourceDir
!= NULL
) && !CFURLHasDirectoryPath(sourceDir
)) {
466 SC_log(LOG_NOTICE
, "Migration source is not a directory: %@", sourceDir
);
470 if ((currentDir
!= NULL
) && !CFURLHasDirectoryPath(currentDir
)) {
471 SC_log(LOG_NOTICE
, "Migration current is not a directory: %@", currentDir
);
475 if ((targetDir
!= NULL
) && !CFURLHasDirectoryPath(targetDir
)) {
476 SC_log(LOG_NOTICE
, "Migration target is not a directory: %@", targetDir
);
480 // Both sourceDir and currentDir cannot be NULL because NULL value indicates using current system
481 if (sourceDir
== NULL
&& currentDir
== NULL
) {
482 SC_log(LOG_NOTICE
, "Both migration source and current are NULL");
486 currentSystemPath
= CFURLCreateWithString(NULL
,
490 // if either of the sourceDir or currentDir are NULL, then populate it with current system path
491 if (sourceDir
== NULL
) {
492 sourceDirConfig
= CFRetain(currentSystemPath
);
494 sourceDirConfig
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
495 PREFS_DEFAULT_DIR_RELATIVE
,
496 kCFURLPOSIXPathStyle
,
501 if (currentDir
!= NULL
) {
502 currentDirConfig
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
503 PREFS_DEFAULT_DIR_RELATIVE
,
504 kCFURLPOSIXPathStyle
,
508 // If the targetDir is not provided then migration will take place in currentDir
509 if (targetDir
== NULL
) {
510 targetDirConfig
= CFRetain(currentSystemPath
);
512 targetDirConfig
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
513 PREFS_DEFAULT_DIR_RELATIVE
,
514 kCFURLPOSIXPathStyle
,
518 // Source directory cannot be the same as target directory
519 if (CFEqual(sourceDirConfig
, targetDirConfig
)) {
520 SC_log(LOG_NOTICE
, "Source directory cannot be the same as target directory");
524 if ((currentDirConfig
== NULL
) || !CFEqual(currentDirConfig
, targetDirConfig
)) {
525 if (!_SCNetworkConfigurationMakePathIfNeeded(targetDirConfig
)) {
526 SC_log(LOG_NOTICE
, "Could not create target directory");
530 if (!SCNetworkConfigurationCopyConfigurationFiles(currentDirConfig
, targetDirConfig
)) {
531 SC_log(LOG_NOTICE
, "Could not copy configuration files from \"%@\" to \"%@\"",
534 } else if (currentDirConfig
!= NULL
) {
535 removeTargetOnFailure
= TRUE
; // Configuration files were copied over to target directory
536 // If migration failed, then we should remove those configuration
537 // files since current directory and target directory are not
542 // If both source and current configurations point to current system, then no migration needs to be done.
543 if ((currentDirConfig
!= NULL
) && CFEqual(sourceDirConfig
, currentDirConfig
)) {
544 SC_log(LOG_NOTICE
, "No migration needed, source and current configurations have the same path");
545 migrationComplete
= TRUE
;
547 migrationComplete
= _SCNetworkConfigurationMigrateConfiguration(sourceDirConfig
, targetDirConfig
);
549 if (migrationComplete
) {
550 SC_log(LOG_NOTICE
, "Migration complete");
551 paths
= _SCNetworkConfigurationCopyMigrationPaths(NULL
);
553 SC_log(LOG_NOTICE
, "Migration failed: %s", SCErrorString(SCError()));
555 // If migration fails, then remove configuration files from target config if they were
556 // copied from the current directory
557 if (removeTargetOnFailure
) {
558 _SCNetworkConfigurationRemoveConfigurationFiles(targetDirConfig
);
562 if (currentDirConfig
!= NULL
) {
563 CFRelease(currentDirConfig
);
565 if (currentSystemPath
!= NULL
) {
566 CFRelease(currentSystemPath
);
568 if (sourceDirConfig
!= NULL
) {
569 CFRelease(sourceDirConfig
);
571 if (targetDirConfig
!= NULL
) {
572 CFRelease(targetDirConfig
);
579 _SCNetworkConfigurationMigrateIsFilePresent(CFURLRef filePath
)
581 Boolean fileExists
= false;
582 char filePathStr
[PATH_MAX
];
584 struct stat statStruct
= { 0, };
586 if (filePath
== NULL
) {
587 SC_log(LOG_NOTICE
, "_SCNetworkConfigurationMigrateIsFilePresent: No path");
591 if (!CFURLGetFileSystemRepresentation(filePath
, TRUE
, (UInt8
*) filePathStr
, sizeof(filePathStr
))) {
592 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", filePath
);
596 statResult
= stat(filePathStr
, &statStruct
);
597 if (statResult
== 0) {
598 SCPreferencesRef prefs
;
601 if (statStruct
.st_size
== 0) {
602 SC_log(LOG_INFO
, "_SCNetworkConfigurationMigrateIsFilePresent: empty .plist: %@", filePath
); // REMOVE
606 prefsID
= CFStringCreateWithCString(NULL
, filePathStr
, kCFStringEncodingUTF8
);
607 prefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, prefsID
);
610 SC_log(LOG_NOTICE
, "_SCNetworkConfigurationMigrateIsFilePresent: bad .plist: %@", filePath
);
614 if (!__SCPreferencesIsEmpty(prefs
)) {
615 // if non-empty .plist
618 SC_log(LOG_NOTICE
, "_SCNetworkConfigurationMigrateIsFilePresent: effectively empty .plist: %@", filePath
);
628 __SCNetworkConfigurationMigrateConfigurationFilesPresent(CFURLRef baseURL
, CFArrayRef
* migrationPaths
, Boolean expected
)
630 Boolean configFilesPresent
= FALSE
;
632 CFURLRef filePath
= NULL
;
634 CFMutableArrayRef migrationPathsMutable
= NULL
;
637 if (baseURL
== NULL
) {
638 SC_log(LOG_NOTICE
, "No base migration URL");
642 migrationPathsMutable
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
643 _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(baseURL
, &prefs
, &interfaces
);
644 CFArrayAppendValue(migrationPathsMutable
, prefs
);
645 CFArrayAppendValue(migrationPathsMutable
, interfaces
);
647 CFRelease(interfaces
);
649 *migrationPaths
= migrationPathsMutable
;
651 count
= CFArrayGetCount(*migrationPaths
);
652 for (CFIndex idx
= 0; idx
< count
; idx
++) {
655 filePath
= CFArrayGetValueAtIndex(*migrationPaths
, idx
);
656 present
= _SCNetworkConfigurationMigrateIsFilePresent(filePath
);
659 SC_log(LOG_INFO
, "Expected migration file not present: %@", filePath
);
665 configFilesPresent
= TRUE
; // all necessary configuration files present
667 return configFilesPresent
;
671 static CFMutableArrayRef
672 _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(SCPreferencesRef ni_prefs
, Boolean isBuiltin
)
675 SCNetworkInterfaceRef interface
;
676 CFArrayRef interfaceList
= NULL
;
677 SCPreferencesRef prefs
= NULL
;
678 CFMutableArrayRef resultInterfaceList
= NULL
;
680 interfaceList
= __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs
);
681 if (interfaceList
== NULL
) {
685 count
= CFArrayGetCount(interfaceList
);
687 resultInterfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
688 prefs
= SCPreferencesCreateCompanion(ni_prefs
, NULL
);
691 for (CFIndex i
= 0; i
< count
; i
++) {
692 interface
= CFArrayGetValueAtIndex(interfaceList
, i
);
693 if (_SCNetworkInterfaceIsBuiltin(interface
) == isBuiltin
) {
694 SCNetworkInterfacePrivateRef newInterface
;
696 newInterface
= __SCNetworkInterfaceCreateCopy(NULL
, interface
, prefs
, NULL
);
697 CFArrayAppendValue(resultInterfaceList
, newInterface
);
698 CFRelease(newInterface
);
703 if (interfaceList
!= NULL
) {
704 CFRelease(interfaceList
);
709 return resultInterfaceList
;
712 static CFMutableDictionaryRef
713 _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs
)
715 CFNumberRef cfMaxUnit
;
717 CFArrayRef ifList
= NULL
;
718 SCNetworkInterfaceRef interface
;
719 CFMutableDictionaryRef interfaceTypeToMaxUnitMapping
= NULL
;
723 ifList
= __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs
);
724 if (ifList
== NULL
) {
725 SC_log(LOG_INFO
, "No interfaces");
729 interfaceTypeToMaxUnitMapping
= CFDictionaryCreateMutable(NULL
, 0,
730 &kCFTypeDictionaryKeyCallBacks
,
731 &kCFTypeDictionaryValueCallBacks
);
732 count
= CFArrayGetCount(ifList
);
733 for (CFIndex idx
= 0; idx
< count
; idx
++) {
735 interface
= CFArrayGetValueAtIndex(ifList
, idx
);
737 if (!isA_SCNetworkInterface(interface
)) {
741 type
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
742 if (!isA_CFNumber(type
)) {
743 SC_log(LOG_INFO
, "No interface type");
747 if (!CFDictionaryContainsKey(interfaceTypeToMaxUnitMapping
, type
)) {
749 cfMaxUnit
= CFNumberCreate(NULL
, kCFNumberIntType
, &temp
);
750 CFDictionaryAddValue(interfaceTypeToMaxUnitMapping
, type
, cfMaxUnit
);
751 CFRelease(cfMaxUnit
);
754 if (cfMaxUnit
== NULL
) {
755 cfMaxUnit
= CFDictionaryGetValue(interfaceTypeToMaxUnitMapping
, type
);
758 unit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
759 if (!isA_CFNumber(unit
)) {
763 if (CFNumberCompare(unit
, cfMaxUnit
, NULL
) == kCFCompareGreaterThan
) {
764 CFDictionarySetValue(interfaceTypeToMaxUnitMapping
, type
, unit
);
767 if (ifList
!= NULL
) {
770 return interfaceTypeToMaxUnitMapping
;
773 static CFMutableDictionaryRef
774 _SCNetworkConfigurationCopyBuiltinMapping (SCPreferencesRef sourcePrefs
, SCPreferencesRef targetPrefs
)
776 CFMutableDictionaryRef builtinMapping
= NULL
;
777 CFIndex sourceBuiltinInterfaceCount
= 0;
778 CFMutableArrayRef sourceBuiltinInterfaces
= NULL
;
779 SCNetworkInterfaceRef sourceInterface
;
780 CFIndex targetBuiltinInterfaceCount
= 0;
781 CFMutableArrayRef targetBuiltinInterfaces
= NULL
;
782 SCNetworkInterfaceRef targetInterface
;
784 sourceBuiltinInterfaces
= _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePrefs
, TRUE
);
785 if (!isA_CFArray(sourceBuiltinInterfaces
)) {
786 SC_log(LOG_INFO
, "No source built-in interfaces");
789 sourceBuiltinInterfaceCount
= CFArrayGetCount(sourceBuiltinInterfaces
);
791 targetBuiltinInterfaces
= _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs
, TRUE
);
792 if (!isA_CFArray(targetBuiltinInterfaces
)) {
793 SC_log(LOG_INFO
, "No target built-in interfaces");
797 // Builtin Mapping will try to map all source interfaces into target interfaces
798 for (CFIndex idx
= 0; idx
< sourceBuiltinInterfaceCount
; idx
++) {
799 Boolean matched
= FALSE
;
801 sourceInterface
= CFArrayGetValueAtIndex(sourceBuiltinInterfaces
, idx
);
802 targetBuiltinInterfaceCount
= CFArrayGetCount(targetBuiltinInterfaces
);
804 for (CFIndex idx2
= 0; idx2
< targetBuiltinInterfaceCount
; idx2
++) {
805 CFDataRef sourceHardwareAddress
;
806 CFDataRef targetHardwareAddress
;
808 targetInterface
= CFArrayGetValueAtIndex(targetBuiltinInterfaces
, idx2
);
809 sourceHardwareAddress
= _SCNetworkInterfaceGetHardwareAddress(sourceInterface
);
810 targetHardwareAddress
= _SCNetworkInterfaceGetHardwareAddress(targetInterface
);
811 if (_SC_CFEqual(sourceHardwareAddress
, targetHardwareAddress
)) {
812 if (builtinMapping
== NULL
) {
813 builtinMapping
= CFDictionaryCreateMutable(NULL
, 0,
814 &kCFTypeDictionaryKeyCallBacks
,
815 &kCFTypeDictionaryValueCallBacks
);
817 CFDictionaryAddValue(builtinMapping
, sourceInterface
, targetInterface
);
818 CFArrayRemoveValueAtIndex(targetBuiltinInterfaces
, idx2
);
824 // proceed to next source interface
828 for (CFIndex idx2
= 0; idx2
< targetBuiltinInterfaceCount
; idx2
++) {
829 targetInterface
= CFArrayGetValueAtIndex(targetBuiltinInterfaces
, idx2
);
831 if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface
, targetInterface
, FALSE
)) {
832 if (builtinMapping
== NULL
) {
833 builtinMapping
= CFDictionaryCreateMutable(NULL
, 0,
834 &kCFTypeDictionaryKeyCallBacks
,
835 &kCFTypeDictionaryValueCallBacks
);
837 CFDictionaryAddValue(builtinMapping
, sourceInterface
, targetInterface
);
838 CFArrayRemoveValueAtIndex(targetBuiltinInterfaces
, idx2
);
845 if (sourceBuiltinInterfaces
!= NULL
) {
846 CFRelease(sourceBuiltinInterfaces
);
848 if (targetBuiltinInterfaces
!= NULL
) {
849 CFRelease(targetBuiltinInterfaces
);
851 return builtinMapping
;
855 isExcludedExternalInterface(SCNetworkInterfaceRef interface
)
857 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
858 #if !TARGET_OS_SIMULATOR
860 #endif // !TARGET_OS_SIMULATOR
862 if (_SCNetworkInterfaceIsHiddenInterface(interface
)) {
866 #if !TARGET_OS_SIMULATOR
867 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
868 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) ||
869 (vid
!= kIOUSBAppleVendorID
)) {
870 // if not "Apple" interface
873 #endif // !TARGET_OS_SIMULATOR
875 if (_SC_CFEqual(interfacePrivate
->name
, CFSTR("iBridge"))) {
876 // exclude "Apple T2 Controller"
883 static CFMutableDictionaryRef
884 _SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourceNIPrefs
, SCPreferencesRef targetNIPrefs
)
886 CFNumberRef cfMaxTargetUnit
= NULL
;
887 CFNumberRef currentInterfaceUnit
= NULL
;
888 CFMutableDictionaryRef externalMapping
= NULL
;
889 CFMutableDictionaryRef interfaceTypeToMaxUnitMapping
= NULL
;
892 CFIndex sourceExternalInterfaceCount
= 0;
893 CFMutableArrayRef sourceExternalInterfaces
= NULL
;
894 SCNetworkInterfaceRef sourceInterface
= NULL
;
895 CFIndex targetExternalInterfaceCount
= 0;
896 CFMutableArrayRef targetExternalInterfaces
= NULL
;
897 SCNetworkInterfaceRef targetInterface
= NULL
;
898 SCPreferencesRef targetPrefs
= NULL
;
901 sourceExternalInterfaces
= _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourceNIPrefs
, FALSE
);
902 if (!isA_CFArray(sourceExternalInterfaces
)) {
903 SC_log(LOG_INFO
, "No source external interfaces");
906 sourceExternalInterfaceCount
= CFArrayGetCount(sourceExternalInterfaces
);
907 if (sourceExternalInterfaceCount
== 0) {
908 SC_log(LOG_INFO
, "No source external interfaces");
912 targetExternalInterfaces
= _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetNIPrefs
, FALSE
);
913 if (!isA_CFArray(targetExternalInterfaces
)) {
914 SC_log(LOG_INFO
, "No target external interfaces");
918 interfaceTypeToMaxUnitMapping
= _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(targetNIPrefs
);
919 externalMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
920 targetPrefs
= SCPreferencesCreateCompanion(targetNIPrefs
, NULL
);
922 // Map all external interfaces which exist in both source and target
923 for (CFIndex idx
= 0; idx
< sourceExternalInterfaceCount
; idx
++) {
924 Boolean matched
= FALSE
;
926 sourceInterface
= CFArrayGetValueAtIndex(sourceExternalInterfaces
, idx
);
927 targetExternalInterfaceCount
= CFArrayGetCount(targetExternalInterfaces
);
928 currentInterfaceUnit
= NULL
;
930 for (CFIndex idx2
= 0; idx2
< targetExternalInterfaceCount
; idx2
++) {
931 CFDataRef sourceHardwareAddress
;
932 CFDataRef targetHardwareAddress
;
934 targetInterface
= CFArrayGetValueAtIndex(targetExternalInterfaces
, idx2
);
935 sourceHardwareAddress
= _SCNetworkInterfaceGetHardwareAddress(sourceInterface
);
936 targetHardwareAddress
= _SCNetworkInterfaceGetHardwareAddress(targetInterface
);
937 if (_SC_CFEqual(sourceHardwareAddress
, targetHardwareAddress
)) {
938 CFDictionaryAddValue(externalMapping
, sourceInterface
, targetInterface
);
939 CFArrayRemoveValueAtIndex(targetExternalInterfaces
, idx2
);
945 // proceed to next source interface
949 for (CFIndex idx2
= 0; idx2
< targetExternalInterfaceCount
; idx2
++) {
950 targetInterface
= CFArrayGetValueAtIndex(targetExternalInterfaces
, idx2
);
952 if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface
, targetInterface
, TRUE
)) {
953 CFDictionaryAddValue(externalMapping
, sourceInterface
, targetInterface
);
954 CFArrayRemoveValueAtIndex(targetExternalInterfaces
, idx2
);
960 // proceed to next source interface
964 // Before we create mapping for external source interfaces that do not exist
965 // in the target we need check for and handle some exclusions.
966 if (isExcludedExternalInterface(sourceInterface
)) {
971 // Create new mappings for external source interfaces which don't exist in the target
972 type
= _SCNetworkInterfaceGetIOInterfaceType(sourceInterface
);
974 cfMaxTargetUnit
= CFDictionaryGetValue(interfaceTypeToMaxUnitMapping
, type
);
975 if (cfMaxTargetUnit
!= NULL
) {
976 CFNumberGetValue(cfMaxTargetUnit
, kCFNumberIntType
, &maxTargetUnit
);
977 newTargetUnit
= maxTargetUnit
+ 1;
982 cfMaxTargetUnit
= CFNumberCreate(NULL
, kCFNumberIntType
, &newTargetUnit
);
983 CFDictionarySetValue(interfaceTypeToMaxUnitMapping
, type
, cfMaxTargetUnit
);
985 targetInterface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
,
990 currentInterfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(targetInterface
);
991 if (!isA_CFNumber(currentInterfaceUnit
) ||
992 !CFEqual(currentInterfaceUnit
, cfMaxTargetUnit
)) {
993 // Update the interface unit
994 __SCNetworkInterfaceSetIOInterfaceUnit(targetInterface
, cfMaxTargetUnit
);
997 CFDictionaryAddValue(externalMapping
, sourceInterface
, targetInterface
);
999 CFRelease(targetInterface
);
1000 targetInterface
= NULL
;
1001 CFRelease(cfMaxTargetUnit
);
1002 cfMaxTargetUnit
= NULL
;
1006 if (sourceExternalInterfaces
!= NULL
) {
1007 CFRelease(sourceExternalInterfaces
);
1009 if (targetExternalInterfaces
!= NULL
) {
1010 CFRelease(targetExternalInterfaces
);
1012 if (interfaceTypeToMaxUnitMapping
!= NULL
) {
1013 CFRelease(interfaceTypeToMaxUnitMapping
);
1015 if (targetPrefs
!= NULL
) {
1016 CFRelease(targetPrefs
);
1018 return externalMapping
;
1021 __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1
, CFStringRef interfaceName2
);
1024 _SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1
, SCNetworkInterfaceRef interface2
, Boolean bypassActive
)
1026 #pragma unused(bypassActive)
1027 Boolean interface1IsBuiltin
;
1028 CFStringRef interface1Prefix
;
1029 CFStringRef interface1Type
;
1030 CFStringRef interface1UserDefinedName
;
1031 Boolean interface2IsBuiltin
;
1032 CFStringRef interface2Prefix
;
1033 CFStringRef interface2Type
;
1034 CFStringRef interface2UserDefinedName
;
1036 if (interface1
== interface2
) {
1037 // No work needs to be done
1040 interface1IsBuiltin
= _SCNetworkInterfaceIsBuiltin(interface1
);
1041 interface2IsBuiltin
= _SCNetworkInterfaceIsBuiltin(interface2
);
1043 interface1UserDefinedName
= SCNetworkInterfaceGetLocalizedDisplayName(interface1
);
1044 interface2UserDefinedName
= SCNetworkInterfaceGetLocalizedDisplayName(interface2
);
1046 interface1Type
= SCNetworkInterfaceGetInterfaceType(interface1
);
1047 interface2Type
= SCNetworkInterfaceGetInterfaceType(interface2
);
1049 interface1Prefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface1
);
1050 interface2Prefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface2
);
1052 // Check if have same builtin values.
1053 // Check if User Defined name matches
1054 // Check if SCNetwork Interface Type matches
1056 if (interface1IsBuiltin
!= interface2IsBuiltin
) {
1060 if (!_SC_CFEqual(interface1Type
, interface2Type
)) {
1064 if (!_SC_CFEqual(interface1Prefix
, interface2Prefix
)) {
1068 if (!_SC_CFEqual(interface1UserDefinedName
, interface2UserDefinedName
)) {
1069 // Checking if we have a mismatch because of the name Ethernet and Ethernet 1
1070 // Checking if we have a mismatch because of the name Airport and WiFi
1071 if (interface1IsBuiltin
&&
1072 interface2IsBuiltin
&&
1073 __SCNetworkConfigurationInterfaceNameIsEquiv(interface1UserDefinedName
, interface2UserDefinedName
)) {
1082 __SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1
, CFStringRef interfaceName2
)
1084 CFStringRef interfaceArray
[] = { CFSTR("iPhone"), CFSTR("iPad"), CFSTR("iPod"), CFSTR("AppleTV") };
1085 const int interfaceCount
= sizeof(interfaceArray
) / sizeof(CFStringRef
);
1086 CFStringRef portSuffix
= CFSTR(", Port 1");
1088 if ((isA_CFString(interfaceName1
)) && (isA_CFString(interfaceName2
))) {
1089 if (!CFEqual(interfaceName1
, interfaceName2
)) {
1090 // Check if we are looking at the WiFi interface
1091 if ((CFEqual(interfaceName1
, CFSTR("AirPort")) ||
1092 (CFEqual(interfaceName1
, CFSTR("Wi-Fi")))) &&
1093 (CFEqual(interfaceName2
, CFSTR("AirPort")) ||
1094 (CFEqual(interfaceName2
, CFSTR("Wi-Fi"))))) {
1098 if (((CFEqual(interfaceName1
, CFSTR("Ethernet"))) ||
1099 (CFEqual(interfaceName1
, CFSTR("Ethernet 1")))) &&
1100 ((CFEqual(interfaceName2
, CFSTR("Ethernet"))) ||
1101 (CFEqual(interfaceName2
, CFSTR("Ethernet 1"))))) {
1105 if ((CFStringHasSuffix(interfaceName1
, portSuffix
) &&
1106 (CFStringCompareWithOptions(interfaceName1
, interfaceName2
, CFRangeMake(0, (CFStringGetLength(interfaceName1
) - CFStringGetLength(portSuffix
))), 0) == kCFCompareEqualTo
)) ||
1107 (CFStringHasSuffix(interfaceName2
, portSuffix
) &&
1108 (CFStringCompareWithOptions(interfaceName2
, interfaceName1
, CFRangeMake(0, (CFStringGetLength(interfaceName2
) - CFStringGetLength(portSuffix
))), 0) == kCFCompareEqualTo
))) {
1112 for (CFIndex idx
= 0; idx
< interfaceCount
; idx
++) {
1113 CFStringRef tempInterfaceName
= interfaceArray
[idx
];
1114 if ((CFEqual(interfaceName1
, tempInterfaceName
) ||
1115 __SCNetworkInterfaceMatchesName(interfaceName1
, tempInterfaceName
)) &&
1116 (CFEqual(interfaceName2
, tempInterfaceName
) ||
1117 __SCNetworkInterfaceMatchesName(interfaceName2
, tempInterfaceName
))) {
1130 CFDictionaryRef interfaceMapping
;
1131 CFMutableArrayRef interfacesMissingServices
;
1132 } missingServiceContext
;
1135 CFDictionaryRef bsdNameToBridgeServices
; // Mapping of BSD Name to SCBridgeInterfaceRef
1136 CFDictionaryRef bsdNameToBondServices
; // Mapping of BSD Name to SCBondInterfaceRef
1137 CFDictionaryRef bsdNameToVLANServices
; // Mapping of BSD Name to SCVLANInterfaceRef
1138 CFDictionaryRef interfaceMapping
;
1140 CFMutableArrayRef interfaceToBeRemoved
; // SCNetworkInterfaceRef. Services containing the interface will be removed
1141 CFMutableArrayRef interfaceToBeReplaced
; // SCNetworkInterfaceRef. Services containing the interface will be replaced with default service
1142 CFMutableArrayRef interfacePreserveServiceInformation
; // SCNetworkInterfaceRef. Services containing the interface will be replaced with new service which has same configuration as the current service with issue.
1143 CFMutableDictionaryRef bsdNameServiceProtocolPreserveMapping
;
1144 SCPreferencesRef prefs
;
1149 _SCNetworkConfigurationValidateInterface (const void *key
, const void *value
, void *context
)
1151 CFStringRef bsdName
= (CFStringRef
)key
;
1152 validityContext
*ctx
= (validityContext
*)context
;
1153 CFDictionaryRef bsdNameToBridgeServices
= ctx
->bsdNameToBridgeServices
;
1154 CFDictionaryRef bsdNameToBondServices
= ctx
->bsdNameToBondServices
;
1155 CFDictionaryRef bsdNameToVLANServices
= ctx
->bsdNameToVLANServices
;
1156 SCNetworkInterfaceRef interface
= NULL
;
1157 CFDictionaryRef interfaceMapping
= ctx
->interfaceMapping
;
1158 CFStringRef interfaceUserDefinedName
= NULL
;
1159 Boolean repair
= ctx
->repair
;
1160 SCNetworkInterfaceRef serviceInterface
= (SCNetworkInterfaceRef
)value
;
1161 CFStringRef serviceInterfaceUserDefinedName
= NULL
;
1162 CFMutableArrayRef interfaceToBeRemoved
= ctx
->interfaceToBeRemoved
;
1163 CFMutableArrayRef interfaceToBeReplaced
= ctx
->interfaceToBeReplaced
;
1164 CFMutableArrayRef interfacePreserveServiceInformation
= ctx
->interfacePreserveServiceInformation
;
1166 // No work needs to be done if we have already made determination that configuration somewhere is not valid,
1167 // or we don't intend to repair invalid configuration.
1168 if ((*ctx
->isValid
== FALSE
) && !repair
) {
1172 // There is no interface present for the service
1173 interface
= CFDictionaryGetValue(interfaceMapping
, bsdName
);
1174 if (interface
== NULL
) {
1175 if (_SCNetworkInterfaceIsBluetoothPAN(serviceInterface
)) {
1176 // interface not expected, BT-PAN
1180 if (((bsdNameToBridgeServices
!= NULL
) && !CFDictionaryContainsKey(bsdNameToBridgeServices
, bsdName
)) &&
1181 ((bsdNameToBondServices
!= NULL
) && !CFDictionaryContainsKey(bsdNameToBondServices
, bsdName
)) &&
1182 ((bsdNameToVLANServices
!= NULL
) && !CFDictionaryContainsKey(bsdNameToVLANServices
, bsdName
))) {
1183 // Not a virtual interface
1185 "No interface with BSD name (%@) present for service",
1189 CFArrayAppendValue(interfaceToBeRemoved
, serviceInterface
);
1191 *ctx
->isValid
= FALSE
;
1196 // Need to compare between both SCNetworkInterfaceRefs
1197 interfaceUserDefinedName
= __SCNetworkInterfaceGetUserDefinedName(interface
);
1198 serviceInterfaceUserDefinedName
= __SCNetworkInterfaceGetUserDefinedName(serviceInterface
);
1200 if (!__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName
, serviceInterfaceUserDefinedName
)) {
1202 "Interface user defined name (%@) doesn't match service/interface user defined name: %@",
1203 interfaceUserDefinedName
,
1204 serviceInterfaceUserDefinedName
);
1205 *ctx
->isValid
= FALSE
;
1206 // Check if the service interface name is set to localized key
1207 if (isA_CFArray(interfacePreserveServiceInformation
) != NULL
&&
1208 __SCNetworkInterfaceMatchesName(interfaceUserDefinedName
, serviceInterfaceUserDefinedName
)) {
1210 "serviceInterfaceUserDefinedName: %@ is the localized key for interface name: %@",
1211 serviceInterfaceUserDefinedName
,
1212 interfaceUserDefinedName
);
1213 CFArrayAppendValue(interfacePreserveServiceInformation
, serviceInterface
);
1215 // Add service interface to the interfaceToBeReplaced list
1216 if (isA_CFArray(interfaceToBeReplaced
) != NULL
) {
1217 CFArrayAppendValue(interfaceToBeReplaced
, interface
);
1219 if (isA_CFArray(interfaceToBeRemoved
) != NULL
) {
1220 CFArrayAppendValue(interfaceToBeRemoved
, serviceInterface
);
1227 _SCNetworkConfigurationCollectMissingService(const void *key
, const void *value
, void *context
)
1229 CFStringRef bsdName
= (CFStringRef
)key
;
1230 missingServiceContext
*ctx
= (missingServiceContext
*)context
;
1231 SCNetworkInterfaceRef interface
= (SCNetworkInterfaceRef
)value
;
1232 CFMutableArrayRef interfacesMissingServices
= ctx
->interfacesMissingServices
;
1233 CFDictionaryRef serviceInterfaceMapping
= ctx
->interfaceMapping
;
1235 if (!isA_SCNetworkInterface(interface
) ||
1236 !_SCNetworkInterfaceIsBuiltin(interface
)) {
1240 // Check if services have mapping for the BSD name of the interface
1241 if (!CFDictionaryContainsKey(serviceInterfaceMapping
, bsdName
)) {
1242 CFArrayAppendValue(interfacesMissingServices
, interface
); // Adding interface since the corresponding service seems to be missing
1247 _SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref
,
1248 SCPreferencesRef ni_pref
)
1250 missingServiceContext context
;
1251 SCNetworkInterfaceRef interface
= NULL
;
1252 CFArrayRef interfaces
= NULL
;
1253 CFMutableArrayRef interfacesWithoutService
= NULL
;
1254 CFDictionaryRef mappingBSDNameToInterface
= NULL
;
1255 CFDictionaryRef mappingServiceBSDNameToInterface
= NULL
;
1256 CFIndex missingServiceCount
= 0;
1257 Boolean success
= FALSE
;
1259 interfaces
= __SCNetworkInterfaceCopyStoredWithPreferences(ni_pref
);
1260 if (interfaces
== NULL
) {
1261 SC_log(LOG_NOTICE
, "No interfaces");
1265 mappingBSDNameToInterface
= __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces
);
1266 CFRelease(interfaces
);
1267 if (!isA_CFDictionary(mappingBSDNameToInterface
)) {
1271 interfaces
= __SCNetworkServiceCopyAllInterfaces(pref
);
1272 if (interfaces
== NULL
) {
1273 SC_log(LOG_NOTICE
, "No [service] interfaces");
1276 mappingServiceBSDNameToInterface
= __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces
);
1277 CFRelease(interfaces
);
1278 if (!isA_CFDictionary(mappingServiceBSDNameToInterface
)) {
1282 interfacesWithoutService
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1284 context
.interfaceMapping
= mappingServiceBSDNameToInterface
;
1285 context
.interfacesMissingServices
= interfacesWithoutService
;
1287 CFDictionaryApplyFunction(mappingBSDNameToInterface
, _SCNetworkConfigurationCollectMissingService
, &context
);
1288 missingServiceCount
= CFArrayGetCount(interfacesWithoutService
);
1292 for (CFIndex idx
= 0; idx
< missingServiceCount
; idx
++) {
1293 interface
= CFArrayGetValueAtIndex(interfacesWithoutService
, idx
);
1295 if (__SCNetworkInterfaceIsMember(pref
, interface
)) {
1296 // if the interface is a member of a bond or bridge
1300 if (!__SCNetworkServiceCreate(pref
, interface
, NULL
)) {
1301 SC_log(LOG_NOTICE
, "Could not create service for interface: %@", interface
);
1306 if (mappingBSDNameToInterface
!= NULL
) {
1307 CFRelease(mappingBSDNameToInterface
);
1309 if (mappingServiceBSDNameToInterface
!= NULL
) {
1310 CFRelease(mappingServiceBSDNameToInterface
);
1312 if (interfacesWithoutService
!= NULL
) {
1313 CFRelease(interfacesWithoutService
);
1320 add_service(const void *value
, void *context
)
1322 validityContext
*ctx
= (validityContext
*)context
;
1323 SCNetworkSetRef currentSet
= NULL
;
1325 SCNetworkInterfaceRef interface
= (SCNetworkInterfaceRef
)value
;
1326 CFDictionaryRef bsdNameServiceProtocolMapping
= ctx
->bsdNameServiceProtocolPreserveMapping
;
1327 SCPreferencesRef prefs
= ctx
->prefs
;
1328 SCNetworkServiceRef service
;
1329 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
1330 CFArrayRef protocolArray
= NULL
;
1332 if (isA_CFString(bsdName
)) {
1333 protocolArray
= CFDictionaryGetValue(bsdNameServiceProtocolMapping
, bsdName
);
1335 service
= SCNetworkServiceCreate(prefs
, interface
);
1336 if (service
== NULL
) {
1337 SC_log(LOG_NOTICE
, "Could not create new service");
1341 if (!SCNetworkServiceEstablishDefaultConfiguration(service
)) {
1342 SC_log(LOG_NOTICE
, "SCNetworkServiceEstablishDefaultConfiguration() failed");
1343 SCNetworkServiceRemove(service
);
1347 if (protocolArray
!= NULL
) {
1348 CFIndex protocolArrayCount
= CFArrayGetCount(protocolArray
);
1350 for (CFIndex idx
= 0; idx
< protocolArrayCount
; idx
++) {
1351 CFDictionaryRef protocolInfo
= CFArrayGetValueAtIndex(protocolArray
, idx
);
1352 CFDictionaryRef configuration
= CFDictionaryGetValue(protocolInfo
, kProtocolConfiguration
);
1353 CFStringRef protocolType
= CFDictionaryGetValue(protocolInfo
, kProtocolType
);
1354 CFBooleanRef cfEnabled
= CFDictionaryGetValue(protocolInfo
, kProtocolEnabled
);
1356 enabled
= CFBooleanGetValue(cfEnabled
);
1360 __SCNetworkServiceAddProtocolToService(service
, protocolType
, configuration
, enabled
);
1364 // Add service to current set
1365 currentSet
= SCNetworkSetCopyCurrent(prefs
);
1366 if (currentSet
== NULL
) {
1367 SC_log(LOG_NOTICE
, "Could not find current set");
1368 SCNetworkServiceRemove(service
);
1372 if (!SCNetworkSetAddService(currentSet
, service
)) {
1373 SC_log(LOG_NOTICE
, "Could not add service to current set");
1374 SCNetworkServiceRemove(service
);
1380 if (service
!= NULL
) {
1383 if (currentSet
!= NULL
) {
1384 CFRelease(currentSet
);
1389 create_bsd_name_service_protocol_mapping(const void *value
, void *context
)
1391 validityContext
*ctx
= (validityContext
*)context
;
1392 CFArrayRef interfacePreserveServiceInformation
= ctx
->interfacePreserveServiceInformation
;
1393 CFMutableDictionaryRef bsdNameServiceProtocolMapping
= ctx
->bsdNameServiceProtocolPreserveMapping
;
1394 SCNetworkInterfaceRef interface
;
1395 SCNetworkServiceRef service
= (SCNetworkServiceRef
)value
;
1397 interface
= SCNetworkServiceGetInterface(service
);
1399 if (CFArrayContainsValue(interfacePreserveServiceInformation
, CFRangeMake(0, CFArrayGetCount(interfacePreserveServiceInformation
)), interface
)) {
1400 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
1401 if (isA_CFString(bsdName
)) {
1403 CFArrayRef protocols
= SCNetworkServiceCopyProtocols(service
);
1404 if (protocols
!= NULL
) {
1405 CFMutableArrayRef protocolArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1406 CFIndex protocolCount
= CFArrayGetCount(protocols
);
1408 for (CFIndex idx
= 0; idx
< protocolCount
; idx
++) {
1409 SCNetworkProtocolRef protocol
= CFArrayGetValueAtIndex(protocols
, idx
);
1410 CFDictionaryRef configuration
= SCNetworkProtocolGetConfiguration(protocol
);
1411 CFStringRef protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
1412 Boolean enabled
= SCNetworkProtocolGetEnabled(protocol
);
1414 if (configuration
== NULL
|| protocolType
== NULL
) {
1417 CFMutableDictionaryRef protocolInfo
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1419 CFDictionaryAddValue(protocolInfo
, kProtocolType
, protocolType
);
1420 CFDictionaryAddValue(protocolInfo
, kProtocolConfiguration
, configuration
);
1421 CFDictionaryAddValue(protocolInfo
, kProtocolEnabled
, enabled
? kCFBooleanTrue
: kCFBooleanFalse
);
1422 CFArrayAppendValue(protocolArray
, protocolInfo
);
1423 CFRelease(protocolInfo
);
1425 CFDictionaryAddValue(bsdNameServiceProtocolMapping
, bsdName
, protocolArray
);
1426 CFRelease(protocols
);
1427 CFRelease(protocolArray
);
1435 remove_service(const void *value
, void *context
)
1437 validityContext
*ctx
= (validityContext
*)context
;
1438 SCNetworkInterfaceRef interface
;
1439 SCNetworkServiceRef service
= (SCNetworkServiceRef
)value
;
1440 CFArrayRef toBeRemoved
= ctx
->interfaceToBeRemoved
;
1442 interface
= SCNetworkServiceGetInterface(service
);
1444 if (CFArrayContainsValue(toBeRemoved
, CFRangeMake(0, CFArrayGetCount(toBeRemoved
)), interface
)) {
1445 SCNetworkServiceRemove(service
);
1450 _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs
,
1451 SCPreferencesRef ni_prefs
,
1452 validityContext
*context
)
1454 CFIndex removeCount
;
1455 CFIndex replaceCount
;
1456 CFArrayRef serviceList
;
1457 CFArrayRef interfaceToBeRemoved
= context
->interfaceToBeRemoved
;
1458 CFArrayRef interfaceToBeReplaced
= context
->interfaceToBeReplaced
;
1460 removeCount
= CFArrayGetCount(interfaceToBeRemoved
);
1461 replaceCount
= CFArrayGetCount(interfaceToBeReplaced
);
1462 if (removeCount
== 0 &&
1463 replaceCount
== 0) {
1464 // We don't have any information to repair
1467 // Backup current preferences before making changes
1468 __SCNetworkConfigurationBackup(prefs
, CFSTR("pre-repair"), prefs
);
1469 __SCNetworkConfigurationBackup(ni_prefs
, CFSTR("pre-repair"), prefs
);
1471 serviceList
= SCNetworkServiceCopyAll(prefs
);
1472 CFArrayApplyFunction(serviceList
, CFRangeMake(0, CFArrayGetCount(serviceList
)), create_bsd_name_service_protocol_mapping
, context
);
1473 CFArrayApplyFunction(serviceList
, CFRangeMake(0, CFArrayGetCount(serviceList
)), remove_service
, (void*)context
);
1474 CFArrayApplyFunction(interfaceToBeReplaced
, CFRangeMake(0, replaceCount
), add_service
, (void*)context
);
1475 CFRelease(serviceList
);
1480 validate_bridge(const void *value
, void *context
)
1482 SCBridgeInterfaceRef bridge
= (SCBridgeInterfaceRef
)value
;
1483 CFArrayRef memberInterfaces
= SCBridgeInterfaceGetMemberInterfaces(bridge
);
1484 CFMutableArrayRef memberInterfacesMutable
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1485 SCPreferencesRef ni_prefs
= (SCPreferencesRef
)context
;
1487 for (CFIndex idx
= 0; idx
< CFArrayGetCount(memberInterfaces
); idx
++) {
1488 CFStringRef bsdName
;
1489 SCNetworkInterfaceRef interface
= (SCNetworkInterfaceRef
)CFArrayGetValueAtIndex(memberInterfaces
, idx
);
1490 SCNetworkInterfaceRef memberInterface
;
1492 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
1493 if (bsdName
== NULL
) {
1497 // Check if member interface is present
1498 memberInterface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ni_prefs
, bsdName
);
1499 if (memberInterface
!= NULL
) {
1500 CFArrayAppendValue(memberInterfacesMutable
, memberInterface
);
1501 CFRelease(memberInterface
);
1505 if (CFArrayGetCount(memberInterfacesMutable
) == 0) {
1506 SC_log(LOG_NOTICE
, "Removing bridge w/no member interfaces: %@", bridge
);
1507 SCBridgeInterfaceRemove(bridge
);
1509 SCBridgeInterfaceSetMemberInterfaces(bridge
, memberInterfacesMutable
);
1511 CFRelease(memberInterfacesMutable
);
1514 #if !TARGET_OS_IPHONE
1516 validate_bond(const void *value
, void *context
)
1518 SCBondInterfaceRef bond
= (SCBondInterfaceRef
)value
;
1519 CFArrayRef memberInterfaces
= SCBondInterfaceGetMemberInterfaces(bond
);
1520 CFMutableArrayRef memberInterfacesMutable
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1521 SCPreferencesRef ni_prefs
= (SCPreferencesRef
)context
;
1523 for (CFIndex idx
= 0; idx
< CFArrayGetCount(memberInterfaces
); idx
++) {
1524 CFStringRef bsdName
;
1525 SCNetworkInterfaceRef interface
= (SCNetworkInterfaceRef
)CFArrayGetValueAtIndex(memberInterfaces
, idx
);
1526 SCNetworkInterfaceRef memberInterface
;
1528 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
1529 if (bsdName
== NULL
) {
1533 // Check if member interface is present
1534 memberInterface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ni_prefs
, bsdName
);
1535 if (memberInterface
!= NULL
) {
1536 CFArrayAppendValue(memberInterfacesMutable
, memberInterface
);
1537 CFRelease(memberInterface
);
1541 if (CFArrayGetCount(memberInterfacesMutable
) == 0) {
1542 SC_log(LOG_NOTICE
, "Removing bond w/no member interfaces: %@", bond
);
1543 SCBondInterfaceRemove(bond
);
1545 SCBondInterfaceSetMemberInterfaces(bond
, memberInterfacesMutable
);
1547 CFRelease(memberInterfacesMutable
);
1549 #endif // !TARGET_OS_IPHONE
1552 SCPreferencesRef prefs
;
1553 SCPreferencesRef ni_prefs
;
1554 #if !TARGET_OS_IPHONE
1555 CFArrayRef bondInterfaces
;
1556 #endif // !TARGET_OS_IPHONE
1557 CFArrayRef bridgeInterfaces
;
1558 } validate_prefs_context
;
1560 static validate_prefs_context
*
1561 validate_prefs_context_create(SCPreferencesRef prefs
, SCPreferencesRef ni_prefs
)
1563 validate_prefs_context
*context
;
1565 context
= calloc(1, sizeof(validate_prefs_context
));
1566 context
->prefs
= prefs
;
1567 context
->ni_prefs
= ni_prefs
;
1568 #if !TARGET_OS_IPHONE
1569 context
->bondInterfaces
= (CFArrayRef
)kCFNull
;
1570 #endif // !TARGET_OS_IPHONE
1571 context
->bridgeInterfaces
= (CFArrayRef
)kCFNull
;
1576 validate_prefs_context_release(validate_prefs_context
*context
)
1578 #if !TARGET_OS_IPHONE
1579 if ((context
->bondInterfaces
!= NULL
) && (context
->bondInterfaces
!= (CFArrayRef
)kCFNull
)) {
1580 CFRelease(context
->bondInterfaces
);
1582 #endif // !TARGET_OS_IPHONE
1583 if ((context
->bridgeInterfaces
!= NULL
) && (context
->bridgeInterfaces
!= (CFArrayRef
)kCFNull
)) {
1584 CFRelease(context
->bridgeInterfaces
);
1590 interfaceArrayContainsBSDName(CFArrayRef interfaces
, CFStringRef bsdName
)
1592 Boolean match
= FALSE
;
1593 CFIndex n
= CFArrayGetCount(interfaces
);
1595 for (CFIndex i
= 0; i
< n
; i
++) {
1596 SCNetworkInterfaceRef interface
;
1597 CFStringRef matchName
;
1599 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
1600 matchName
= SCNetworkInterfaceGetBSDName(interface
);
1601 if (_SC_CFEqual(bsdName
, matchName
)) {
1611 validate_vlan(const void *value
, void *context
)
1613 CFStringRef bsdName
;
1614 SCNetworkInterfaceRef interface
;
1615 Boolean isValid
= FALSE
;
1616 SCNetworkInterfaceRef physicalInterface
;
1617 validate_prefs_context
*prefs
= (validate_prefs_context
*)context
;
1618 SCVLANInterfaceRef vlan
= (SCVLANInterfaceRef
)value
;
1620 physicalInterface
= SCVLANInterfaceGetPhysicalInterface(vlan
);
1621 bsdName
= SCNetworkInterfaceGetBSDName(physicalInterface
);
1622 if (bsdName
== NULL
) {
1626 // Check if the physical interface is present
1627 interface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, prefs
->ni_prefs
, bsdName
);
1628 if (interface
!= NULL
) {
1629 CFRelease(interface
);
1634 #if !TARGET_OS_IPHONE
1635 if (prefs
->bondInterfaces
== (CFArrayRef
)kCFNull
) {
1636 prefs
->bondInterfaces
= SCBondInterfaceCopyAll(prefs
->prefs
);
1638 if (prefs
->bondInterfaces
!= NULL
) {
1639 isValid
= interfaceArrayContainsBSDName(prefs
->bondInterfaces
, bsdName
);
1644 #endif // !TARGET_OS_IPHONE
1646 if (prefs
->bridgeInterfaces
== (CFArrayRef
)kCFNull
) {
1647 prefs
->bridgeInterfaces
= SCBridgeInterfaceCopyAll(prefs
->prefs
);
1649 if (prefs
->bridgeInterfaces
!= NULL
) {
1650 isValid
= interfaceArrayContainsBSDName(prefs
->bridgeInterfaces
, bsdName
);
1658 SC_log(LOG_NOTICE
, "Removing VLAN w/no physical interface: %@", vlan
);
1659 SCVLANInterfaceRemove(vlan
);
1664 _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs
,
1665 SCPreferencesRef ni_prefs
,
1666 CFDictionaryRef options
)
1668 CFArrayRef allServices
= NULL
;
1669 CFArrayRef allSets
= NULL
;
1670 CFDictionaryRef bsdNameToBridgeServices
= NULL
;
1671 CFDictionaryRef bsdNameToBondServices
= NULL
;
1672 CFDictionaryRef bsdNameToVLANServices
= NULL
;
1673 validityContext context
;
1674 CFArrayRef interfaces
= NULL
;
1675 CFMutableArrayRef interfaceToBeRemoved
= NULL
;
1676 CFMutableArrayRef interfaceToBeReplaced
= NULL
;
1677 CFMutableArrayRef interfacePreserveServiceInformation
= NULL
;
1678 CFMutableDictionaryRef bsdNameServiceProtocolPreserveMapping
= NULL
;
1679 Boolean isValid
= TRUE
;
1680 CFDictionaryRef mappingBSDNameToInterface
= NULL
;
1681 CFDictionaryRef mappingServiceBSDNameToInterface
= NULL
;
1682 CFStringRef model
= NULL
;
1683 CFStringRef ni_model
= NULL
;
1684 Boolean repairConfiguration
= FALSE
;
1685 Boolean revertBypassSystemInterfaces
= FALSE
;
1686 CFArrayRef setServiceOrder
= NULL
;
1687 CFArrayRef setServices
= NULL
;
1689 if ((isA_CFDictionary(options
) != NULL
)) {
1690 CFBooleanRef repair
= CFDictionaryGetValue(options
, kSCNetworkConfigurationRepair
);
1691 if (isA_CFBoolean(repair
) != NULL
) {
1692 repairConfiguration
= CFBooleanGetValue(repair
);
1697 "%sbypassing system interfaces for %@",
1698 _SCNetworkConfigurationBypassSystemInterfaces(prefs
) ? "" : "not ",
1701 if (!_SCNetworkConfigurationBypassSystemInterfaces(prefs
)) {
1702 _SCNetworkConfigurationSetBypassSystemInterfaces(prefs
, TRUE
);
1703 revertBypassSystemInterfaces
= TRUE
;
1707 Check the validity by:
1708 - Comparing if the models are the same
1710 model
= SCPreferencesGetValue(prefs
, MODEL
);
1711 if (!isA_CFString(model
)) {
1713 "Configuration validity check: no \"Model\" property in preferences.plist"
1717 ni_model
= SCPreferencesGetValue(ni_prefs
, MODEL
);
1718 if (!isA_CFString(ni_model
)) {
1720 "Configuration validity check: no \"Model\" property in NetworkInterfaces.plist"
1724 if (isA_CFString(model
) && isA_CFString(ni_model
) && !CFEqual(model
, ni_model
)) {
1727 "Configuration validity check: model names do not match!"
1736 - Comparing if the interfaces names mentioned in NetworkInterfaces.plist and preferences.plist match
1739 __SCNetworkInterfaceCreateMappingUsingBSDName(SCPreferencesRef prefs);
1741 interfaces
= __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs
);
1742 if (interfaces
== NULL
) {
1744 "Configuration validity check: no network interfaces!"
1750 mappingBSDNameToInterface
= __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces
);
1751 CFRelease(interfaces
);
1752 if (!isA_CFDictionary(mappingBSDNameToInterface
)) {
1755 "Configuration validity check: no BSD name to network interface mapping!"
1761 interfaces
= __SCNetworkServiceCopyAllInterfaces(prefs
);
1762 if (!isA_CFArray(interfaces
)) {
1763 if (interfaces
!= NULL
) CFRelease(interfaces
);
1766 "Configuration validity check: no service interfaces!"
1771 mappingServiceBSDNameToInterface
= __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces
);
1772 CFRelease(interfaces
);
1773 if (!isA_CFDictionary(mappingServiceBSDNameToInterface
)) {
1776 "Configuration validity check: no BSD name to service interface mapping!"
1782 if (repairConfiguration
) {
1783 interfaceToBeRemoved
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1784 interfaceToBeReplaced
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1785 interfacePreserveServiceInformation
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1786 bsdNameServiceProtocolPreserveMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1787 #if !TARGET_OS_IPHONE
1788 bsdNameToBridgeServices
= _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(prefs
);
1789 bsdNameToBondServices
= _SCNetworkMigrationCopyMappingBSDNameToBondServices(prefs
);
1790 bsdNameToVLANServices
= _SCNetworkMigrationCopyMappingBSDNameToVLANServices(prefs
);
1791 #endif // !TARGET_OS_IPHONE
1793 context
.interfaceMapping
= mappingBSDNameToInterface
;
1794 context
.isValid
= &isValid
;
1795 context
.interfaceToBeRemoved
= interfaceToBeRemoved
;
1796 context
.interfaceToBeReplaced
= interfaceToBeReplaced
;
1797 context
.interfacePreserveServiceInformation
= interfacePreserveServiceInformation
;
1798 context
.bsdNameToBridgeServices
= bsdNameToBridgeServices
;
1799 context
.bsdNameToBondServices
= bsdNameToBondServices
;
1800 context
.bsdNameToVLANServices
= bsdNameToVLANServices
;
1801 context
.repair
= repairConfiguration
;
1802 context
.prefs
= prefs
;
1803 context
.bsdNameServiceProtocolPreserveMapping
= bsdNameServiceProtocolPreserveMapping
;
1805 CFDictionaryApplyFunction(mappingServiceBSDNameToInterface
, _SCNetworkConfigurationValidateInterface
, &context
);
1809 "Configuration validity check: mismatch between interface names in NetworkInterfaces.plist and preferences.plist!"
1814 if (repairConfiguration
) {
1815 isValid
= _SCNetworkConfigurationRepairUsingPreferences(prefs
, ni_prefs
, &context
);
1819 // Save the changes if repair fixed an invalid configuration
1820 if (!SCPreferencesCommitChanges(prefs
)) {
1821 SC_log(LOG_NOTICE
, "SCPreferencesCommitChanges() failed");
1829 - Check if all the network services mentioned in the SCNetworkSet are actually present in the SCNetworkService array
1831 allServices
= SCNetworkServiceCopyAll(prefs
);
1832 if (!isA_CFArray(allServices
)) {
1835 "Configuration validity check: no services!"
1841 allSets
= SCNetworkSetCopyAll(prefs
);
1842 if (!isA_CFArray(allSets
)) {
1845 "Configuration validity check: no sets!"
1851 for (CFIndex idx
= 0; ((idx
< CFArrayGetCount(allSets
)) && isValid
); idx
++) {
1852 SCNetworkSetRef set
= CFArrayGetValueAtIndex(allSets
, idx
);
1854 setServices
= SCNetworkSetCopyServices(set
);
1855 if (setServices
== NULL
) {
1857 "Configuration validity check: set w/no services!"
1864 for (CFIndex idx2
= 0; idx2
< CFArrayGetCount(setServices
); idx2
++) {
1865 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(setServices
, idx2
);
1867 if (!CFArrayContainsValue(allServices
, CFRangeMake(0, CFArrayGetCount(allServices
)), service
)) {
1870 "All network services in the network set are not present in SCNetworkService array");
1879 - Check if service IDs in service order do exist in the SET
1881 setServiceOrder
= SCNetworkSetGetServiceOrder(set
);
1882 if (setServiceOrder
!= NULL
) {
1883 for (CFIndex idx2
= 0; idx2
< CFArrayGetCount(setServiceOrder
); idx2
++) {
1884 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(setServiceOrder
, idx2
);
1885 if (!CFArrayContainsValue(setServiceOrder
, CFRangeMake(0, CFArrayGetCount(setServiceOrder
)), service
) &&
1886 !CFArrayContainsValue(allServices
, CFRangeMake(0, CFArrayGetCount(allServices
)), service
)) {
1888 "Service: %@ is not present in the service order for set %@",
1895 if (setServices
!= NULL
) {
1896 CFRelease(setServices
);
1902 - Check if the virtual network interfaces have valid member interfaces
1904 CFArrayRef bridges
= SCBridgeInterfaceCopyAll(prefs
);
1905 if (bridges
!= NULL
) {
1906 CFArrayApplyFunction(bridges
, CFRangeMake(0, CFArrayGetCount(bridges
)), validate_bridge
, (void*)ni_prefs
);
1909 #if !TARGET_OS_IPHONE
1910 CFArrayRef bonds
= SCBondInterfaceCopyAll(prefs
);
1911 if (bonds
!= NULL
) {
1912 CFArrayApplyFunction(bonds
, CFRangeMake(0, CFArrayGetCount(bonds
)), validate_bond
, (void*)ni_prefs
);
1915 #endif // !TARGET_OS_IPHONE
1916 CFArrayRef vlans
= SCVLANInterfaceCopyAll(prefs
);
1917 if (vlans
!= NULL
) {
1918 validate_prefs_context
*validate_prefs
;
1920 validate_prefs
= validate_prefs_context_create(prefs
, ni_prefs
);
1921 CFArrayApplyFunction(vlans
, CFRangeMake(0, CFArrayGetCount(vlans
)), validate_vlan
, (void*)validate_prefs
);
1922 validate_prefs_context_release(validate_prefs
);
1928 if (mappingBSDNameToInterface
!= NULL
) {
1929 CFRelease(mappingBSDNameToInterface
);
1931 if (mappingServiceBSDNameToInterface
!= NULL
) {
1932 CFRelease(mappingServiceBSDNameToInterface
);
1934 if (allServices
!= NULL
) {
1935 CFRelease(allServices
);
1937 if (allSets
!= NULL
) {
1940 #if !TARGET_OS_IPHONE
1941 if (bsdNameToBridgeServices
!= NULL
) {
1942 CFRelease(bsdNameToBridgeServices
);
1944 if (bsdNameToBondServices
!= NULL
) {
1945 CFRelease(bsdNameToBondServices
);
1947 if (bsdNameToVLANServices
!= NULL
) {
1948 CFRelease(bsdNameToVLANServices
);
1950 #endif // !TARGET_OS_IPHONE
1951 if (setServices
!= NULL
) {
1952 CFRelease(setServices
);
1954 if (interfaceToBeRemoved
!= NULL
) {
1955 CFRelease(interfaceToBeRemoved
);
1957 if (interfaceToBeReplaced
!= NULL
) {
1958 CFRelease(interfaceToBeReplaced
);
1960 if (interfacePreserveServiceInformation
!= NULL
) {
1961 CFRelease(interfacePreserveServiceInformation
);
1963 if (bsdNameServiceProtocolPreserveMapping
!= NULL
) {
1964 CFRelease(bsdNameServiceProtocolPreserveMapping
);
1966 if (revertBypassSystemInterfaces
) {
1967 _SCNetworkConfigurationSetBypassSystemInterfaces(prefs
, FALSE
);
1973 _SCNetworkConfigurationCheckValidity(CFURLRef configDir
, CFDictionaryRef options
)
1975 CFURLRef baseURL
= NULL
;
1976 CFURLRef configNetworkInterfaceFile
= NULL
;
1977 CFStringRef configNetworkInterfaceFileString
= NULL
;
1978 SCPreferencesRef configNetworkInterfacePref
= NULL
;
1979 SCPreferencesRef configPref
= NULL
;
1980 CFURLRef configPreferenceFile
= NULL
;
1981 CFStringRef configPreferencesFileString
= NULL
;
1982 Boolean isValid
= FALSE
;
1983 char networkInterfaceStr
[PATH_MAX
];
1984 char prefsStr
[PATH_MAX
];
1986 if (configDir
== NULL
) {
1987 SC_log(LOG_NOTICE
, "Migration files not found in directory: %@",
1988 (configDir
== NULL
) ? CFSTR("NULL") : CFURLGetString(configDir
));
1991 baseURL
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
1992 PREFS_DEFAULT_DIR_RELATIVE
,
1993 kCFURLPOSIXPathStyle
,
1997 configPreferenceFile
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
1998 (const UInt8
*)PREFS_DEFAULT_CONFIG_PLIST
,
1999 sizeof(PREFS_DEFAULT_CONFIG_PLIST
),
2002 configNetworkInterfaceFile
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
2003 (const UInt8
*)INTERFACES_DEFAULT_CONFIG_PLIST
,
2004 sizeof(INTERFACES_DEFAULT_CONFIG_PLIST
),
2008 if (!CFURLGetFileSystemRepresentation(configPreferenceFile
, TRUE
, (UInt8
*)prefsStr
, sizeof(prefsStr
))) {
2009 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configPreferenceFile
);
2012 if (!CFURLGetFileSystemRepresentation(configNetworkInterfaceFile
, TRUE
, (UInt8
*)networkInterfaceStr
, sizeof(networkInterfaceStr
))) {
2013 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configNetworkInterfaceFile
);
2017 configPreferencesFileString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), prefsStr
);
2018 configNetworkInterfaceFileString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), networkInterfaceStr
);
2020 configPref
= SCPreferencesCreate(NULL
,
2022 configPreferencesFileString
);
2024 configNetworkInterfacePref
= SCPreferencesCreate(NULL
,
2026 configNetworkInterfaceFileString
);
2027 if ((configPref
== NULL
) || (configNetworkInterfacePref
== NULL
)) {
2031 // This function compares preferences.plist and NetworkInterfaces.plist and verifies if the values are correct
2032 // Checking interface mismatch for validity
2033 isValid
= _SCNetworkConfigurationCheckValidityWithPreferences(configPref
, configNetworkInterfacePref
, options
);
2036 if (baseURL
!= NULL
) {
2039 if (configPreferencesFileString
!= NULL
) {
2040 CFRelease(configPreferencesFileString
);
2042 if (configNetworkInterfaceFileString
!= NULL
) {
2043 CFRelease(configNetworkInterfaceFileString
);
2045 if (configPref
!= NULL
) {
2046 CFRelease(configPref
);
2048 if (configNetworkInterfacePref
!= NULL
) {
2049 CFRelease(configNetworkInterfacePref
);
2051 if (configPreferenceFile
!= NULL
) {
2052 CFRelease(configPreferenceFile
);
2054 if (configNetworkInterfaceFile
!= NULL
) {
2055 CFRelease(configNetworkInterfaceFile
);
2062 CFMutableArrayRef externalInterfaceList
;
2063 CFMutableArrayRef networkInterfaceList
;
2064 Boolean foundNewInterfaces
;
2065 } externalMappingContext
;
2068 _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key
, const void *value
, void *context
)
2071 externalMappingContext
*ctx
= context
;
2072 CFDictionaryRef interface_entity
= NULL
;
2073 SCNetworkInterfaceRef targetInterface
= (SCNetworkInterfaceRef
)value
;
2075 if (CFArrayContainsValue(ctx
->externalInterfaceList
, CFRangeMake(0, CFArrayGetCount(ctx
->externalInterfaceList
)), targetInterface
)) {
2076 SC_log(LOG_NOTICE
, "Target interface (%@) already exists, not adding to NetworkInterfaces.plist", targetInterface
);
2077 return; // If the target interface already exists then do not add it to NetworkInterfaces.plist
2079 ctx
->foundNewInterfaces
= TRUE
;
2080 interface_entity
= __SCNetworkInterfaceCopyStorageEntity(targetInterface
);
2082 if (interface_entity
!= NULL
) {
2083 CFArrayAppendValue(ctx
->networkInterfaceList
, interface_entity
);
2084 CFRelease(interface_entity
);
2088 static CFArrayRef
// CFDictionaryRef
2089 _SCNetworkMigrationCreateNetworkInterfaceArray(SCPreferencesRef ni_prefs
, CFDictionaryRef externalMapping
, Boolean
*hasNewInterface
)
2091 externalMappingContext context
;
2093 CFMutableArrayRef externalInterfaceList
= NULL
;
2094 CFArrayRef if_list
= NULL
;
2095 CFDictionaryRef interface_entity
= NULL
;
2096 CFMutableArrayRef networkInterfaceList
= NULL
;
2098 if (ni_prefs
== NULL
) {
2099 SC_log(LOG_NOTICE
, "No NetworkInterfaces.plist");
2103 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
2104 if (!isA_CFArray(if_list
) ||
2105 ((count
= CFArrayGetCount(if_list
)) == 0)) {
2106 SC_log(LOG_NOTICE
, "No interfaces");
2110 networkInterfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2112 // Keep the same builtin and external interfaces
2113 for (CFIndex idx
= 0; idx
< count
; idx
++) {
2114 interface_entity
= CFArrayGetValueAtIndex(if_list
, idx
);
2115 if (!isA_CFDictionary(interface_entity
)) {
2118 CFArrayAppendValue(networkInterfaceList
, interface_entity
);
2121 if (!isA_CFDictionary(externalMapping
)) {
2122 // if no external mapping
2126 // Add any new external interfaces found
2127 externalInterfaceList
= _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(ni_prefs
, FALSE
);
2128 context
.externalInterfaceList
= externalInterfaceList
;
2129 context
.networkInterfaceList
= networkInterfaceList
;
2130 context
.foundNewInterfaces
= FALSE
;
2132 CFDictionaryApplyFunction(externalMapping
, _SCNetworkConfigurationCollectInterfaceStorageEntity
, &context
);
2134 if (hasNewInterface
!= NULL
) {
2135 *hasNewInterface
= context
.foundNewInterfaces
;
2138 if (externalInterfaceList
!= NULL
) {
2139 CFRelease(externalInterfaceList
);
2141 return networkInterfaceList
;
2145 SCNetworkMigrationMapSourceToTargetName(const void *key
, const void *value
, void *context
)
2147 SCNetworkInterfaceRef interfaceKey
= (SCNetworkInterfaceRef
)key
;
2148 SCNetworkInterfaceRef interfaceValue
= (SCNetworkInterfaceRef
)value
;
2149 CFMutableDictionaryRef mapping
= (CFMutableDictionaryRef
)context
;
2150 CFStringRef sourceBSDName
= NULL
;
2151 CFStringRef targetBSDName
= NULL
;
2153 sourceBSDName
= SCNetworkInterfaceGetBSDName(interfaceKey
);
2154 if (!isA_CFString(sourceBSDName
)) {
2158 targetBSDName
= SCNetworkInterfaceGetBSDName(interfaceValue
);
2159 if (!isA_CFString(targetBSDName
)) {
2163 if (!CFDictionaryContainsKey(mapping
, sourceBSDName
)) {
2164 CFDictionaryAddValue(mapping
, sourceBSDName
, targetBSDName
);
2169 static CFDictionaryRef
2170 _SCNetworkMigrationCreateBSDNameMapping(CFDictionaryRef internalMapping
, CFDictionaryRef externalMapping
)
2172 CFMutableDictionaryRef bsdNameMapping
= CFDictionaryCreateMutable(NULL
, 0,
2173 &kCFTypeDictionaryKeyCallBacks
,
2174 &kCFTypeDictionaryValueCallBacks
);
2176 if ((internalMapping
== NULL
) && (externalMapping
== NULL
)) {
2180 if (internalMapping
!= NULL
) {
2181 CFDictionaryApplyFunction(internalMapping
, SCNetworkMigrationMapSourceToTargetName
, bsdNameMapping
);
2184 if (externalMapping
!= NULL
) {
2185 CFDictionaryApplyFunction(externalMapping
, SCNetworkMigrationMapSourceToTargetName
, bsdNameMapping
);
2189 return bsdNameMapping
;
2192 static CFDictionaryRef
2193 _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs
)
2195 SCNetworkServiceRef service
;
2196 CFMutableDictionaryRef serviceSetMapping
;
2197 CFArrayRef services
= NULL
;
2198 CFMutableArrayRef setList
= NULL
;
2199 CFArrayRef sets
= NULL
;
2201 serviceSetMapping
= CFDictionaryCreateMutable(NULL
, 0,
2202 &kCFTypeDictionaryKeyCallBacks
,
2203 &kCFTypeDictionaryValueCallBacks
);
2204 services
= SCNetworkServiceCopyAll(prefs
);
2205 if (services
== NULL
) {
2208 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
2209 service
= CFArrayGetValueAtIndex(services
, idx
);
2210 if (!CFDictionaryContainsKey(serviceSetMapping
, service
)) {
2211 setList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2212 CFDictionaryAddValue(serviceSetMapping
, service
, setList
);
2216 CFRelease(services
);
2218 sets
= SCNetworkSetCopyAll(prefs
);
2223 for (CFIndex idx
= 0; idx
< CFArrayGetCount(sets
); idx
++) {
2224 SCNetworkSetRef set
;
2226 set
= CFArrayGetValueAtIndex(sets
, idx
);
2227 services
= SCNetworkSetCopyServices(set
);
2228 for (CFIndex idx2
= 0; idx2
< CFArrayGetCount(services
); idx2
++) {
2229 service
= CFArrayGetValueAtIndex(services
, idx2
);
2230 setList
= (CFMutableArrayRef
)CFDictionaryGetValue(serviceSetMapping
, service
);
2231 if (setList
!= NULL
) {
2232 CFArrayAppendValue(setList
, set
);
2235 CFRelease(services
);
2242 return serviceSetMapping
;
2245 static CFDictionaryRef
2246 _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs
,
2247 SCPreferencesRef targetPrefs
)
2249 SCNetworkSetRef currentSourceSet
= NULL
;
2250 CFMutableDictionaryRef setMapping
= NULL
;
2251 CFStringRef setName
;
2252 CFArrayRef sourceSets
= NULL
;
2253 CFIndex targetCount
;
2254 SCNetworkSetRef targetSet
;
2255 CFArrayRef targetSets
= NULL
;
2256 CFMutableArrayRef targetSetsMutable
= NULL
;
2258 sourceSets
= SCNetworkSetCopyAll(sourcePrefs
);
2259 targetSets
= SCNetworkSetCopyAll(targetPrefs
);
2261 if (sourceSets
== NULL
||
2262 targetSets
== NULL
) {
2265 targetSetsMutable
= CFArrayCreateMutableCopy(NULL
, 0, targetSets
);
2266 targetCount
= CFArrayGetCount(targetSetsMutable
);
2268 setMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2270 currentSourceSet
= SCNetworkSetCopyCurrent(sourcePrefs
);
2272 // Mapping the current source set to the first target set, and setting it as current set
2273 if (currentSourceSet
!= NULL
) {
2274 if (targetCount
> 0) {
2275 targetSet
= CFArrayGetValueAtIndex(targetSetsMutable
, 0);
2276 CFRetain(targetSet
);
2277 CFArrayRemoveValueAtIndex(targetSetsMutable
, 0);
2279 setName
= SCNetworkSetGetName(currentSourceSet
);
2280 SCNetworkSetSetName(targetSet
, setName
);
2281 CFDictionaryAddValue(setMapping
, currentSourceSet
, targetSet
);
2282 SCNetworkSetSetCurrent(targetSet
);
2283 CFRelease(targetSet
);
2286 SC_log(LOG_NOTICE
, "Number of sets in the target should be at least 1, but is found to be %ld", targetCount
);
2291 for (CFIndex idx
= 0; idx
< CFArrayGetCount(sourceSets
); idx
++) {
2292 SCNetworkSetRef sourceSet
= CFArrayGetValueAtIndex(sourceSets
, idx
);
2294 if ((currentSourceSet
!= NULL
) && CFEqual(sourceSet
, currentSourceSet
)) {
2298 targetCount
= CFArrayGetCount(targetSetsMutable
);
2299 setName
= SCNetworkSetGetName(sourceSet
);
2301 if (targetCount
> 0) {
2302 targetSet
= CFArrayGetValueAtIndex(targetSetsMutable
, 0);
2303 CFRetain(targetSet
);
2304 CFArrayRemoveValueAtIndex(targetSetsMutable
, 0);
2306 targetSet
= SCNetworkSetCreate(targetPrefs
);
2308 SCNetworkSetSetName(targetSet
, setName
);
2309 CFDictionaryAddValue(setMapping
, sourceSet
, targetSet
);
2311 CFRelease(targetSet
);
2316 if (sourceSets
!= NULL
) {
2317 CFRelease(sourceSets
);
2319 if (targetSets
!= NULL
) {
2320 CFRelease(targetSets
);
2322 if (targetSetsMutable
!= NULL
) {
2323 CFRelease(targetSetsMutable
);
2325 if (currentSourceSet
!= NULL
) {
2326 CFRelease(currentSourceSet
);
2332 // This function finds the mapping between source and target preferences (SCNetworkServicesRef -> SCNetworkServicesRef)
2333 // If there is no mapping found between source and target preferences, then the CFBooleanRef value indicating no value is found is stored (SCNetworkServicesRef -> kCFBooleanFalse)
2334 static CFDictionaryRef
2335 _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef sourcePrefs
,
2336 SCPreferencesRef targetPrefs
,
2337 CFDictionaryRef bsdNameMapping
)
2339 CFMutableDictionaryRef serviceMapping
= NULL
; // Mapping of services between source and target configurations
2340 CFStringRef sourceBSDName
= NULL
;
2341 CFIndex sourceCount
= 0;
2342 SCNetworkInterfaceRef sourceInterface
= NULL
;
2343 CFStringRef sourceInterfaceSubType
= NULL
; // Check interface type and subtype to be able to transfer VPN
2344 CFStringRef sourceInterfaceType
= NULL
;
2345 CFArrayRef sourceSCNetworkServices
= NULL
;
2346 CFMutableArrayRef sourceSCNetworkServicesMutable
= NULL
; // Source SCNetworkServiceRef mutable array
2347 SCNetworkServiceRef sourceService
= NULL
;
2348 CFStringRef targetBSDName
= NULL
;
2349 CFStringRef targetBSDNameMapped
= NULL
;
2350 CFIndex targetCount
= 0; // Count of Source and Target Services
2351 SCNetworkInterfaceRef targetInterface
= NULL
;
2352 CFStringRef targetInterfaceSubType
= NULL
; // services during migration
2353 CFStringRef targetInterfaceType
= NULL
;
2354 CFArrayRef targetSCNetworkServices
= NULL
;
2355 CFMutableArrayRef targetSCNetworkServicesMutable
= NULL
; // Target SCNetworkServiceRef mutable array
2356 SCNetworkServiceRef targetService
= NULL
;
2358 // We need BSD Mapping to successfully create service mapping
2359 if (bsdNameMapping
== NULL
) {
2360 SC_log(LOG_NOTICE
, "No BSD name mappings");
2363 sourceSCNetworkServices
= SCNetworkServiceCopyAll(sourcePrefs
);
2364 if (!isA_CFArray(sourceSCNetworkServices
)) {
2365 SC_log(LOG_NOTICE
, "No source network services");
2368 targetSCNetworkServices
= SCNetworkServiceCopyAll(targetPrefs
);
2369 if (!isA_CFArray(targetSCNetworkServices
)) {
2370 SC_log(LOG_NOTICE
, "No target network services");
2374 sourceCount
= CFArrayGetCount(sourceSCNetworkServices
);
2376 sourceSCNetworkServicesMutable
= CFArrayCreateMutableCopy(NULL
, 0, sourceSCNetworkServices
);
2377 targetSCNetworkServicesMutable
= CFArrayCreateMutableCopy(NULL
, 0, targetSCNetworkServices
);
2379 serviceMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2381 for (CFIndex idx
= 0; idx
< sourceCount
; idx
++) {
2382 sourceBSDName
= NULL
;
2383 sourceService
= NULL
;
2384 sourceInterface
= NULL
;
2385 sourceInterfaceType
= NULL
;
2386 sourceInterfaceSubType
= NULL
;
2387 targetBSDNameMapped
= NULL
;
2389 targetCount
= CFArrayGetCount(targetSCNetworkServicesMutable
);
2390 sourceService
= (SCNetworkServiceRef
) CFArrayGetValueAtIndex(sourceSCNetworkServicesMutable
, idx
);
2392 sourceInterface
= SCNetworkServiceGetInterface(sourceService
);
2393 if (sourceInterface
== NULL
) {
2394 SC_log(LOG_NOTICE
, "No source interface");
2398 sourceInterfaceType
= __SCNetworkInterfaceGetEntityType(sourceInterface
);
2399 if ((isA_CFString(sourceInterfaceType
) != NULL
) &&
2400 (CFEqual(sourceInterfaceType
, kSCValNetInterfaceTypeVPN
) ||
2401 CFEqual(sourceInterfaceType
, kSCValNetInterfaceTypePPP
))) {
2402 sourceInterfaceSubType
= __SCNetworkInterfaceGetEntitySubType(sourceInterface
);
2403 if (!isA_CFString(sourceInterfaceSubType
)) {
2404 SC_log(LOG_NOTICE
, "No source interface SubType");
2408 else if ((isA_CFString(sourceInterfaceType
) &&
2409 !CFEqual(sourceInterfaceType
, kSCValNetInterfaceTypeIPSec
) &&
2410 !CFEqual(sourceInterfaceType
, kSCValNetInterfaceType6to4
) &&
2411 !CFEqual(sourceInterfaceType
, kSCValNetInterfaceTypeLoopback
)) ||
2412 !isA_CFString(sourceInterfaceType
)) {
2413 sourceBSDName
= SCNetworkInterfaceGetBSDName(sourceInterface
);
2414 if (!isA_CFString(sourceBSDName
) ||
2415 !CFDictionaryGetValueIfPresent(bsdNameMapping
,
2417 (const void **)&targetBSDNameMapped
) ||
2418 !isA_CFString(targetBSDNameMapped
)) {
2419 SC_log(LOG_INFO
, "No BSD name mapping for %@",
2420 (sourceBSDName
!= NULL
) ? sourceBSDName
: CFSTR("NULL"));
2424 // Find the bsd name in target service
2425 for (CFIndex idx2
= 0; idx2
< targetCount
; idx2
++) {
2426 targetService
= NULL
;
2427 targetInterface
= NULL
;
2428 targetBSDName
= NULL
;
2429 targetInterfaceType
= NULL
;
2430 targetInterfaceSubType
= NULL
;
2432 targetService
= (SCNetworkServiceRef
) CFArrayGetValueAtIndex(targetSCNetworkServicesMutable
, idx2
);
2434 targetInterface
= SCNetworkServiceGetInterface(targetService
);
2435 if (targetInterface
== NULL
) {
2436 SC_log(LOG_NOTICE
, "No target interface");
2439 if (sourceBSDName
!= NULL
) {
2440 targetBSDName
= SCNetworkInterfaceGetBSDName(targetInterface
);
2441 if (!isA_CFString(targetBSDName
)) {
2442 SC_log(LOG_NOTICE
, "No target BSD name: %@", targetInterface
);
2446 if (CFEqual(targetBSDName
, targetBSDNameMapped
)) {
2447 CFDictionaryAddValue(serviceMapping
, sourceService
, targetService
);
2448 CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable
, idx2
);
2452 // Source Interface Type should be VPN
2453 targetInterfaceType
= __SCNetworkInterfaceGetEntityType(targetInterface
);
2454 if ((!isA_CFString(targetInterfaceType
)) ||
2455 (!CFEqual(targetInterfaceType
, kSCValNetInterfaceTypeVPN
) &&
2456 !CFEqual(targetInterfaceType
, kSCValNetInterfaceTypePPP
))) {
2457 SC_log(LOG_NOTICE
, "Unexpected target interface type: %@", targetInterface
);
2460 targetInterfaceSubType
= __SCNetworkInterfaceGetEntitySubType(targetInterface
);
2461 if (!isA_CFString(targetInterfaceSubType
)) {
2462 SC_log(LOG_NOTICE
, "No target interface SubType: %@", targetInterface
);
2466 // Check if the target interface type and the target interface sub type match
2467 if (CFEqual(targetInterfaceType
, sourceInterfaceType
) &&
2468 CFEqual(targetInterfaceSubType
, sourceInterfaceSubType
)) {
2469 CFDictionaryAddValue(serviceMapping
, sourceService
, targetService
);
2470 CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable
, idx2
);
2475 // Check if sourceService has found a mapping or not, if not the create a NULL mapping to indicate
2476 // the this service needs to be added and not replaced
2477 if (!CFDictionaryContainsKey(serviceMapping
, sourceService
)) {
2478 CFDictionaryAddValue(serviceMapping
, sourceService
, kCFBooleanFalse
);
2484 if (sourceSCNetworkServices
!= NULL
) {
2485 CFRelease(sourceSCNetworkServices
);
2487 if (targetSCNetworkServices
!= NULL
) {
2488 CFRelease(targetSCNetworkServices
);
2490 if (sourceSCNetworkServicesMutable
!= NULL
) {
2491 CFRelease(sourceSCNetworkServicesMutable
);
2493 if (targetSCNetworkServicesMutable
!= NULL
) {
2494 CFRelease(targetSCNetworkServicesMutable
);
2497 return serviceMapping
;
2501 SCPreferencesRef targetPrefs
;
2502 CFDictionaryRef bsdNameMapping
;
2503 CFDictionaryRef setMapping
;
2504 CFDictionaryRef serviceSetMapping
;
2505 } serviceMigrationContext
;
2508 // SCNetworkServiceRef: if target service needs replacement
2509 // CFBooleanRef: if target service is not present
2511 ServiceMigrationAddOrReplace(const void *key
, const void *value
, void *context
)
2513 CFDictionaryRef bsdNameMapping
= NULL
;
2514 serviceMigrationContext
*ctx
= (serviceMigrationContext
*)context
;
2515 CFDictionaryRef setMapping
;
2516 CFDictionaryRef sourceServiceSetMapping
;
2517 SCNetworkServiceRef sourceService
= (SCNetworkServiceRef
)key
;
2518 SCPreferencesRef targetPrefs
= NULL
;
2519 SCNetworkServiceRef targetService
= (SCNetworkServiceRef
)value
;
2521 targetPrefs
= ctx
->targetPrefs
;
2522 bsdNameMapping
= ctx
->bsdNameMapping
;
2523 setMapping
= ctx
->setMapping
;
2524 sourceServiceSetMapping
= ctx
->serviceSetMapping
;
2526 if ((setMapping
!= NULL
) || (sourceServiceSetMapping
!= NULL
)) {
2527 if (isA_SCNetworkService(targetService
)) {
2528 (void)SCNetworkServiceGetName(targetService
); // ensures that the service name will be logged
2529 SCNetworkServiceRemove(targetService
);
2533 if (!__SCNetworkServiceMigrateNew(targetPrefs
, sourceService
, bsdNameMapping
, setMapping
, sourceServiceSetMapping
)) {
2534 (void)SCNetworkServiceGetName(sourceService
); // ensures that the service name will be logged
2535 SC_log(LOG_INFO
, "*** [source] service add failed: %@", sourceService
);
2540 logConfiguration(const char *description
, SCPreferencesRef prefs
)
2544 sets
= SCNetworkSetCopyAll(prefs
);
2546 CFIndex n
= CFArrayGetCount(sets
);
2548 SC_log(LOG_NOTICE
, "%s configuration", description
);
2549 for (CFIndex i
= 0; i
< n
; i
++) {
2550 CFArrayRef services
;
2551 SCNetworkSetRef set
;
2553 set
= CFArrayGetValueAtIndex(sets
, i
);
2554 SC_log(LOG_NOTICE
, " Set %@ (%@)",
2555 SCNetworkSetGetSetID(set
),
2556 SCNetworkSetGetName(set
));
2558 services
= SCNetworkSetCopyServices(set
);
2559 if (services
!= NULL
) {
2564 order
= SCNetworkSetGetServiceOrder(set
);
2565 if (order
!= NULL
) {
2566 nOrder
= CFArrayGetCount(order
);
2569 n
= CFArrayGetCount(services
);
2571 CFMutableArrayRef sorted
;
2573 sorted
= CFArrayCreateMutableCopy(NULL
, 0, services
);
2574 CFArraySortValues(sorted
,
2575 CFRangeMake(0, CFArrayGetCount(sorted
)),
2576 _SCNetworkServiceCompare
,
2578 CFRelease(services
);
2582 for (CFIndex i
= 0; i
< n
; i
++) {
2583 CFStringRef bsdName
;
2584 SCNetworkInterfaceRef interface
;
2585 CFIndex orderIndex
= kCFNotFound
;
2586 SCNetworkServiceRef service
;
2587 CFStringRef serviceName
;
2588 CFStringRef serviceID
;
2590 service
= CFArrayGetValueAtIndex(services
, i
);
2591 serviceID
= SCNetworkServiceGetServiceID(service
);
2592 serviceName
= SCNetworkServiceGetName(service
);
2593 if (serviceName
== NULL
) serviceName
= CFSTR("");
2595 interface
= SCNetworkServiceGetInterface(service
);
2596 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
2598 if (order
!= NULL
) {
2599 orderIndex
= CFArrayGetFirstIndexOfValue(order
,
2600 CFRangeMake(0, nOrder
),
2603 if (orderIndex
!= kCFNotFound
) {
2604 SC_log(LOG_NOTICE
, " Service %2ld : %@, %2d (%@%s%@)",
2607 __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service
)), // temp?
2609 bsdName
!= NULL
? ", " : "",
2610 bsdName
!= NULL
? bsdName
: CFSTR(""));
2612 SC_log(LOG_NOTICE
, " Service : %@, %2d (%@%s%@)",
2614 __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service
)), // temp?
2616 bsdName
!= NULL
? ", " : "",
2617 bsdName
!= NULL
? bsdName
: CFSTR(""));
2621 CFRelease(services
);
2632 logMapping(const void *key
, const void *value
, void *context
)
2634 #pragma unused(context)
2635 CFTypeRef mapping_key
= NULL
;
2636 const char **mapping_name
= (const char **)context
;
2637 CFTypeRef mapping_value
= NULL
;
2638 Boolean mapping_value_new
= FALSE
;
2640 if (*mapping_name
!= NULL
) {
2641 SC_log(LOG_NOTICE
, "%s =", *mapping_name
);
2642 *mapping_name
= NULL
;
2645 if (isA_SCNetworkService(key
)) {
2646 mapping_key
= SCNetworkServiceGetServiceID(key
);
2647 } else if (isA_SCNetworkSet(key
)) {
2648 mapping_key
= SCNetworkSetGetSetID(key
);
2653 if (isA_SCNetworkService(value
)) {
2654 mapping_value
= SCNetworkServiceGetServiceID(value
);
2655 } else if (isA_SCNetworkSet(value
)) {
2656 mapping_value
= SCNetworkSetGetSetID(value
);
2657 } else if (isA_CFBoolean(value
)) {
2658 mapping_value
= CFSTR("None");
2659 } else if (isA_CFArray(value
)) {
2660 CFIndex n
= CFArrayGetCount(value
);
2661 CFMutableStringRef str
= CFStringCreateMutable(NULL
, 0);
2663 CFStringAppendFormat(str
, NULL
, CFSTR("( "));
2664 for (CFIndex i
= 0; i
< n
; i
++) {
2667 val
= CFArrayGetValueAtIndex(value
, i
);
2668 if (isA_SCNetworkSet(val
)) {
2669 val
= SCNetworkSetGetSetID(val
);
2671 CFStringAppendFormat(str
, NULL
, CFSTR("%s%@"),
2677 CFStringAppendFormat(str
, NULL
, CFSTR(" )"));
2678 mapping_value
= str
;
2679 mapping_value_new
= TRUE
;
2681 mapping_value
= value
;
2684 SC_log(LOG_NOTICE
, " %@ --> %@", mapping_key
, mapping_value
);
2686 if (mapping_value_new
) {
2687 CFRelease(mapping_value
);
2693 _SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs
,
2694 SCPreferencesRef targetPrefs
,
2695 CFDictionaryRef serviceMapping
,
2696 CFDictionaryRef bsdNameMapping
,
2697 CFDictionaryRef setMapping
,
2698 CFDictionaryRef serviceSetMapping
)
2700 serviceMigrationContext context
;
2701 const char *mapping_name
;
2702 Boolean success
= FALSE
;
2704 if ((sourcePrefs
== NULL
) ||
2705 (targetPrefs
== NULL
) ||
2706 !isA_CFDictionary(serviceMapping
) ||
2707 !isA_CFDictionary(bsdNameMapping
)) {
2708 SC_log(LOG_INFO
, "No sourcePrefs, targetPrefs, serviceMapping, or bsdNameMapping");
2712 if (bsdNameMapping
!= NULL
) {
2713 mapping_name
= "BSD name mapping";
2714 CFDictionaryApplyFunction(bsdNameMapping
, logMapping
, &mapping_name
);
2716 if (serviceMapping
!= NULL
) {
2717 mapping_name
= "SCNetworkService mapping";
2718 CFDictionaryApplyFunction(serviceMapping
, logMapping
, &mapping_name
);
2720 if (setMapping
!= NULL
) {
2721 mapping_name
= "SCNetworkSet mapping";
2722 CFDictionaryApplyFunction(setMapping
, logMapping
, &mapping_name
);
2724 if (serviceSetMapping
!= NULL
) {
2725 mapping_name
= "SCNetworkService/SCNetworkSet mapping";
2726 CFDictionaryApplyFunction(serviceSetMapping
, logMapping
, &mapping_name
);
2729 context
.targetPrefs
= targetPrefs
;
2730 context
.bsdNameMapping
= bsdNameMapping
;
2731 context
.setMapping
= setMapping
;
2732 context
.serviceSetMapping
= serviceSetMapping
;
2733 CFDictionaryApplyFunction(serviceMapping
, ServiceMigrationAddOrReplace
, &context
);
2741 _SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs
, SCPreferencesRef targetPrefs
)
2743 CFDictionaryRef btmm
;
2744 CFDictionaryRef btmmDSID
;
2745 CFStringRef btmmDSIDPath
;
2746 CFStringRef btmmPath
;
2747 CFStringRef computerName
;
2748 CFStringRef hostname
;
2749 CFStringRef localHostname
;
2750 CFStringEncoding nameEncoding
;
2752 SC_log(LOG_NOTICE
, "Copying \"system\" settings");
2754 if ((sourcePrefs
== NULL
) ||
2755 (targetPrefs
== NULL
)) {
2759 hostname
= SCPreferencesGetHostName(sourcePrefs
);
2760 if (hostname
!= NULL
) {
2761 SCPreferencesSetHostName(targetPrefs
, hostname
);
2762 SC_log(LOG_NOTICE
, " copied HostName");
2765 localHostname
= _SCPreferencesCopyLocalHostName(sourcePrefs
);
2766 if (localHostname
!= NULL
) {
2767 SCPreferencesSetLocalHostName(targetPrefs
, localHostname
);
2768 CFRelease(localHostname
);
2769 SC_log(LOG_NOTICE
, " copied LocalHostName");
2772 computerName
= _SCPreferencesCopyComputerName(sourcePrefs
, &nameEncoding
);
2773 if (computerName
!= NULL
) {
2774 SCPreferencesSetComputerName(targetPrefs
, computerName
, nameEncoding
);
2775 CFRelease(computerName
);
2776 SC_log(LOG_NOTICE
, " copied ComputerName");
2779 btmmPath
= CFStringCreateWithFormat(NULL
, NULL
,
2784 btmm
= SCPreferencesPathGetValue(sourcePrefs
, btmmPath
);
2786 SCPreferencesPathSetValue(targetPrefs
, btmmPath
, btmm
);
2788 CFRelease(btmmPath
);
2790 btmmDSIDPath
= CFStringCreateWithFormat(NULL
, NULL
,
2794 BACK_TO_MY_MAC_DSIDS
);
2795 btmmDSID
= SCPreferencesPathGetValue(sourcePrefs
, btmmDSIDPath
);
2796 if (btmmDSID
!= NULL
) {
2797 SCPreferencesPathSetValue(targetPrefs
, btmmDSIDPath
, btmmDSID
);
2799 CFRelease(btmmDSIDPath
);
2804 #if !TARGET_OS_IPHONE
2807 CFMutableArrayRef interfaceList
;
2808 SCPreferencesRef ni_prefs
;
2809 CFDictionaryRef bsdNameMapping
;
2810 } virtualInterfaceMemberListContext
;
2813 SCPreferencesRef prefs
;
2814 SCPreferencesRef ni_prefs
;
2815 CFDictionaryRef bsdNameMapping
;
2816 CFDictionaryRef virtualBSDNameMapping
;
2817 CFDictionaryRef mappingBSDNameToService
;
2818 CFDictionaryRef setMapping
;
2819 CFDictionaryRef serviceSetMapping
;
2820 } virtualInterfaceContext
;
2823 add_virtual_interface(const void *value
, void *context
)
2825 virtualInterfaceMemberListContext
*ctx
= (virtualInterfaceMemberListContext
*)context
;
2826 CFDictionaryRef bsdNameMapping
= ctx
->bsdNameMapping
;
2827 CFMutableArrayRef interfaceList
= ctx
->interfaceList
;
2828 CFStringRef oldInterfaceBSDName
= (CFStringRef
)value
;
2829 SCNetworkInterfaceRef newInterface
;
2830 CFStringRef newInterfaceBSDName
;
2832 SC_log(LOG_INFO
, "old BSD interface name: %@", oldInterfaceBSDName
);
2834 newInterfaceBSDName
= CFDictionaryGetValue(bsdNameMapping
, oldInterfaceBSDName
);
2835 if (newInterfaceBSDName
== NULL
) {
2838 SC_log(LOG_INFO
, "new BSD interface name: %@", newInterfaceBSDName
);
2840 newInterface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ctx
->ni_prefs
, newInterfaceBSDName
);
2841 if (newInterface
!= NULL
) {
2842 SC_log(LOG_INFO
, "adding interface to interfaceList: %@", newInterface
);
2843 CFArrayAppendValue(interfaceList
, newInterface
);
2844 CFRelease(newInterface
);
2850 add_target_bridge(const void *key
, const void *value
, void *context
)
2852 CFStringRef bridgeName
;
2853 CFDictionaryRef bridgeOptions
;
2854 virtualInterfaceContext
*ctx
= (virtualInterfaceContext
*)context
;
2855 CFDictionaryRef bridgeBSDNameMapping
= ctx
->virtualBSDNameMapping
;
2856 CFDictionaryRef bsdNameToServiceMapping
= ctx
->mappingBSDNameToService
;
2857 virtualInterfaceMemberListContext memberListContext
;
2858 CFMutableArrayRef newInterfaceList
;
2859 SCBridgeInterfaceRef newBridge
;
2860 SCBridgeInterfaceRef oldBridge
= (SCBridgeInterfaceRef
)key
;
2861 CFStringRef oldBSDName
;
2862 CFArrayRef oldInterfaceList
= (CFArrayRef
)value
;
2863 CFArrayRef oldServiceList
;
2864 SCPreferencesRef prefs
= ctx
->prefs
;
2865 CFDictionaryRef serviceSetMapping
= ctx
->serviceSetMapping
;
2866 CFDictionaryRef setMapping
= ctx
->setMapping
;
2868 newInterfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2870 memberListContext
.bsdNameMapping
= ctx
->bsdNameMapping
;
2871 memberListContext
.interfaceList
= newInterfaceList
;
2872 memberListContext
.ni_prefs
= ctx
->ni_prefs
;
2874 CFArrayApplyFunction(oldInterfaceList
, CFRangeMake(0, CFArrayGetCount(oldInterfaceList
)), add_virtual_interface
, &memberListContext
);
2876 newBridge
= SCBridgeInterfaceCreate(prefs
);
2878 if (!__SCBridgeInterfaceSetMemberInterfaces(newBridge
, newInterfaceList
)) {
2879 SC_log(LOG_NOTICE
, "__SCBridgeInterfaceSetMemberInterfaces() failed");
2881 CFRelease(newInterfaceList
);
2883 bridgeOptions
= SCBridgeInterfaceGetOptions(oldBridge
);
2884 if (bridgeOptions
!= NULL
) {
2885 SCBridgeInterfaceSetOptions(newBridge
, bridgeOptions
);
2888 bridgeName
= SCNetworkInterfaceGetLocalizedDisplayName(oldBridge
);
2890 if (bridgeName
!= NULL
) {
2891 SCBridgeInterfaceSetLocalizedDisplayName(newBridge
, bridgeName
);
2894 oldBSDName
= SCNetworkInterfaceGetBSDName(oldBridge
);
2895 if (oldBSDName
== NULL
) {
2899 oldServiceList
= CFDictionaryGetValue(bsdNameToServiceMapping
, oldBSDName
);
2900 if (oldServiceList
== NULL
) {
2904 for (CFIndex idx
= 0; idx
< CFArrayGetCount(oldServiceList
); idx
++) {
2905 SCNetworkServiceRef oldService
= CFArrayGetValueAtIndex(oldServiceList
, idx
);
2906 if (!__SCNetworkServiceMigrateNew(prefs
, oldService
, bridgeBSDNameMapping
, setMapping
, serviceSetMapping
)) {
2907 SC_log(LOG_NOTICE
, "could not migrate bridge service: %@", oldService
);
2911 CFRelease(newBridge
);
2915 _SCNetworkMigrationRemoveBridgeServices(SCPreferencesRef prefs
)
2917 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
2919 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
2920 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
2921 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
2922 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
2924 if ((bsdName
!= NULL
) &&
2925 (SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeBridge
)) {
2926 SC_log(LOG_INFO
, "removing service: %@", service
);
2927 SCNetworkServiceRemove(service
);
2930 CFRelease(services
);
2934 static CFDictionaryRef
2935 _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs
)
2937 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
2938 CFMutableDictionaryRef bridgeServices
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2940 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
2941 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
2942 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
2943 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
2945 if ((bsdName
!= NULL
) &&
2946 SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeBridge
) {
2947 CFMutableArrayRef serviceList
;
2948 if (!CFDictionaryContainsKey(bridgeServices
, bsdName
)) {
2949 serviceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2950 CFDictionaryAddValue(bridgeServices
, bsdName
, serviceList
);
2951 CFRelease(serviceList
);
2953 serviceList
= (CFMutableArrayRef
)CFDictionaryGetValue(bridgeServices
, bsdName
);
2954 CFArrayAppendValue(serviceList
, service
);
2957 CFRelease(services
);
2958 return bridgeServices
;
2963 _SCNetworkMigrationDoBridgeMigration(SCPreferencesRef sourcePrefs
,
2964 SCPreferencesRef sourceNIPrefs
,
2965 SCPreferencesRef targetPrefs
,
2966 SCPreferencesRef targetNIPrefs
,
2967 CFDictionaryRef bsdNameMapping
,
2968 CFDictionaryRef setMapping
,
2969 CFDictionaryRef serviceSetMapping
)
2971 #pragma unused(sourceNIPrefs)
2972 CFArrayRef allSourceBridges
;
2973 CFArrayRef allTargetBridges
;
2974 SCBridgeInterfaceRef bridge
;
2975 CFMutableDictionaryRef bridgeInterfaceMapping
= NULL
;
2976 CFMutableDictionaryRef bridgeMapping
;
2977 CFDictionaryRef bsdNameToBridgeServices
;
2978 virtualInterfaceContext context
;
2980 Boolean success
= FALSE
;
2982 allSourceBridges
= SCBridgeInterfaceCopyAll(sourcePrefs
);
2983 allTargetBridges
= SCBridgeInterfaceCopyAll(targetPrefs
);
2985 bsdNameToBridgeServices
= _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(sourcePrefs
);
2987 bridgeInterfaceMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2988 bridgeMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2990 // Create Bridge Interface Mapping
2991 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allSourceBridges
); idx
++) {
2992 bridge
= CFArrayGetValueAtIndex(allSourceBridges
, idx
);
2993 CFArrayRef bridgeMembers
= SCBridgeInterfaceGetMemberInterfaces(bridge
);
2994 CFMutableArrayRef interfaceList
;
2996 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2997 for (CFIndex idx2
= 0; idx2
< CFArrayGetCount(bridgeMembers
); idx2
++) {
2998 CFStringRef interfaceName
= NULL
;
2999 SCNetworkInterfaceRef interface
= NULL
;
3001 interface
= CFArrayGetValueAtIndex(bridgeMembers
, idx2
);
3002 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3004 if (CFDictionaryContainsKey(bsdNameMapping
, interfaceName
)) {
3005 CFStringRef bridgeNewName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("bridge%ld"), count
);
3006 CFDictionaryAddValue(bridgeMapping
, interfaceName
, bridgeNewName
);
3007 CFArrayAppendValue(interfaceList
, interfaceName
);
3008 CFRelease(bridgeNewName
);
3012 if (CFArrayGetCount(interfaceList
) > 0) {
3013 CFDictionaryAddValue(bridgeInterfaceMapping
, bridge
, interfaceList
);
3015 CFRelease(interfaceList
);
3017 // Remove bridge services from target
3018 _SCNetworkMigrationRemoveBridgeServices(targetPrefs
);
3020 // Remove Target Bridges
3021 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allTargetBridges
); idx
++) {
3022 bridge
= CFArrayGetValueAtIndex(allTargetBridges
, idx
);
3023 if (!SCBridgeInterfaceRemove(bridge
)) {
3024 SC_log(LOG_NOTICE
, "SCBridgeInterfaceRemove() failed: %@", bridge
);
3029 context
.prefs
= targetPrefs
;
3030 context
.ni_prefs
= targetNIPrefs
;
3031 context
.bsdNameMapping
= bsdNameMapping
;
3032 context
.virtualBSDNameMapping
= bridgeMapping
;
3033 context
.mappingBSDNameToService
= bsdNameToBridgeServices
;
3034 context
.setMapping
= setMapping
;
3035 context
.serviceSetMapping
= serviceSetMapping
;
3037 // Add Bridge configurations at the target using mapping
3038 CFDictionaryApplyFunction(bridgeInterfaceMapping
, add_target_bridge
, &context
);
3042 CFRelease(allSourceBridges
);
3043 CFRelease(allTargetBridges
);
3044 CFRelease(bridgeInterfaceMapping
);
3045 CFRelease(bridgeMapping
);
3046 CFRelease(bsdNameToBridgeServices
);
3052 add_target_bond(const void *key
, const void *value
, void *context
)
3054 CFNumberRef bondMode
;
3055 CFStringRef bondName
;
3056 CFDictionaryRef bondOptions
;
3057 virtualInterfaceContext
*ctx
= (virtualInterfaceContext
*)context
;
3058 CFDictionaryRef bondBSDNameMapping
= ctx
->virtualBSDNameMapping
;
3059 CFDictionaryRef bsdNameToServiceMapping
= ctx
->mappingBSDNameToService
;
3060 virtualInterfaceMemberListContext memberListContext
;
3061 CFMutableArrayRef newInterfaceList
;
3062 SCBondInterfaceRef newBond
;
3063 SCBondInterfaceRef oldBond
= (SCBondInterfaceRef
)key
;
3064 CFStringRef oldBSDName
;
3065 CFArrayRef oldInterfaceList
= (CFArrayRef
)value
;
3066 CFArrayRef oldServiceList
;
3067 SCPreferencesRef prefs
= ctx
->prefs
;
3068 CFDictionaryRef serviceSetMapping
= ctx
->serviceSetMapping
;
3069 CFDictionaryRef setMapping
= ctx
->setMapping
;
3071 newInterfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3073 memberListContext
.bsdNameMapping
= ctx
->bsdNameMapping
;
3074 memberListContext
.interfaceList
= newInterfaceList
;
3075 memberListContext
.ni_prefs
= ctx
->ni_prefs
;
3077 CFArrayApplyFunction(oldInterfaceList
, CFRangeMake(0, CFArrayGetCount(oldInterfaceList
)), add_virtual_interface
, &memberListContext
);
3079 newBond
= SCBondInterfaceCreate(prefs
);
3080 if (!__SCBondInterfaceSetMemberInterfaces(newBond
, newInterfaceList
)) {
3081 SC_log(LOG_NOTICE
, "__SCBondInterfaceSetMemberInterfaces() failed");
3083 CFRelease(newInterfaceList
);
3085 bondOptions
= SCBondInterfaceGetOptions(oldBond
);
3086 if (bondOptions
!= NULL
) {
3087 SCBondInterfaceSetOptions(newBond
, bondOptions
);
3090 bondName
= SCNetworkInterfaceGetLocalizedDisplayName(oldBond
);
3091 if (bondName
!= NULL
) {
3092 SCBondInterfaceSetLocalizedDisplayName(newBond
, bondName
);
3095 bondMode
= SCBondInterfaceGetMode(oldBond
);
3096 if (bondMode
!= NULL
) {
3097 SCBondInterfaceSetMode(newBond
, bondMode
);
3099 oldBSDName
= SCNetworkInterfaceGetBSDName(oldBond
);
3100 if (oldBSDName
== NULL
) {
3104 oldServiceList
= CFDictionaryGetValue(bsdNameToServiceMapping
, oldBSDName
);
3105 if (oldServiceList
== NULL
) {
3109 for (CFIndex idx
= 0; idx
< CFArrayGetCount(oldServiceList
); idx
++) {
3110 SCNetworkServiceRef oldService
= CFArrayGetValueAtIndex(oldServiceList
, idx
);
3111 if (!__SCNetworkServiceMigrateNew(prefs
, oldService
, bondBSDNameMapping
, setMapping
, serviceSetMapping
)) {
3112 SC_log(LOG_NOTICE
, "could not migrate bond service: %@", oldService
);
3120 _SCNetworkMigrationRemoveBondServices(SCPreferencesRef prefs
)
3122 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
3124 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
3125 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
3126 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
3127 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3129 if ((bsdName
!= NULL
) &&
3130 SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeBond
) {
3131 SCNetworkServiceRemove(service
);
3134 CFRelease(services
);
3138 static CFDictionaryRef
3139 _SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs
)
3141 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
3142 CFMutableDictionaryRef bondServices
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3144 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
3145 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
3146 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
3147 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3149 if ((bsdName
!= NULL
) &&
3150 SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeBond
) {
3151 CFMutableArrayRef serviceList
;
3152 if (!CFDictionaryContainsKey(bondServices
, bsdName
)) {
3153 serviceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3154 CFDictionaryAddValue(bondServices
, bsdName
, serviceList
);
3155 CFRelease(serviceList
);
3157 serviceList
= (CFMutableArrayRef
)CFDictionaryGetValue(bondServices
, bsdName
);
3158 CFArrayAppendValue(serviceList
, service
);
3161 CFRelease(services
);
3162 return bondServices
;
3167 _SCNetworkMigrationDoBondMigration(SCPreferencesRef sourcePrefs
,
3168 SCPreferencesRef sourceNIPrefs
,
3169 SCPreferencesRef targetPrefs
,
3170 SCPreferencesRef targetNIPrefs
,
3171 CFDictionaryRef bsdNameMapping
,
3172 CFDictionaryRef setMapping
,
3173 CFDictionaryRef serviceSetMapping
)
3175 #pragma unused(sourceNIPrefs)
3176 CFArrayRef allSourceBonds
;
3177 CFArrayRef allTargetBonds
;
3178 SCBondInterfaceRef bond
;
3179 CFMutableDictionaryRef bondInterfaceMapping
= NULL
;
3180 CFMutableDictionaryRef bondMapping
;
3181 CFDictionaryRef bsdNameToBondServices
;
3182 virtualInterfaceContext context
;
3184 Boolean success
= FALSE
;
3186 allSourceBonds
= SCBondInterfaceCopyAll(sourcePrefs
);
3187 allTargetBonds
= SCBondInterfaceCopyAll(targetPrefs
);
3189 bsdNameToBondServices
= _SCNetworkMigrationCopyMappingBSDNameToBondServices(sourcePrefs
);
3191 bondInterfaceMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3192 bondMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3193 // Create Bond Interface mapping
3194 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allSourceBonds
); idx
++) {
3195 bond
= CFArrayGetValueAtIndex(allSourceBonds
, idx
);
3196 CFArrayRef bondMembers
= SCBondInterfaceGetMemberInterfaces(bond
);
3197 CFMutableArrayRef interfaceList
;
3199 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3200 for (CFIndex idx2
= 0; idx2
< CFArrayGetCount(bondMembers
); idx2
++) {
3201 CFStringRef interfaceName
;
3202 SCNetworkInterfaceRef interface
;
3204 interface
= CFArrayGetValueAtIndex(bondMembers
, idx2
);
3205 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3207 if (CFDictionaryContainsKey(bsdNameMapping
, interfaceName
)) {
3208 CFStringRef bondNewName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("bond%ld"), count
);
3209 CFDictionaryAddValue(bondMapping
, interfaceName
, bondNewName
);
3210 CFArrayAppendValue(interfaceList
, interfaceName
);
3211 CFRelease(bondNewName
);
3215 if (CFArrayGetCount(interfaceList
) > 0) {
3216 CFDictionaryAddValue(bondInterfaceMapping
, bond
, interfaceList
);
3218 CFRelease(interfaceList
);
3220 // Remove bond services from target
3221 _SCNetworkMigrationRemoveBondServices(targetPrefs
);
3223 // Remove Target Bonds
3224 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allTargetBonds
); idx
++) {
3225 bond
= CFArrayGetValueAtIndex(allTargetBonds
, idx
);
3226 if (!SCBondInterfaceRemove(bond
)) {
3227 SC_log(LOG_NOTICE
, "SCBondInterfaceRemove() failed: %@", bond
);
3232 context
.prefs
= targetPrefs
;
3233 context
.ni_prefs
= targetNIPrefs
;
3234 context
.bsdNameMapping
= bsdNameMapping
;
3235 context
.virtualBSDNameMapping
= bondMapping
;
3236 context
.mappingBSDNameToService
= bsdNameToBondServices
;
3237 context
.setMapping
= setMapping
;
3238 context
.serviceSetMapping
= serviceSetMapping
;
3240 // Add Bond configurations at the target using mapping
3241 CFDictionaryApplyFunction(bondInterfaceMapping
, add_target_bond
, &context
);
3245 CFRelease(allSourceBonds
);
3246 CFRelease(allTargetBonds
);
3247 CFRelease(bondInterfaceMapping
);
3248 CFRelease(bondMapping
);
3249 CFRelease(bsdNameToBondServices
);
3254 add_target_vlan(const void *value
, void *context
)
3256 CFDictionaryRef bsdNameMapping
;
3257 virtualInterfaceContext
*ctx
= (virtualInterfaceContext
*)context
;
3258 CFDictionaryRef bsdNameToServiceMapping
= ctx
->mappingBSDNameToService
;
3259 SCPreferencesRef prefs
= ctx
->prefs
;
3260 SCVLANInterfaceRef newVLAN
= NULL
;
3261 SCNetworkInterfaceRef newPhysicalInterface
= NULL
;
3262 CFStringRef newPhysicalInterfaceName
;
3263 SCVLANInterfaceRef oldVLAN
= (SCVLANInterfaceRef
)value
;
3264 CFStringRef oldBSDName
;
3265 SCNetworkInterfaceRef oldPhysicalInterface
;
3266 CFStringRef oldPhysicalInterfaceName
;
3267 SCNetworkServiceRef oldService
;
3268 CFArrayRef oldServiceList
;
3269 CFDictionaryRef serviceSetMapping
= ctx
->serviceSetMapping
;
3270 CFDictionaryRef setMapping
= ctx
->setMapping
;
3271 CFDictionaryRef vlanBSDNameMapping
= ctx
->virtualBSDNameMapping
;
3272 CFNumberRef vlanTag
;
3273 CFStringRef vlanName
;
3274 CFDictionaryRef vlanOptions
;
3276 bsdNameMapping
= ctx
->bsdNameMapping
;
3278 oldPhysicalInterface
= SCVLANInterfaceGetPhysicalInterface(oldVLAN
);
3279 if (oldPhysicalInterface
== NULL
) {
3280 SC_log(LOG_NOTICE
, "No old VLAN physical interface");
3284 oldPhysicalInterfaceName
= SCNetworkInterfaceGetBSDName(oldPhysicalInterface
);
3285 if (oldPhysicalInterfaceName
== NULL
) {
3286 SC_log(LOG_NOTICE
, "No old VLAN physical interface name");
3290 newPhysicalInterfaceName
= CFDictionaryGetValue(bsdNameMapping
, oldPhysicalInterfaceName
);
3291 if (newPhysicalInterfaceName
== NULL
) {
3292 SC_log(LOG_NOTICE
, "No new VLAN physical interface name");
3295 newPhysicalInterface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ctx
->ni_prefs
, newPhysicalInterfaceName
);
3296 if (newPhysicalInterface
== NULL
) {
3297 SC_log(LOG_NOTICE
, "Could not create new VLAN physical interface");
3301 vlanTag
= SCVLANInterfaceGetTag(oldVLAN
);
3302 if (vlanTag
== NULL
) {
3303 SC_log(LOG_NOTICE
, "No old VLAN interface tag");
3307 newVLAN
= SCVLANInterfaceCreate(prefs
, newPhysicalInterface
, vlanTag
);
3308 if (newVLAN
== NULL
) {
3309 SC_log(LOG_NOTICE
, "Could not create new VLAN interface");
3313 vlanName
= SCNetworkInterfaceGetLocalizedDisplayName(oldVLAN
);
3314 if (vlanName
!= NULL
) {
3315 SCVLANInterfaceSetLocalizedDisplayName(newVLAN
, vlanName
);
3318 vlanOptions
= SCVLANInterfaceGetOptions(oldVLAN
);
3319 if (vlanOptions
!= NULL
) {
3320 SCVLANInterfaceSetOptions(newVLAN
, vlanOptions
);
3322 oldBSDName
= SCNetworkInterfaceGetBSDName(oldVLAN
);
3324 if (oldBSDName
== NULL
) {
3328 oldServiceList
= CFDictionaryGetValue(bsdNameToServiceMapping
, oldBSDName
);
3329 if (oldServiceList
== NULL
) {
3333 for (CFIndex idx
= 0; idx
< CFArrayGetCount(oldServiceList
); idx
++) {
3334 oldService
= CFArrayGetValueAtIndex(oldServiceList
, idx
);
3335 if (!__SCNetworkServiceMigrateNew(prefs
, oldService
, vlanBSDNameMapping
, setMapping
, serviceSetMapping
)) {
3336 SC_log(LOG_NOTICE
, "Could not migrate VLAN service: %@", oldService
);
3341 if (newPhysicalInterface
!= NULL
) {
3342 CFRelease(newPhysicalInterface
);
3344 if (newVLAN
!= NULL
) {
3350 _SCNetworkMigrationRemoveVLANServices(SCPreferencesRef prefs
)
3352 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
3354 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
3355 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
3356 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
3357 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3359 if ((bsdName
!= NULL
) &&
3360 SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeVLAN
) {
3361 SCNetworkServiceRemove(service
);
3365 CFRelease(services
);
3369 static CFDictionaryRef
3370 _SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs
)
3372 CFArrayRef services
= SCNetworkServiceCopyAll(prefs
);
3373 CFMutableDictionaryRef vlanServices
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3375 for (CFIndex idx
= 0; idx
< CFArrayGetCount(services
); idx
++) {
3376 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(services
, idx
);
3377 SCNetworkInterfaceRef interface
= SCNetworkServiceGetInterface(service
);
3378 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3380 if ((bsdName
!= NULL
) &&
3381 SCNetworkInterfaceGetInterfaceType(interface
) == kSCNetworkInterfaceTypeVLAN
) {
3382 CFMutableArrayRef serviceList
;
3383 if (!CFDictionaryContainsKey(vlanServices
, bsdName
)) {
3384 serviceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3385 CFDictionaryAddValue(vlanServices
, bsdName
, serviceList
);
3386 CFRelease(serviceList
);
3388 serviceList
= (CFMutableArrayRef
)CFDictionaryGetValue(vlanServices
, bsdName
);
3389 CFArrayAppendValue(serviceList
, service
);
3392 CFRelease(services
);
3393 return vlanServices
;
3397 _SCNetworkMigrationDoVLANMigration(SCPreferencesRef sourcePrefs
,
3398 SCPreferencesRef sourceNIPrefs
,
3399 SCPreferencesRef targetPrefs
,
3400 SCPreferencesRef targetNIPrefs
,
3401 CFDictionaryRef bsdNameMapping
,
3402 CFDictionaryRef setMapping
,
3403 CFDictionaryRef serviceSetMapping
)
3405 #pragma unused(sourceNIPrefs)
3406 CFArrayRef allSourceVLAN
;
3407 CFArrayRef allTargetVLAN
;
3408 virtualInterfaceContext context
;
3410 Boolean success
= FALSE
;
3411 SCVLANInterfaceRef vlan
;
3412 CFMutableArrayRef vlanList
;
3413 CFMutableDictionaryRef vlanMapping
;
3414 CFDictionaryRef bsdNameToVLANServices
;
3416 allSourceVLAN
= SCVLANInterfaceCopyAll(sourcePrefs
);
3417 allTargetVLAN
= SCVLANInterfaceCopyAll(targetPrefs
);
3419 bsdNameToVLANServices
= _SCNetworkMigrationCopyMappingBSDNameToVLANServices(sourcePrefs
);
3421 vlanList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3422 vlanMapping
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3424 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allSourceVLAN
); idx
++) {
3425 vlan
= CFArrayGetValueAtIndex(allSourceVLAN
, idx
);
3426 CFStringRef vlanBSDName
= SCNetworkInterfaceGetBSDName(vlan
);
3427 SCNetworkInterfaceRef physicalInterface
= SCVLANInterfaceGetPhysicalInterface(vlan
);
3428 CFStringRef physicalInterfaceName
= SCNetworkInterfaceGetBSDName(physicalInterface
);
3430 // Add VLAN to be migrated if the mapping between interfaces exists
3431 if (CFDictionaryContainsKey(bsdNameMapping
, physicalInterfaceName
)) {
3432 CFStringRef vlanNewName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("vlan%ld"), count
);
3433 CFDictionaryAddValue(vlanMapping
, vlanBSDName
, vlanNewName
);
3434 CFArrayAppendValue(vlanList
, vlan
);
3435 CFRelease(vlanNewName
);
3439 // Remove vlan services from target
3440 _SCNetworkMigrationRemoveVLANServices(targetPrefs
);
3442 // Remove Target VLANs
3443 for (CFIndex idx
= 0; idx
< CFArrayGetCount(allTargetVLAN
); idx
++) {
3444 vlan
= CFArrayGetValueAtIndex(allTargetVLAN
, idx
);
3445 if (!SCVLANInterfaceRemove(vlan
)) {
3446 SC_log(LOG_NOTICE
, "SCVLANInterfaceRemove() failed: %@", vlan
);
3451 context
.prefs
= targetPrefs
;
3452 context
.ni_prefs
= targetNIPrefs
;
3453 context
.bsdNameMapping
= bsdNameMapping
;
3454 context
.virtualBSDNameMapping
= vlanMapping
;
3455 context
.mappingBSDNameToService
= bsdNameToVLANServices
;
3456 context
.setMapping
= setMapping
;
3457 context
.serviceSetMapping
= serviceSetMapping
;
3459 // Add VLAN configurations at the target using vlanList
3460 CFArrayApplyFunction(vlanList
, CFRangeMake(0, CFArrayGetCount(vlanList
)), add_target_vlan
, &context
);
3464 CFRelease(allSourceVLAN
);
3465 CFRelease(allTargetVLAN
);
3466 CFRelease(vlanList
);
3467 CFRelease(vlanMapping
);
3468 CFRelease(bsdNameToVLANServices
);
3473 _SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePrefs
,
3474 SCPreferencesRef sourceNIPrefs
,
3475 SCPreferencesRef targetPrefs
,
3476 SCPreferencesRef targetNIPrefs
,
3477 CFDictionaryRef bsdNameMapping
,
3478 CFDictionaryRef setMapping
,
3479 CFDictionaryRef serviceSetMapping
)
3482 if (!_SCNetworkMigrationDoBridgeMigration(sourcePrefs
, sourceNIPrefs
,
3483 targetPrefs
, targetNIPrefs
,
3484 bsdNameMapping
, setMapping
, serviceSetMapping
)) {
3485 SC_log(LOG_NOTICE
, "Bridge migration failed");
3489 if (!_SCNetworkMigrationDoBondMigration(sourcePrefs
, sourceNIPrefs
,
3490 targetPrefs
, targetNIPrefs
,
3491 bsdNameMapping
, setMapping
, serviceSetMapping
)) {
3492 SC_log(LOG_NOTICE
, "Bond migration failed");
3496 if (!_SCNetworkMigrationDoVLANMigration(sourcePrefs
, sourceNIPrefs
,
3497 targetPrefs
, targetNIPrefs
,
3498 bsdNameMapping
, setMapping
, serviceSetMapping
)) {
3499 SC_log(LOG_NOTICE
, "VLAN migration failed");
3503 #endif // !TARGET_OS_IPHONE
3506 SCPreferencesRef prefs
;
3507 CFArrayRef serviceOrder
;
3508 CFMutableArrayRef serviceOrderMutable
;
3510 } migrated_service_context
;
3513 create_migrated_order(const void *value
, void *context
)
3515 migrated_service_context
*ctx
= (migrated_service_context
*)context
;
3516 CFMutableArrayRef migratedServiceOrder
= ctx
->serviceOrderMutable
;
3517 CFArrayRef targetServiceOrder
= ctx
->serviceOrder
;
3518 CFStringRef migratedServiceID
= (CFStringRef
)value
;
3519 Boolean
*success
= ctx
->success
;
3521 if (*success
== FALSE
) {
3525 // Preserving the service order in the source configuration for the services
3526 // which were migrated into the target configuration
3527 for (CFIndex idx
= 0; idx
< CFArrayGetCount(targetServiceOrder
); idx
++) {
3528 CFStringRef targetServiceID
= CFArrayGetValueAtIndex(targetServiceOrder
, idx
);
3529 if (CFEqual(migratedServiceID
, targetServiceID
)) {
3530 CFArrayAppendValue(migratedServiceOrder
, migratedServiceID
);
3537 SCPreferencesRef prefs
;
3538 CFMutableArrayRef serviceListMutable
;
3539 CFArrayRef serviceOrder
;
3541 } non_migrated_service_context
;
3544 create_non_migrated_service_list(const void *value
, void *context
)
3546 non_migrated_service_context
*ctx
= (non_migrated_service_context
*)context
;
3547 CFArrayRef migratedServiceOrder
= ctx
->serviceOrder
;
3548 CFMutableArrayRef nonMigratedService
= ctx
->serviceListMutable
;
3549 SCPreferencesRef prefs
= ctx
->prefs
;
3550 SCNetworkServiceRef service
;
3551 Boolean
*success
= ctx
->success
;
3552 CFStringRef targetServiceID
= (CFStringRef
)value
;
3554 if (*success
== FALSE
) {
3558 // Adding all services not present in migratedServiceOrder into nonMigrated service
3559 if (CFArrayGetFirstIndexOfValue(migratedServiceOrder
,
3560 CFRangeMake(0, CFArrayGetCount(migratedServiceOrder
)),
3561 targetServiceID
) != kCFNotFound
) {
3562 // if service already present
3566 service
= SCNetworkServiceCopy(prefs
, targetServiceID
);
3567 if (service
== NULL
) {
3572 CFArrayAppendValue(nonMigratedService
, service
);
3577 preserve_service_order(const void *key
, const void *value
, void *context
)
3579 migrated_service_context migrated_context
;
3580 CFMutableArrayRef migratedServiceOrder
;
3581 non_migrated_service_context non_migrated_context
;
3582 CFMutableArrayRef nonMigratedServices
;
3583 SCNetworkSetRef sourceSet
= (SCNetworkSetRef
)key
;
3584 CFArrayRef sourceServiceOrder
= NULL
;
3585 Boolean
*success
= (Boolean
*)context
;
3586 SCNetworkSetRef targetSet
= (SCNetworkSetRef
)value
;
3587 SCNetworkSetPrivateRef targetPrivate
= (SCNetworkSetPrivateRef
)targetSet
;
3588 CFArrayRef targetServiceOrder
= NULL
;
3590 if (*success
== FALSE
) {
3594 migratedServiceOrder
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3595 nonMigratedServices
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3597 sourceServiceOrder
= SCNetworkSetGetServiceOrder(sourceSet
);
3598 if (sourceServiceOrder
== NULL
) {
3601 targetServiceOrder
= SCNetworkSetGetServiceOrder(targetSet
);
3602 if (targetServiceOrder
== NULL
) {
3606 migrated_context
.prefs
= NULL
;
3607 migrated_context
.serviceOrder
= targetServiceOrder
;
3608 migrated_context
.serviceOrderMutable
= migratedServiceOrder
;
3609 migrated_context
.success
= success
;
3611 // Creating a list of service IDs which were migrated in the target set
3612 // while maintaining the service order of the source set
3613 CFArrayApplyFunction(sourceServiceOrder
, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder
)), create_migrated_order
, &migrated_context
);
3614 if (*success
== FALSE
) {
3618 non_migrated_context
.prefs
= targetPrivate
->prefs
;
3619 non_migrated_context
.serviceOrder
= migratedServiceOrder
;
3620 non_migrated_context
.serviceListMutable
= nonMigratedServices
;
3621 non_migrated_context
.success
= success
;
3623 // Creating a list of all the services which were not migrated from the
3624 // source set to the target set
3625 CFArrayApplyFunction(targetServiceOrder
, CFRangeMake(0, CFArrayGetCount(targetServiceOrder
)), create_non_migrated_service_list
, &non_migrated_context
);
3627 // Remove non migrated service
3628 for (CFIndex idx
= 0; idx
< CFArrayGetCount(nonMigratedServices
); idx
++) {
3629 SCNetworkServiceRef service
= CFArrayGetValueAtIndex(nonMigratedServices
, idx
);
3630 SCNetworkSetRemoveService(targetSet
, service
);
3633 // Set migrated service order
3634 SCNetworkSetSetServiceOrder(targetSet
, migratedServiceOrder
);
3636 // Add non migrated services
3637 for (CFIndex idx
= 0; idx
< CFArrayGetCount(nonMigratedServices
); idx
++) {
3639 SCNetworkServiceRef service
;
3641 service
= CFArrayGetValueAtIndex(nonMigratedServices
, idx
);
3642 ok
= SCNetworkSetAddService(targetSet
, service
);
3644 CFStringRef bsdName
;
3645 SCNetworkInterfaceRef interface
;
3647 interface
= SCNetworkServiceGetInterface(service
);
3648 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3649 SC_log(LOG_NOTICE
, "preserve_service_order(): could not add service: %s"
3650 "\n serviceID = %@, interface = %@",
3651 SCErrorString(SCError()),
3652 SCNetworkServiceGetServiceID(service
),
3653 bsdName
!= NULL
? bsdName
: CFSTR("?"));
3658 CFRelease(migratedServiceOrder
);
3659 CFRelease(nonMigratedServices
);
3665 _SCNetworkMigrationDoServiceOrderMigration(SCPreferencesRef sourcePrefs
,
3666 SCPreferencesRef targetPrefs
,
3667 CFDictionaryRef setMapping
)
3669 #pragma unused(sourcePrefs)
3670 #pragma unused(targetPrefs)
3671 Boolean success
= TRUE
;
3673 if (!isA_CFDictionary(setMapping
)) {
3677 CFDictionaryApplyFunction(setMapping
, preserve_service_order
, &success
);
3682 // This is a function that looks at source and target network configuration
3683 // and determines what network configurations can be transferred from source to
3686 _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir
, CFURLRef targetDir
)
3688 CFDictionaryRef bsdNameMapping
= NULL
; // Mapping between BSD name and SCNetworkInterfaceRef to help with mapping services
3689 CFMutableDictionaryRef builtinMapping
= NULL
; // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
3690 CFMutableDictionaryRef externalMapping
= NULL
; // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
3691 Boolean migrationSuccess
= FALSE
;
3692 CFArrayRef newTargetNetworkInterfaceEntity
= NULL
; // Array of Interface Entity which used to create new target interfaces created during migration
3693 CFDictionaryRef serviceMapping
= NULL
; // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef)
3694 CFDictionaryRef setMapping
= NULL
;
3695 CFDictionaryRef sourceServiceSetMapping
= NULL
;
3696 CFArrayRef sourceConfigurationFiles
= NULL
; // Path to the source configuration files which need to be migrated
3697 CFStringRef sourceModel
= NULL
;
3698 CFURLRef sourceNetworkInterfaceFile
= NULL
; // Source CFURLRef for preferences.plist and NetworkInterfaces.plist
3699 char sourceNetworkInterfaceFileStr
[PATH_MAX
];
3700 CFStringRef sourceNetworkInterfaceFileString
= NULL
; // Source CFStringRef for preferences.plist and NetworkInterfaces.plist
3701 SCPreferencesRef sourceNetworkInterfacePrefs
= NULL
; // Source SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
3702 CFURLRef sourcePreferencesFile
= NULL
;
3703 char sourcePreferencesFileStr
[PATH_MAX
];
3704 CFStringRef sourcePreferencesFileString
= NULL
;
3705 SCPreferencesRef sourcePrefs
= NULL
;
3707 CFArrayRef targetConfigurationFiles
= NULL
; // Path to the target configuration files where migration will take place to
3708 Boolean targetConfigurationFilesPresent
;
3709 CFStringRef targetModel
= NULL
;
3710 CFURLRef targetNetworkInterfaceFile
= NULL
; // Target CFURLRef for preferences.plist and NetworkInterfaces.plist
3711 char targetNetworkInterfaceFileStr
[PATH_MAX
];
3712 CFStringRef targetNetworkInterfaceFileString
= NULL
; // Target CFStringRef for preferences.plist and NetworkInterfaces.plist
3713 SCPreferencesRef targetNetworkInterfacePrefs
= NULL
; // Target SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
3714 CFURLRef targetPreferencesFile
= NULL
;
3715 char targetPreferencesFileStr
[PATH_MAX
];
3716 CFStringRef targetPreferencesFileString
= NULL
;
3717 SCPreferencesRef targetPrefs
= NULL
;
3718 Boolean isUpgradeScenario
= FALSE
;
3719 CFMutableDictionaryRef validityOptions
= NULL
;
3721 // Check if configuration files exist in sourceDir
3722 if (!__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir
, &sourceConfigurationFiles
, TRUE
)) {
3723 SC_log(LOG_NOTICE
, "sourceDir: (%@) missing configuration files", sourceDir
);
3727 sourcePreferencesFile
= CFArrayGetValueAtIndex(sourceConfigurationFiles
, PREFERENCES_PLIST_INDEX
);
3728 if (!CFURLGetFileSystemRepresentation(sourcePreferencesFile
, TRUE
, (UInt8
*)sourcePreferencesFileStr
, sizeof(sourcePreferencesFileStr
))) {
3729 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", sourcePreferencesFile
);
3733 sourceNetworkInterfaceFile
= CFArrayGetValueAtIndex(sourceConfigurationFiles
, NETWORK_INTERFACES_PLIST_INDEX
);
3734 if (!CFURLGetFileSystemRepresentation(sourceNetworkInterfaceFile
, TRUE
, (UInt8
*)sourceNetworkInterfaceFileStr
, sizeof(sourceNetworkInterfaceFileStr
))) {
3735 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", sourceNetworkInterfaceFile
);
3739 sourcePreferencesFileString
= CFStringCreateWithCString(NULL
, sourcePreferencesFileStr
, kCFStringEncodingUTF8
);
3740 sourceNetworkInterfaceFileString
= CFStringCreateWithCString(NULL
, sourceNetworkInterfaceFileStr
, kCFStringEncodingUTF8
);
3742 sourcePrefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, sourcePreferencesFileString
);
3743 sourceNetworkInterfacePrefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, sourceNetworkInterfaceFileString
);
3744 if ((sourcePrefs
== NULL
) || (sourceNetworkInterfacePrefs
== NULL
)) {
3748 targetConfigurationFilesPresent
= __SCNetworkConfigurationMigrateConfigurationFilesPresent(targetDir
, &targetConfigurationFiles
, FALSE
);
3749 if (!targetConfigurationFilesPresent
) {
3750 // if the expected configuration files are not present in the target directory
3751 if (targetConfigurationFiles
== NULL
) {
3752 // but we don't know what files are needed (no target URL)
3753 SC_log(LOG_NOTICE
, "targetConfigurationFiles is NULL");
3758 targetPreferencesFile
= CFArrayGetValueAtIndex(targetConfigurationFiles
, PREFERENCES_PLIST_INDEX
);
3759 if (!CFURLGetFileSystemRepresentation(targetPreferencesFile
, TRUE
, (UInt8
*)targetPreferencesFileStr
, sizeof(targetPreferencesFileStr
))) {
3760 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", targetPreferencesFile
);
3763 targetNetworkInterfaceFile
= CFArrayGetValueAtIndex(targetConfigurationFiles
, NETWORK_INTERFACES_PLIST_INDEX
);
3764 if (!CFURLGetFileSystemRepresentation(targetNetworkInterfaceFile
, TRUE
, (UInt8
*)targetNetworkInterfaceFileStr
, sizeof(targetNetworkInterfaceFileStr
))) {
3765 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", targetNetworkInterfaceFile
);
3769 targetPreferencesFileString
= CFStringCreateWithCString(NULL
, targetPreferencesFileStr
, kCFStringEncodingUTF8
);
3770 targetNetworkInterfaceFileString
= CFStringCreateWithCString(NULL
, targetNetworkInterfaceFileStr
, kCFStringEncodingUTF8
);
3772 if (targetConfigurationFilesPresent
) {
3773 targetPrefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, targetPreferencesFileString
);
3774 targetNetworkInterfacePrefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, targetNetworkInterfaceFileString
);
3775 if ((targetPrefs
== NULL
) || (targetNetworkInterfacePrefs
== NULL
)) {
3776 SC_log(LOG_NOTICE
, "Could not open target prefs/ni_prefs");
3780 // create and populate a new preferences.plist
3781 targetPrefs
= SCPreferencesCreate(NULL
, PLUGIN_ID
, targetPreferencesFileString
);
3782 __SCNetworkPopulateDefaultPrefs(targetPrefs
);
3784 // create and populate a new NetworkInterfaces.plist
3785 targetNetworkInterfacePrefs
= SCPreferencesCreateCompanion(targetPrefs
, INTERFACES_DEFAULT_CONFIG
);
3786 __SCNetworkPopulateDefaultNIPrefs(targetNetworkInterfacePrefs
);
3788 validityOptions
= CFDictionaryCreateMutable(NULL
, 0,
3789 &kCFTypeDictionaryKeyCallBacks
,
3790 &kCFTypeDictionaryValueCallBacks
);
3791 CFDictionaryAddValue(validityOptions
, kSCNetworkConfigurationRepair
, kCFBooleanTrue
);
3793 // Setting Bypass Interface to avoid looking at system interfaces
3794 _SCNetworkConfigurationSetBypassSystemInterfaces(sourcePrefs
, TRUE
);
3795 _SCNetworkConfigurationSetBypassSystemInterfaces(targetPrefs
, TRUE
);
3797 sourceModel
= SCPreferencesGetValue(sourcePrefs
, MODEL
);
3798 targetModel
= SCPreferencesGetValue(targetPrefs
, MODEL
);
3799 isUpgradeScenario
= (isA_CFString(sourceModel
) && isA_CFString(targetModel
) && CFEqual(sourceModel
, targetModel
));
3800 if (isUpgradeScenario
) {
3801 SC_log(LOG_NOTICE
, "Migrating network configuration: performing an \"upgrade\"");
3803 SC_log(LOG_NOTICE
, "Migrating network configuration: performing a \"migration\"");
3808 "\n sourceNetworkInterfacePrefs = %@"
3809 "\n targetPrefs = %@%s"
3810 "\n targetNetworkInterfacePrefs = %@%s",
3812 sourceNetworkInterfacePrefs
,
3814 targetConfigurationFilesPresent
? "" : ", new",
3815 targetNetworkInterfacePrefs
,
3816 targetConfigurationFilesPresent
? "" : ", new");
3818 // create backup of migration source
3819 suffix
= CFStringCreateWithFormat(NULL
, NULL
,
3820 CFSTR("pre-%s-source"),
3821 isUpgradeScenario
? "upgrade" : "migration");
3822 __SCNetworkConfigurationBackup(sourcePrefs
, suffix
, targetPrefs
);
3823 __SCNetworkConfigurationBackup(sourceNetworkInterfacePrefs
, suffix
, targetPrefs
);
3826 // create backup of migration target
3827 suffix
= CFStringCreateWithFormat(NULL
, NULL
,
3828 CFSTR("pre-%s-%starget"),
3829 isUpgradeScenario
? "upgrade" : "migration",
3830 targetConfigurationFilesPresent
? "" : "new-");
3831 __SCNetworkConfigurationBackup(targetPrefs
, suffix
, targetPrefs
);
3832 __SCNetworkConfigurationBackup(targetNetworkInterfacePrefs
, suffix
, targetPrefs
);
3835 // Create services for builtin interfaces at source if they don't exist
3836 (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(sourcePrefs
, sourceNetworkInterfacePrefs
);
3837 // Checking validity of the source and destination preferences before continuing
3838 if (!_SCNetworkConfigurationCheckValidityWithPreferences(sourcePrefs
,
3839 sourceNetworkInterfacePrefs
,
3841 SC_log(LOG_NOTICE
, "Source configuration not valid");
3842 goto skipServiceMigration
;
3844 // Only call this function if configuration files were not created by default
3845 if (targetConfigurationFilesPresent
) {
3846 // Create services for builtin interfaces at target if they don't exist
3847 (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(targetPrefs
, targetNetworkInterfacePrefs
);
3848 if (!_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs
,
3849 targetNetworkInterfacePrefs
,
3851 SC_log(LOG_NOTICE
, "Target configuration not valid");
3852 goto skipServiceMigration
;
3855 // Upgrade scenario, source and target models match
3856 if (isUpgradeScenario
) {
3857 Boolean foundNewInterface
= FALSE
;
3858 // Create SCPreferences to copy the target prefs
3859 SCPreferencesRef upgradeSourcePrefs
= SCPreferencesCreate(NULL
, CFSTR("Upgrade Source Prefs"), NULL
);
3860 SCPreferencesRef upgradeSourceNIPrefs
= SCPreferencesCreate(NULL
, CFSTR("Upgrade Source NI Prefs"), INTERFACES_DEFAULT_CONFIG
);
3863 "Migrating network configuration:"
3864 "\n upgradeSourcePrefs [temp] = %@"
3865 "\n upgradeSourceNIPrefs [temp] = %@"
3866 "\n Copying target --> upgrade, source --> target",
3868 upgradeSourceNIPrefs
);
3870 // Content of target prefs
3871 CFDictionaryRef targetPrefsContent
= SCPreferencesPathGetValue(targetPrefs
, CFSTR("/"));
3872 CFDictionaryRef targetNIPrefsContent
= SCPreferencesPathGetValue(targetNetworkInterfacePrefs
, CFSTR("/"));
3874 // Backing up the target prefs into source prefs
3875 SCPreferencesPathSetValue(upgradeSourcePrefs
, CFSTR("/"), targetPrefsContent
);
3876 SCPreferencesPathSetValue(upgradeSourceNIPrefs
, CFSTR("/"), targetNIPrefsContent
);
3878 // Copying content from the source prefs
3879 CFDictionaryRef sourcePrefsContent
= SCPreferencesPathGetValue(sourcePrefs
, CFSTR("/"));
3880 CFDictionaryRef sourceNIPreferencesContent
= SCPreferencesPathGetValue(sourceNetworkInterfacePrefs
, CFSTR("/"));
3882 // Setting the contents of the source prefs into the target prefs
3883 SCPreferencesPathSetValue(targetPrefs
, CFSTR("/"), sourcePrefsContent
);
3884 SCPreferencesPathSetValue(targetNetworkInterfacePrefs
, CFSTR("/"), sourceNIPreferencesContent
);
3886 // Getting the mapping of the non builtin interfaces between source and target
3887 externalMapping
= _SCNetworkConfigurationCopyExternalInterfaceMapping(upgradeSourceNIPrefs
, targetNetworkInterfacePrefs
);
3889 "Upgradng, external interface mapping: %@",
3892 newTargetNetworkInterfaceEntity
= _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs
, externalMapping
, &foundNewInterface
);
3895 "Upgrading, %s new interfaces"
3896 "\n newTargetNetworkInterfaceEntity = %@",
3897 foundNewInterface
? "found" : "no",
3898 newTargetNetworkInterfaceEntity
);
3900 if (foundNewInterface
) {
3901 if (newTargetNetworkInterfaceEntity
== NULL
) {
3902 SC_log(LOG_NOTICE
, "Upgrading, failed w/no new interface list");
3903 CFRelease(upgradeSourcePrefs
);
3904 CFRelease(upgradeSourceNIPrefs
);
3908 // add new interface mapping to NetworkInterfaces.plist
3909 if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs
, newTargetNetworkInterfaceEntity
)) {
3910 SC_log(LOG_NOTICE
, "Upgrading, failed to update NetworkInterfaces.plist");
3911 CFRelease(upgradeSourcePrefs
);
3912 CFRelease(upgradeSourceNIPrefs
);
3916 // create BSD name mapping to facilitate mapping of services
3917 bsdNameMapping
= _SCNetworkMigrationCreateBSDNameMapping(NULL
, externalMapping
);
3919 serviceMapping
= _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(upgradeSourcePrefs
, targetPrefs
, bsdNameMapping
);
3921 logConfiguration("Source", upgradeSourcePrefs
);
3922 logConfiguration("Target", targetPrefs
);
3923 _SCNetworkMigrationDoServiceMigration(upgradeSourcePrefs
,
3929 logConfiguration("Updated", targetPrefs
);
3931 CFRelease(upgradeSourcePrefs
);
3932 CFRelease(upgradeSourceNIPrefs
);
3934 builtinMapping
= _SCNetworkConfigurationCopyBuiltinMapping(sourceNetworkInterfacePrefs
, targetNetworkInterfacePrefs
);
3936 externalMapping
= _SCNetworkConfigurationCopyExternalInterfaceMapping(sourceNetworkInterfacePrefs
, targetNetworkInterfacePrefs
);
3938 newTargetNetworkInterfaceEntity
= _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs
, externalMapping
, NULL
);
3939 if (newTargetNetworkInterfaceEntity
== NULL
) {
3940 SC_log(LOG_NOTICE
, "Migrating, failed w/no new interface list");
3944 // Write new interface mapping to NetworkInterfaces.plist
3945 if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs
, newTargetNetworkInterfaceEntity
)) {
3946 SC_log(LOG_NOTICE
, "Migrating, failed to update NetworkInterfaces.plist");
3950 // create BSD name mapping to facilitate mapping of services
3951 bsdNameMapping
= _SCNetworkMigrationCreateBSDNameMapping(builtinMapping
, externalMapping
);
3953 serviceMapping
= _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(sourcePrefs
, targetPrefs
, bsdNameMapping
);
3954 if (serviceMapping
== NULL
) {
3958 setMapping
= _SCNetworkMigrationCreateSetMapping(sourcePrefs
, targetPrefs
);
3960 sourceServiceSetMapping
= _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs
);
3962 logConfiguration("Source", sourcePrefs
);
3963 logConfiguration("Target", targetPrefs
);
3964 if (!_SCNetworkMigrationDoServiceMigration(sourcePrefs
,
3969 sourceServiceSetMapping
)) {
3970 SC_log(LOG_NOTICE
, "SCNetworkMigrationDoServiceMigration(): service migration failed");
3973 #if !TARGET_OS_IPHONE
3974 // Migrating Virtual Network Interfaces
3975 if (!_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs
, sourceNetworkInterfacePrefs
,
3976 targetPrefs
, targetNetworkInterfacePrefs
,
3977 bsdNameMapping
, setMapping
, sourceServiceSetMapping
)) {
3978 SC_log(LOG_NOTICE
, "SCNetworkMigrationDoServiceMigration(): virtual interface migration failed");
3980 #endif // !TARGET_OS_IPHONE
3981 // Migrate Service Order
3982 if (!_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs
, targetPrefs
, setMapping
)) {
3983 SC_log(LOG_NOTICE
, "SCNetworkMigrationDoServiceMigration(): service order migration failed");
3985 logConfiguration("Migrated", targetPrefs
);
3988 skipServiceMigration
:
3989 // Migrating System Information
3990 if (!isUpgradeScenario
) {
3991 if (!_SCNetworkMigrationDoSystemMigration(sourcePrefs
, targetPrefs
)) {
3992 SC_log(LOG_NOTICE
, "SCNetworkMigrationDoServiceMigration(): system setting migration failed");
3995 if (!_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs
, targetNetworkInterfacePrefs
, validityOptions
)) {
3996 SC_log(LOG_NOTICE
, "Migrated configuration not valid");
3999 if (!SCPreferencesCommitChanges(targetPrefs
)) {
4000 SC_log(LOG_NOTICE
, "SCPreferencesCommitChanges(target preferences.plist) failed: %s", SCErrorString(SCError()));
4004 if (!SCPreferencesCommitChanges(targetNetworkInterfacePrefs
)) {
4005 SC_log(LOG_NOTICE
, "SCPreferencesCommitChanges(target NetworkInterfaces.plist) failed: %s", SCErrorString(SCError()));
4008 migrationSuccess
= TRUE
;
4011 if (setMapping
!= NULL
) {
4012 CFRelease(setMapping
);
4014 if (sourceServiceSetMapping
!= NULL
) {
4015 CFRelease(sourceServiceSetMapping
);
4017 if (sourceConfigurationFiles
!= NULL
) {
4018 CFRelease(sourceConfigurationFiles
);
4020 if (targetConfigurationFiles
!= NULL
) {
4021 CFRelease(targetConfigurationFiles
);
4023 if (sourcePreferencesFileString
!= NULL
) {
4024 CFRelease(sourcePreferencesFileString
);
4026 if (sourceNetworkInterfaceFileString
!= NULL
) {
4027 CFRelease(sourceNetworkInterfaceFileString
);
4029 if (targetPreferencesFileString
!= NULL
) {
4030 CFRelease(targetPreferencesFileString
);
4032 if (targetNetworkInterfaceFileString
!= NULL
) {
4033 CFRelease(targetNetworkInterfaceFileString
);
4035 if (newTargetNetworkInterfaceEntity
!= NULL
) {
4036 CFRelease(newTargetNetworkInterfaceEntity
);
4038 if (builtinMapping
!= NULL
) {
4039 CFRelease(builtinMapping
);
4041 if (externalMapping
!= NULL
) {
4042 CFRelease(externalMapping
);
4044 if (bsdNameMapping
!= NULL
) {
4045 CFRelease(bsdNameMapping
);
4047 if (serviceMapping
!= NULL
) {
4048 CFRelease(serviceMapping
);
4050 if (targetPrefs
!= NULL
) {
4051 CFRelease(targetPrefs
);
4053 if (sourcePrefs
!= NULL
) {
4054 CFRelease(sourcePrefs
);
4056 if (sourceNetworkInterfacePrefs
!= NULL
) {
4057 CFRelease(sourceNetworkInterfacePrefs
);
4059 if (targetNetworkInterfacePrefs
!= NULL
) {
4060 CFRelease(targetNetworkInterfacePrefs
);
4062 if (validityOptions
!= NULL
) {
4063 CFRelease(validityOptions
);
4065 return migrationSuccess
;
4071 _SCNetworkMigrationAreServicesIdentical(SCPreferencesRef configPref
, SCPreferencesRef expectedConfigPref
)
4073 const void * expected_vals_q
[N_QUICK
];
4074 const void ** expected_vals
= expected_vals_q
;
4075 CFMutableArrayRef expectedServiceArray
= NULL
;
4076 CFIndex expectedServiceArrayCount
= 0;
4077 CFDictionaryRef expectedServiceDict
= NULL
;
4078 size_t expectedServiceDictCount
= 0;
4079 CFDictionaryRef expectedServiceEntity
= 0;
4080 Boolean foundMatch
= FALSE
;
4081 CFMutableArrayRef serviceArray
= NULL
;
4082 CFIndex serviceArrayCount
= 0;
4083 CFDictionaryRef serviceDict
= NULL
;
4084 size_t serviceDictCount
= 0;
4085 CFDictionaryRef serviceEntity
= NULL
;
4086 Boolean success
= FALSE
;
4087 const void * vals_q
[N_QUICK
];
4088 const void ** vals
= vals_q
;
4090 serviceDict
= SCPreferencesGetValue(configPref
, kSCPrefNetworkServices
);
4091 if (!isA_CFDictionary(serviceDict
)) {
4094 serviceDictCount
= CFDictionaryGetCount(serviceDict
);
4096 expectedServiceDict
= SCPreferencesGetValue(expectedConfigPref
, kSCPrefNetworkServices
);
4097 if (!isA_CFDictionary(expectedServiceDict
)) {
4100 expectedServiceDictCount
= CFDictionaryGetCount(expectedServiceDict
);
4102 if (serviceDictCount
!= expectedServiceDictCount
) {
4106 if (serviceDictCount
> (sizeof(vals_q
) / sizeof(CFTypeRef
))) {
4107 vals
= CFAllocatorAllocate(NULL
, serviceDictCount
* sizeof(CFPropertyListRef
), 0);
4110 CFDictionaryGetKeysAndValues(serviceDict
, NULL
, vals
);
4111 serviceArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4113 for (size_t idx
=0; idx
< serviceDictCount
; idx
++) {
4114 serviceEntity
= vals
[idx
];
4115 if (!isA_CFDictionary(serviceEntity
)) {
4118 CFArrayAppendValue(serviceArray
, serviceEntity
);
4121 serviceArrayCount
= CFArrayGetCount(serviceArray
);
4123 if (expectedServiceDictCount
> (sizeof(expected_vals_q
) / sizeof(CFTypeRef
))) {
4124 expected_vals
= CFAllocatorAllocate(NULL
, expectedServiceDictCount
, 0);
4127 CFDictionaryGetKeysAndValues(expectedServiceDict
, NULL
, expected_vals
);
4128 expectedServiceArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4130 for (size_t idx
= 0; idx
< expectedServiceDictCount
; idx
++) {
4131 serviceEntity
= expected_vals
[idx
];
4132 if (!isA_CFDictionary(serviceEntity
)) {
4135 CFArrayAppendValue(expectedServiceArray
, serviceEntity
);
4137 expectedServiceArrayCount
= CFArrayGetCount(expectedServiceArray
);
4139 if (serviceArrayCount
!= expectedServiceArrayCount
) {
4143 for (CFIndex idx
= 0; idx
< expectedServiceArrayCount
; idx
++) {
4145 expectedServiceEntity
= CFArrayGetValueAtIndex(expectedServiceArray
, idx
);
4146 serviceArrayCount
= CFArrayGetCount(serviceArray
);
4148 for (CFIndex idx2
= 0; idx2
< serviceArrayCount
; idx2
++) {
4149 serviceEntity
= CFArrayGetValueAtIndex(serviceArray
, idx2
);
4151 if (CFEqual(expectedServiceEntity
, serviceEntity
)) {
4162 success
= foundMatch
;
4164 if (vals
!= vals_q
) {
4165 CFAllocatorDeallocate(NULL
, vals
);
4167 if (expected_vals
!= expected_vals_q
) {
4168 CFAllocatorDeallocate(NULL
, expected_vals
);
4174 _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical (SCPreferencesRef configNetworkInterfacePref
, SCPreferencesRef expectedNetworkInterfacePref
)
4176 CFDictionaryRef expectedInterfaceEntity
= NULL
;
4177 CFArrayRef expectedInterfaceList
= NULL
;
4178 CFIndex expectedInterfaceListCount
;
4179 Boolean foundMatch
= FALSE
;
4180 CFDictionaryRef interfaceEntity
= NULL
;
4181 CFArrayRef interfaceList
= NULL
;
4182 CFIndex interfaceListCount
;
4183 CFMutableArrayRef interfaceListMutable
= NULL
;
4184 Boolean success
= FALSE
;
4186 interfaceList
= SCPreferencesGetValue(configNetworkInterfacePref
, INTERFACES
);
4187 if (!isA_CFArray(interfaceList
)) {
4190 interfaceListMutable
= CFArrayCreateMutableCopy(NULL
, 0, interfaceList
);
4191 interfaceListCount
= CFArrayGetCount(interfaceListMutable
);
4193 expectedInterfaceList
= SCPreferencesGetValue(expectedNetworkInterfacePref
, INTERFACES
);
4194 if (!isA_CFArray(expectedInterfaceList
)) {
4197 expectedInterfaceListCount
= CFArrayGetCount(expectedInterfaceList
);
4199 if (interfaceListCount
!= expectedInterfaceListCount
) {
4203 for (CFIndex idx
= 0; idx
< expectedInterfaceListCount
; idx
++) {
4205 expectedInterfaceEntity
= CFArrayGetValueAtIndex(expectedInterfaceList
, idx
);
4206 interfaceListCount
= CFArrayGetCount(interfaceListMutable
);
4208 for (CFIndex idx2
= 0; idx2
< interfaceListCount
; idx2
++) {
4209 interfaceEntity
= CFArrayGetValueAtIndex(interfaceList
, idx2
);
4210 if (CFEqual(expectedInterfaceEntity
, interfaceEntity
)) {
4219 success
= foundMatch
;
4222 if (interfaceListMutable
!= NULL
) {
4223 CFRelease(interfaceListMutable
);
4230 _SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL
,
4231 CFURLRef expectedConfigurationURL
)
4233 CFURLRef baseConfigURL
= NULL
;
4234 CFURLRef baseExpectedConfigURL
= NULL
;
4235 CFURLRef configPreferencesURL
= NULL
;
4236 CFURLRef configNetworkInterfacesURL
= NULL
;
4237 SCPreferencesRef configPref
= NULL
;
4238 SCPreferencesRef configNetworkInterfacePref
= NULL
;
4239 SCPreferencesRef expectedConfigPref
= NULL
;
4240 SCPreferencesRef expectedNetworkInterfacePref
= NULL
;
4241 CFURLRef expectedNetworkInterfaceURL
= NULL
;
4242 CFURLRef expectedPreferencesURL
= NULL
;
4243 Boolean isIdentical
= FALSE
;
4244 CFStringRef networkInterfaceConfigString
= NULL
;
4245 CFStringRef networkInterfaceExpectedString
= NULL
;
4246 CFStringRef prefsConfigString
= NULL
;
4247 CFStringRef prefsExpectedString
= NULL
;
4248 char networkInterfaceConfigStr
[PATH_MAX
];
4249 char networkInterfaceExpectedStr
[PATH_MAX
];
4250 char prefsConfigStr
[PATH_MAX
];
4251 char prefsExpectedStr
[PATH_MAX
];
4253 if (configurationURL
== NULL
||
4254 expectedConfigurationURL
== NULL
) {
4257 baseConfigURL
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
4258 PREFS_DEFAULT_DIR_RELATIVE
,
4259 kCFURLPOSIXPathStyle
,
4262 configPreferencesURL
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
4263 (const UInt8
*)PREFS_DEFAULT_CONFIG_PLIST
,
4264 sizeof(PREFS_DEFAULT_CONFIG_PLIST
),
4267 if (!CFURLResourceIsReachable(configPreferencesURL
, NULL
)) {
4268 SC_log(LOG_NOTICE
, "No preferences.plist file: %@", configPreferencesURL
);
4272 configNetworkInterfacesURL
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
4273 (const UInt8
*)INTERFACES_DEFAULT_CONFIG_PLIST
,
4274 sizeof(INTERFACES_DEFAULT_CONFIG_PLIST
),
4277 if (!CFURLResourceIsReachable(configNetworkInterfacesURL
, NULL
)) {
4278 SC_log(LOG_NOTICE
, "No NetworkInterfaces.plist file: %@", configNetworkInterfacesURL
);
4282 if (!CFURLGetFileSystemRepresentation(configPreferencesURL
, TRUE
, (UInt8
*)prefsConfigStr
, sizeof(prefsConfigStr
))) {
4283 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configPreferencesURL
);
4286 if (!CFURLGetFileSystemRepresentation(configNetworkInterfacesURL
, TRUE
, (UInt8
*)networkInterfaceConfigStr
, sizeof(networkInterfaceConfigStr
))) {
4287 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", configNetworkInterfacesURL
);
4291 baseExpectedConfigURL
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
4292 PREFS_DEFAULT_DIR_RELATIVE
,
4293 kCFURLPOSIXPathStyle
,
4295 expectedConfigurationURL
);
4296 expectedPreferencesURL
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
4297 (const UInt8
*)PREFS_DEFAULT_CONFIG_PLIST
,
4298 sizeof(PREFS_DEFAULT_CONFIG_PLIST
),
4300 baseExpectedConfigURL
);
4302 if (!CFURLResourceIsReachable(expectedPreferencesURL
, NULL
)) {
4303 SC_log(LOG_NOTICE
, "No expected preferences.plist file");
4307 expectedNetworkInterfaceURL
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
4308 (const UInt8
*)INTERFACES_DEFAULT_CONFIG_PLIST
,
4309 sizeof(INTERFACES_DEFAULT_CONFIG_PLIST
),
4311 baseExpectedConfigURL
);
4313 if (!CFURLResourceIsReachable(expectedNetworkInterfaceURL
, NULL
)) {
4314 SC_log(LOG_NOTICE
, "No expected NetworkInterfaces.plist file");
4318 if (!CFURLGetFileSystemRepresentation(expectedPreferencesURL
, TRUE
, (UInt8
*)prefsExpectedStr
, sizeof(prefsExpectedStr
))) {
4319 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", expectedPreferencesURL
);
4322 if (!CFURLGetFileSystemRepresentation(expectedNetworkInterfaceURL
, TRUE
, (UInt8
*)networkInterfaceExpectedStr
, sizeof(networkInterfaceExpectedStr
))) {
4323 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", expectedNetworkInterfaceURL
);
4327 prefsConfigString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), prefsConfigStr
);
4328 networkInterfaceConfigString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), networkInterfaceConfigStr
);
4329 prefsExpectedString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), prefsExpectedStr
);
4330 networkInterfaceExpectedString
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%s"), networkInterfaceExpectedStr
);
4332 configPref
= SCPreferencesCreate(NULL
, PLUGIN_ID
, prefsConfigString
);
4333 expectedConfigPref
= SCPreferencesCreate(NULL
, PLUGIN_ID
, prefsExpectedString
);
4334 configNetworkInterfacePref
= SCPreferencesCreate(NULL
, PLUGIN_ID
, networkInterfaceConfigString
);
4335 expectedNetworkInterfacePref
= SCPreferencesCreate(NULL
, PLUGIN_ID
, networkInterfaceExpectedString
);
4337 if (configPref
== NULL
||
4338 expectedConfigPref
== NULL
||
4339 configNetworkInterfacePref
== NULL
||
4340 expectedNetworkInterfacePref
== NULL
) {
4341 SC_log(LOG_NOTICE
, "One of the preferences is NULL");
4342 isIdentical
= FALSE
;
4344 isIdentical
= (_SCNetworkMigrationAreServicesIdentical(configPref
, expectedConfigPref
) &&
4345 _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical(configNetworkInterfacePref
, expectedNetworkInterfacePref
));
4347 if (baseConfigURL
!= NULL
) {
4348 CFRelease(baseConfigURL
);
4350 if (configPreferencesURL
!= NULL
) {
4351 CFRelease(configPreferencesURL
);
4353 if (configNetworkInterfacesURL
!= NULL
) {
4354 CFRelease(configNetworkInterfacesURL
);
4356 if (baseExpectedConfigURL
!= NULL
) {
4357 CFRelease(baseExpectedConfigURL
);
4359 if (expectedPreferencesURL
!= NULL
) {
4360 CFRelease(expectedPreferencesURL
);
4362 if (expectedNetworkInterfaceURL
!= NULL
) {
4363 CFRelease(expectedNetworkInterfaceURL
);
4365 if (prefsConfigString
!= NULL
) {
4366 CFRelease(prefsConfigString
);
4368 if (networkInterfaceConfigString
!= NULL
) {
4369 CFRelease(networkInterfaceConfigString
);
4371 if (prefsExpectedString
!= NULL
) {
4372 CFRelease(prefsExpectedString
);
4374 if (networkInterfaceExpectedString
!= NULL
) {
4375 CFRelease(networkInterfaceExpectedString
);
4377 if (configPref
!= NULL
) {
4378 CFRelease(configPref
);
4380 if (expectedConfigPref
!= NULL
) {
4381 CFRelease(expectedConfigPref
);
4383 if (configNetworkInterfacePref
!= NULL
) {
4384 CFRelease(configNetworkInterfacePref
);
4386 if (expectedNetworkInterfacePref
!= NULL
) {
4387 CFRelease(expectedNetworkInterfacePref
);
4393 _SCNetworkConfigurationCopyMigrationRemovePaths (CFArrayRef targetPaths
,
4396 CFURLRef affectedURL
;
4397 char filePath
[PATH_MAX
];
4398 CFURLRef targetFile
;
4399 CFMutableArrayRef toBeRemoved
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4401 for (CFIndex idx
= 0; idx
< CFArrayGetCount(targetPaths
); idx
++) {
4402 affectedURL
= CFArrayGetValueAtIndex(targetPaths
, idx
);
4404 if (!CFURLGetFileSystemRepresentation(affectedURL
, TRUE
, (UInt8
*)filePath
, sizeof(filePath
))) {
4405 SC_log(LOG_NOTICE
, "Cannot get file system representation for url: %@", affectedURL
);
4408 targetFile
= CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL
,
4409 (const UInt8
*)filePath
,
4410 strnlen(filePath
, sizeof(filePath
)),
4414 if (!CFURLResourceIsReachable(targetFile
, NULL
)) {
4415 CFArrayAppendValue(toBeRemoved
, affectedURL
);
4417 CFRelease(targetFile
);
4419 // If number of files to be removed is 0, return NULL
4420 if (CFArrayGetCount(toBeRemoved
) == 0) {
4421 CFRelease(toBeRemoved
);