From 260b6351efde785de0bf60ad5f0d3a6bdad1d797 Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 18 Dec 2020 10:19:03 +0000 Subject: [PATCH] configd-1109.60.2.tar.gz --- SystemConfiguration.fproj/SCD.c | 23 +- .../SCNetworkConfigurationInternal.c | 209 ++++++ .../SCNetworkConfigurationInternal.h | 1 + .../SCNetworkConfigurationPrivate.h | 7 + .../SCNetworkMigration.c | 639 +++++++++++------- SystemConfiguration.fproj/SCNetworkService.c | 123 ++-- scutil.tproj/net.c | 36 + scutil.tproj/net.h | 2 + scutil.tproj/scutil.c | 15 +- 9 files changed, 736 insertions(+), 319 deletions(-) diff --git a/SystemConfiguration.fproj/SCD.c b/SystemConfiguration.fproj/SCD.c index 473ceb2..e0512a9 100644 --- a/SystemConfiguration.fproj/SCD.c +++ b/SystemConfiguration.fproj/SCD.c @@ -586,15 +586,18 @@ __SC_log_send(int level, os_log_t log, os_log_type_t type, os_log_pack_t pack) char buffer[256]; const char *buffer_ptr = buffer; char *composed = NULL; + Boolean do_log = FALSE; Boolean do_print = FALSE; Boolean do_syslog = FALSE; if (_sc_log > kSCLogDestinationFile) { + do_log = TRUE; + if (_SC_isInstallEnvironment()) { /* * os_log(3) messages are not persisted in the - * install environment. So, we use syslog(3) - * instead. + * install environment. But, the installer does + * capture syslog(3) messages. */ do_syslog = TRUE; } @@ -606,14 +609,16 @@ __SC_log_send(int level, os_log_t log, os_log_type_t type, os_log_pack_t pack) do_print = TRUE; // print requested } - if (!do_print && !do_syslog) { - // if only os_log requested - os_log_pack_send(pack, log, type); - } else if (do_print && !do_syslog) { - // if os_log and print requested - composed = os_log_pack_send_and_compose(pack, log, type, buffer, sizeof(buffer)); + if (do_log) { + if (!do_print && !do_syslog) { + // if only os_log requested + os_log_pack_send(pack, log, type); + } else { + // if os_log and print (or syslog) requested + composed = os_log_pack_send_and_compose(pack, log, type, buffer, sizeof(buffer)); + } } else { - // if print-only and/or syslog requested + // if print-only requested mach_get_times(NULL, &pack->olp_continuous_time, &pack->olp_wall_time); composed = os_log_pack_compose(pack, log, type, buffer, sizeof(buffer)); } diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c index 32806c1..bd4da05 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.c @@ -36,6 +36,10 @@ #include +#pragma mark - +#pragma mark SCNetworkConfiguration logging + + __private_extern__ os_log_t __log_SCNetworkConfiguration(void) { @@ -49,6 +53,211 @@ __log_SCNetworkConfiguration(void) } +static void +logConfiguration_NetworkInterfaces(int level, const char *description, SCPreferencesRef prefs) +{ + CFArrayRef interfaces; + + interfaces = SCPreferencesGetValue(prefs, INTERFACES); + if (isA_CFArray(interfaces)) { + CFStringRef model = SCPreferencesGetValue(prefs, MODEL); + CFIndex n = CFArrayGetCount(interfaces); + + SC_log(level, "%s%sinterfaces (%@)", + description != NULL ? description : "", + description != NULL ? " " : "", + model != NULL ? model : CFSTR("No model")); + + for (CFIndex i = 0; i < n; i++) { + CFStringRef bsdName; + CFDictionaryRef dict; + CFDictionaryRef info; + CFStringRef name; + + dict = CFArrayGetValueAtIndex(interfaces, i); + if (!isA_CFDictionary(dict)) { + continue; + } + + bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName)); + if (!isA_CFString(bsdName)) { + continue; + } + + info = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceInfo)); + name = CFDictionaryGetValue(info, kSCPropUserDefinedName); + SC_log(level, " %@ (%@)", + bsdName, + name != NULL ? name : CFSTR("???")); + } + + } +} + +static void +logConfiguration_preferences(int level, const char *description, SCPreferencesRef prefs) +{ + CFStringRef model = SCPreferencesGetValue(prefs, MODEL); + CFIndex n; + CFMutableArrayRef orphans; + CFArrayRef services; + CFArrayRef sets; + + SC_log(level, "%s%sconfiguration (%@)", + description != NULL ? description : "", + description != NULL ? " " : "", + model != NULL ? model : CFSTR("No model")); + + services = SCNetworkServiceCopyAll(prefs); + if (services != NULL) { + orphans = CFArrayCreateMutableCopy(NULL, 0, services); + CFRelease(services); + } else { + orphans = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + + sets = SCNetworkSetCopyAll(prefs); + if (sets != NULL) { + n = CFArrayGetCount(sets); + for (CFIndex i = 0; i < n; i++) { + SCNetworkSetRef set; + + set = CFArrayGetValueAtIndex(sets, i); + SC_log(level, " Set %@ (%@)", + SCNetworkSetGetSetID(set), + SCNetworkSetGetName(set)); + + services = SCNetworkSetCopyServices(set); + if (services != NULL) { + CFIndex n; + CFIndex nOrder = 0; + CFArrayRef order; + + order = SCNetworkSetGetServiceOrder(set); + if (order != NULL) { + nOrder = CFArrayGetCount(order); + } + + n = CFArrayGetCount(services); + if (n > 1) { + CFMutableArrayRef sorted; + + sorted = CFArrayCreateMutableCopy(NULL, 0, services); + CFArraySortValues(sorted, + CFRangeMake(0, CFArrayGetCount(sorted)), + _SCNetworkServiceCompare, + (void *)order); + CFRelease(services); + services = sorted; + } + + for (CFIndex i = 0; i < n; i++) { + CFStringRef bsdName; + SCNetworkInterfaceRef interface; + CFIndex o; + CFIndex orderIndex = kCFNotFound; + SCNetworkServiceRef service; + CFStringRef serviceName; + CFStringRef serviceID; + CFStringRef userDefinedName; + + service = CFArrayGetValueAtIndex(services, i); + serviceID = SCNetworkServiceGetServiceID(service); + serviceName = SCNetworkServiceGetName(service); + if (serviceName == NULL) serviceName = CFSTR(""); + + interface = SCNetworkServiceGetInterface(service); + bsdName = SCNetworkInterfaceGetBSDName(interface); + + userDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface); + if (_SC_CFEqual(serviceName, userDefinedName)) { + userDefinedName = NULL; + } + + if (order != NULL) { + orderIndex = CFArrayGetFirstIndexOfValue(order, + CFRangeMake(0, nOrder), + serviceID); + } + if (orderIndex != kCFNotFound) { + SC_log(level, " Service %2ld : %@, %2d (%@%s%@%s%@)", + orderIndex + 1, + serviceID, + __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp? + serviceName, + bsdName != NULL ? ", " : "", + bsdName != NULL ? bsdName : CFSTR(""), + userDefinedName != NULL ? " : " : "", + userDefinedName != NULL ? userDefinedName : CFSTR("")); + } else { + SC_log(level, " Service : %@, %2d (%@%s%@%s%@)", + serviceID, + __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp? + serviceName, + bsdName != NULL ? ", " : "", + bsdName != NULL ? bsdName : CFSTR(""), + userDefinedName != NULL ? " : " : "", + userDefinedName != NULL ? userDefinedName : CFSTR("")); + } + + o = CFArrayGetFirstIndexOfValue(orphans, CFRangeMake(0, CFArrayGetCount(orphans)), service); + if (o != kCFNotFound) { + CFArrayRemoveValueAtIndex(orphans, o); + } + } + + CFRelease(services); + } + } + + CFRelease(sets); + } + + n = CFArrayGetCount(orphans); + if (n > 0) { + SC_log(level, " Orphans"); + + for (CFIndex i = 0; i < n; i++) { + CFStringRef bsdName; + SCNetworkInterfaceRef interface; + SCNetworkServiceRef service; + CFStringRef serviceName; + CFStringRef serviceID; + + service = CFArrayGetValueAtIndex(orphans, i); + serviceID = SCNetworkServiceGetServiceID(service); + serviceName = SCNetworkServiceGetName(service); + if (serviceName == NULL) serviceName = CFSTR(""); + + interface = SCNetworkServiceGetInterface(service); + bsdName = SCNetworkInterfaceGetBSDName(interface); + + SC_log(level, " Service : %@, %2d (%@%s%@)", + serviceID, + __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp? + serviceName, + bsdName != NULL ? ", " : "", + bsdName != NULL ? bsdName : CFSTR("")); + } + } + CFRelease(orphans); + + return; +} + +void +__SCNetworkConfigurationReport(int level, const char *description, SCPreferencesRef prefs, SCPreferencesRef ni_prefs) +{ + logConfiguration_NetworkInterfaces(level, description, ni_prefs); + logConfiguration_preferences (level, description, prefs); + return; +} + + +#pragma mark - +#pragma mark Misc + + static Boolean isEffectivelyEmptyConfiguration(CFDictionaryRef config) { diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h index 90fb90d..7388377 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationInternal.h @@ -37,6 +37,7 @@ #include "SCPreferencesPathKey.h" #include "IPMonitorControl.h" #include +#include #define NETWORK_CONFIGURATION_VERSION 20191120 diff --git a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h index fea0160..bf6318e 100644 --- a/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h +++ b/SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h @@ -95,6 +95,12 @@ typedef CF_ENUM(uint32_t, SCNetworkServicePrimaryRank) { @group Configuration */ +void +__SCNetworkConfigurationReport (int level, + const char *description, + SCPreferencesRef prefs, + SCPreferencesRef ni_prefs) SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0),bridgeos(5.0)); + Boolean _SCNetworkConfigurationBypassSystemInterfaces (SCPreferencesRef prefs) SPI_AVAILABLE(macos(10.15.4), ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0)); @@ -1250,6 +1256,7 @@ VPNServiceIsManagedAppVPN (VPNServiceRef service) API_AVAILABLE(macos(10.9)) #pragma mark Migration SPI extern const CFStringRef kSCNetworkConfigurationRepair /* CFBoolean */ API_AVAILABLE(macos(10.10), ios(8.0)); +extern const CFStringRef kSCNetworkConfigurationRepairModel /* CFBoolean */ API_AVAILABLE(macos(11.0), ios(14.0)); extern const CFStringRef kSCNetworkConfigurationMigrationActionKey /* CFNumber */ API_AVAILABLE(macos(10.10), ios(8.0)); diff --git a/SystemConfiguration.fproj/SCNetworkMigration.c b/SystemConfiguration.fproj/SCNetworkMigration.c index 16c4c7c..a8eadc1 100644 --- a/SystemConfiguration.fproj/SCNetworkMigration.c +++ b/SystemConfiguration.fproj/SCNetworkMigration.c @@ -56,6 +56,193 @@ const CFStringRef kSCNetworkConfigurationMigrationActionKey = CFSTR("MigrationActionKey"); const CFStringRef kSCNetworkConfigurationRepair = CFSTR("ConfigurationRepair"); +const CFStringRef kSCNetworkConfigurationRepairModel = CFSTR("ConfigurationRepairModel"); + + +static void +logInterfaces(int level, const char *description, CFArrayRef interfaces, Boolean detailed) +{ + CFMutableArrayRef interfaceNames = NULL; + + if (detailed) { + SC_log(level, "%s = ", description); + } else { + interfaceNames = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + + for (CFIndex i = 0, n = CFArrayGetCount(interfaces); i < n; i++) { + CFStringRef bsdName; + SCNetworkInterfaceRef interface; + CFStringRef userDefinedName = NULL; + + interface = CFArrayGetValueAtIndex(interfaces, i); + if (isA_SCNetworkInterface(interface)) { + bsdName = SCNetworkInterfaceGetBSDName(interface); + if (bsdName == NULL) { + continue; + } + userDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface); + } else if (isA_CFDictionary(interface)) { + CFDictionaryRef info; + + bsdName = CFDictionaryGetValue((CFDictionaryRef)interface, CFSTR(kSCNetworkInterfaceBSDName)); + if (bsdName == NULL) { + continue; + } + + info = CFDictionaryGetValue((CFDictionaryRef)interface, CFSTR(kSCNetworkInterfaceInfo)); + if (info != NULL) { + userDefinedName = CFDictionaryGetValue(info, kSCPropUserDefinedName); + } + } else { + bsdName = CFSTR("?"); + } + + if (interfaceNames == NULL) { + SC_log(level, " %@ (%@)", + bsdName, + userDefinedName != NULL ? userDefinedName : CFSTR("?")); + } else { + CFArrayAppendValue(interfaceNames, bsdName); + } + } + + if (interfaceNames != NULL) { + CFStringRef list; + + list = CFStringCreateByCombiningStrings(NULL, interfaceNames, CFSTR(", ")); + SC_log(level, "%s = %@", description, list); + CFRelease(list); + + CFRelease(interfaceNames); + } + + return; +} + + +typedef struct { + int level; + const char *name; +} logMappingContext; + +/* + * logMapping_one() + * + * Logs a single key/value of a mapping dictionary + */ +static void +logMapping_one(const void *key, const void *value, void *context) +{ +#pragma unused(context) + logMappingContext * mapping_context = (logMappingContext *)context; + CFTypeRef mapping_key = NULL; + CFTypeRef mapping_value = NULL; + Boolean mapping_value_retained = FALSE; + + if (mapping_context->name != NULL) { + SC_log(mapping_context->level, "%s =", mapping_context->name); + mapping_context->name = NULL; + } + + if (isA_SCNetworkService(key)) { + mapping_key = SCNetworkServiceGetServiceID(key); + } else if (isA_SCNetworkSet(key)) { + mapping_key = SCNetworkSetGetSetID(key); + } else if (isA_SCNetworkInterface(key)) { + mapping_key = SCNetworkInterfaceGetBSDName(key); + } else { + mapping_key = key; + } + + if (isA_SCNetworkService(value)) { + mapping_value = SCNetworkServiceGetServiceID(value); + } else if (isA_SCNetworkSet(value)) { + mapping_value = SCNetworkSetGetSetID(value); + } else if (isA_SCNetworkInterface(value)) { + CFStringRef bsdName; + CFStringRef userDefinedName; + + bsdName = SCNetworkInterfaceGetBSDName(value); + userDefinedName = __SCNetworkInterfaceGetUserDefinedName(value); + mapping_value = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)"), + bsdName, + userDefinedName != NULL ? userDefinedName : CFSTR("?")); + mapping_value_retained = TRUE; + } else if (isA_CFBoolean(value)) { + mapping_value = CFSTR("None"); + } else if (isA_CFArray(value)) { + CFIndex n = CFArrayGetCount(value); + CFMutableStringRef str = CFStringCreateMutable(NULL, 0); + + CFStringAppendFormat(str, NULL, CFSTR("( ")); + for (CFIndex i = 0; i < n; i++) { + CFTypeRef val; + + val = CFArrayGetValueAtIndex(value, i); + if (isA_SCNetworkSet(val)) { + val = SCNetworkSetGetSetID(val); + } + CFStringAppendFormat(str, NULL, CFSTR("%s%@"), + i == 0 ? "" : ", ", + val); + + + } + CFStringAppendFormat(str, NULL, CFSTR(" )")); + mapping_value = str; + mapping_value_retained = TRUE; + } else { + mapping_value = value; + } + + SC_log(mapping_context->level, " %@ --> %@", mapping_key, mapping_value); + + if (mapping_value_retained) { + CFRelease(mapping_value); + } + return; +} + +/* + * logMapping() + * + * Generates a log of the mappings between : + * + * bsdNameServiceProtocolPreserveMapping + * SCNetworkService/SCNetworkInterface/bsdName + * --> array + * + * mappingServiceBSDNameToInterface + * SCNetworkInterface/bsdName + * --> SCNetworkInterface + * + * bsdNameMapping + * [source]interface BSD name + * --> [target]interface BSD name + * + * externalMapping (like bsdNameMapping but only for "external" interfaces) + * + * serviceMapping (matching on SCNetworkService/SCNetworkInterface/bsdName) + * [source]SCNetworkService + * --> [target]SCNetworkService + * + * setMapping (matching on the SCNetworkSet "name") + * [source]SCNetworkSet + * --> [target]SCNetworkSet + * + * serviceSetMapping + * SCNetworkService + * --> array + */ +static void +logMapping(int level, CFDictionaryRef mapping, const char *name) +{ + logMappingContext mappingContext = { .level = level, .name = name }; + + CFDictionaryApplyFunction(mapping, logMapping_one, &mappingContext); + return; +} #if !TARGET_OS_IPHONE static CFDictionaryRef @@ -1146,7 +1333,7 @@ typedef struct { } validityContext; static void -_SCNetworkConfigurationValidateInterface (const void *key, const void *value, void *context) +_SCNetworkConfigurationValidateInterface(const void *key, const void *value, void *context) { CFStringRef bsdName = (CFStringRef)key; validityContext *ctx = (validityContext*)context; @@ -1172,17 +1359,12 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo // There is no interface present for the service interface = CFDictionaryGetValue(interfaceMapping, bsdName); if (interface == NULL) { - if (_SCNetworkInterfaceIsBluetoothPAN(serviceInterface)) { - // interface not expected, BT-PAN - return; - } - if (((bsdNameToBridgeServices != NULL) && !CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName)) && ((bsdNameToBondServices != NULL) && !CFDictionaryContainsKey(bsdNameToBondServices , bsdName)) && ((bsdNameToVLANServices != NULL) && !CFDictionaryContainsKey(bsdNameToVLANServices , bsdName))) { // Not a virtual interface SC_log(LOG_NOTICE, - "No interface with BSD name (%@) present for service", + "No interface with BSD name \"%@\" present for service", bsdName); if (repair) { @@ -1199,7 +1381,7 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo if (!__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName, serviceInterfaceUserDefinedName)) { SC_log(LOG_NOTICE, - "Interface user defined name (%@) doesn't match service/interface user defined name: %@", + "Interface user defined name \"%@\" doesn't match service/interface user defined name \"%@\"", interfaceUserDefinedName, serviceInterfaceUserDefinedName); *ctx->isValid = FALSE; @@ -1207,7 +1389,7 @@ _SCNetworkConfigurationValidateInterface (const void *key, const void *value, vo if (isA_CFArray(interfacePreserveServiceInformation) != NULL && __SCNetworkInterfaceMatchesName(interfaceUserDefinedName, serviceInterfaceUserDefinedName)) { SC_log(LOG_NOTICE, - "serviceInterfaceUserDefinedName: %@ is the localized key for interface name: %@", + "serviceInterfaceUserDefinedName: \"%@\" is the localized key for interface name \"%@\"", serviceInterfaceUserDefinedName, interfaceUserDefinedName); CFArrayAppendValue(interfacePreserveServiceInformation, serviceInterface); @@ -1326,6 +1508,8 @@ add_service(const void *value, void *context) CFDictionaryRef bsdNameServiceProtocolMapping = ctx->bsdNameServiceProtocolPreserveMapping; SCPreferencesRef prefs = ctx->prefs; SCNetworkServiceRef service; + CFStringRef serviceID; + CFStringRef serviceName; CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface); CFArrayRef protocolArray = NULL; @@ -1375,6 +1559,15 @@ add_service(const void *value, void *context) goto done; } + serviceID = SCNetworkServiceGetServiceID(service); + serviceName = SCNetworkServiceGetName(service); + if (serviceName == NULL) serviceName = CFSTR(""); + SC_log(LOG_INFO, "Adding service : %@ (%@%s%@)", + serviceID, + serviceName, + bsdName != NULL ? ", " : "", + bsdName != NULL ? bsdName : CFSTR("")); + done: if (service != NULL) { @@ -1440,8 +1633,21 @@ remove_service(const void *value, void *context) CFArrayRef toBeRemoved = ctx->interfaceToBeRemoved; interface = SCNetworkServiceGetInterface(service); - if (CFArrayContainsValue(toBeRemoved, CFRangeMake(0, CFArrayGetCount(toBeRemoved)), interface)) { + CFStringRef bsdName; + CFStringRef serviceID; + CFStringRef serviceName; + + serviceID = SCNetworkServiceGetServiceID(service); + serviceName = SCNetworkServiceGetName(service); + if (serviceName == NULL) serviceName = CFSTR(""); + bsdName = SCNetworkInterfaceGetBSDName(interface); + SC_log(LOG_INFO, "Removing service : %@ (%@%s%@)", + serviceID, + serviceName, + bsdName != NULL ? ", " : "", + bsdName != NULL ? bsdName : CFSTR("")); + SCNetworkServiceRemove(service); } } @@ -1459,20 +1665,35 @@ _SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs, removeCount = CFArrayGetCount(interfaceToBeRemoved); replaceCount = CFArrayGetCount(interfaceToBeReplaced); - if (removeCount == 0 && - replaceCount == 0) { + if ((removeCount == 0) && (replaceCount == 0)) { // We don't have any information to repair return FALSE; } + // Backup current preferences before making changes __SCNetworkConfigurationBackup(prefs, CFSTR("pre-repair"), prefs); __SCNetworkConfigurationBackup(ni_prefs, CFSTR("pre-repair"), prefs); + __SCNetworkConfigurationReport(LOG_DEBUG, "pre-repair", prefs, ni_prefs); + if (interfaceToBeRemoved != NULL) { + logInterfaces(LOG_DEBUG, "Interfaces to be removed", interfaceToBeRemoved, FALSE); + } + if (interfaceToBeReplaced != NULL) { + logInterfaces(LOG_DEBUG, "Interfaces to be replaced", interfaceToBeReplaced, FALSE); + } + serviceList = SCNetworkServiceCopyAll(prefs); CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), create_bsd_name_service_protocol_mapping, context); + if (context->bsdNameServiceProtocolPreserveMapping != NULL) { + logMapping(LOG_DEBUG, context->bsdNameServiceProtocolPreserveMapping, "BSD name / Service Protocol mapping"); + } + CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), remove_service, (void*)context); CFArrayApplyFunction(interfaceToBeReplaced, CFRangeMake(0, replaceCount), add_service, (void*)context); CFRelease(serviceList); + + __SCNetworkConfigurationReport(LOG_DEBUG, "post-repair", prefs, ni_prefs); + return TRUE; } @@ -1682,21 +1903,34 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, CFStringRef model = NULL; CFStringRef ni_model = NULL; Boolean repairConfiguration = FALSE; + Boolean repairModel = FALSE; Boolean revertBypassSystemInterfaces = FALSE; CFArrayRef setServiceOrder = NULL; CFArrayRef setServices = NULL; if ((isA_CFDictionary(options) != NULL)) { - CFBooleanRef repair = CFDictionaryGetValue(options, kSCNetworkConfigurationRepair); - if (isA_CFBoolean(repair) != NULL) { - repairConfiguration = CFBooleanGetValue(repair); + CFBooleanRef val; + + val = CFDictionaryGetValue(options, kSCNetworkConfigurationRepair); + if (isA_CFBoolean(val) != NULL) { + repairConfiguration = CFBooleanGetValue(val); + } + + val = CFDictionaryGetValue(options, kSCNetworkConfigurationRepairModel); + if (isA_CFBoolean(val) != NULL) { + repairModel = CFBooleanGetValue(val); } } SC_log(LOG_INFO, - "%sbypassing system interfaces for %@", - _SCNetworkConfigurationBypassSystemInterfaces(prefs) ? "" : "not ", - prefs); + "Configuration validity check%s%s%s" + "\n prefs = %@" + "\n ni_prefs = %@", + repairModel ? ", w/repair-model" : "", + repairConfiguration ? ", w/repair-configuration" : "", + _SCNetworkConfigurationBypassSystemInterfaces(prefs) ? ", bypass system interfaces" : "", + prefs, + ni_prefs); if (!_SCNetworkConfigurationBypassSystemInterfaces(prefs)) { _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, TRUE); @@ -1707,19 +1941,25 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, Check the validity by: - Comparing if the models are the same */ - model = SCPreferencesGetValue(prefs, MODEL); + model = SCPreferencesGetValue(prefs , MODEL); + ni_model = SCPreferencesGetValue(ni_prefs, MODEL); if (!isA_CFString(model)) { - SC_log(LOG_INFO, - "Configuration validity check: no \"Model\" property in preferences.plist" - "\n %@", - prefs); + if (repairModel && isA_CFString(ni_model)) { + SC_log(LOG_INFO, " updating \"Model\" property in preferences.plist"); + SCPreferencesSetValue(prefs, MODEL, ni_model); // have prefs model match ni_prefs + model = ni_model; + } else { + SC_log(LOG_INFO, " no \"Model\" property in preferences.plist"); + } } - ni_model = SCPreferencesGetValue(ni_prefs, MODEL); if (!isA_CFString(ni_model)) { - SC_log(LOG_INFO, - "Configuration validity check: no \"Model\" property in NetworkInterfaces.plist" - "\n %@", - ni_prefs); + if (repairModel && isA_CFString(model)) { + SC_log(LOG_INFO, " updating \"Model\" property in NetworkInterfaces.plist"); + SCPreferencesSetValue(ni_prefs, MODEL, model); // have ni_prefs model match prefs + ni_model = model; + } else { + SC_log(LOG_INFO, " no \"Model\" property in NetworkInterfaces.plist"); + } } if (isA_CFString(model) && isA_CFString(ni_model) && !CFEqual(model, ni_model)) { isValid = FALSE; @@ -1759,18 +1999,22 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, } interfaces = __SCNetworkServiceCopyAllInterfaces(prefs); - if (!isA_CFArray(interfaces)) { - if (interfaces != NULL) CFRelease(interfaces); + if (interfaces == NULL) { isValid = FALSE; SC_log(LOG_NOTICE, "Configuration validity check: no service interfaces!" "\n %@", prefs); goto done; + } else { + logInterfaces(LOG_DEBUG, "interfaces", interfaces, TRUE); } + mappingServiceBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces); CFRelease(interfaces); - if (!isA_CFDictionary(mappingServiceBSDNameToInterface)) { + if (mappingServiceBSDNameToInterface != NULL) { + logMapping(LOG_DEBUG, mappingServiceBSDNameToInterface, "mappingServiceBSDNameToInterface"); + } else { isValid = FALSE; SC_log(LOG_NOTICE, "Configuration validity check: no BSD name to service interface mapping!" @@ -1790,6 +2034,7 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, bsdNameToVLANServices = _SCNetworkMigrationCopyMappingBSDNameToVLANServices(prefs); #endif // !TARGET_OS_IPHONE } + context.interfaceMapping = mappingBSDNameToInterface; context.isValid = &isValid; context.interfaceToBeRemoved = interfaceToBeRemoved; @@ -1801,12 +2046,11 @@ _SCNetworkConfigurationCheckValidityWithPreferences(SCPreferencesRef prefs, context.repair = repairConfiguration; context.prefs = prefs; context.bsdNameServiceProtocolPreserveMapping = bsdNameServiceProtocolPreserveMapping; - CFDictionaryApplyFunction(mappingServiceBSDNameToInterface, _SCNetworkConfigurationValidateInterface, &context); if (!isValid) { SC_log(LOG_NOTICE, - "Configuration validity check: mismatch between interface names in NetworkInterfaces.plist and preferences.plist!" + "Configuration validity check: mismatched interface names between NetworkInterfaces.plist and preferences.plist!" "\n %@" "\n %@", prefs, @@ -1966,6 +2210,8 @@ done: if (revertBypassSystemInterfaces) { _SCNetworkConfigurationSetBypassSystemInterfaces(prefs, FALSE); } + + SC_log(LOG_INFO, " configuration is %svalid", isValid ? "" : "not "); return isValid; } @@ -2059,9 +2305,9 @@ done: typedef struct { - CFMutableArrayRef externalInterfaceList; - CFMutableArrayRef networkInterfaceList; - Boolean foundNewInterfaces; + CFMutableArrayRef externalInterfaceList; + CFMutableArrayRef networkInterfaceList; + Boolean foundNewInterfaces; } externalMappingContext; static void @@ -2069,17 +2315,45 @@ _SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void { #pragma unused(key) externalMappingContext *ctx = context; - CFDictionaryRef interface_entity = NULL; + CFDictionaryRef interface_entity; + CFIndex matchIndex; SCNetworkInterfaceRef targetInterface = (SCNetworkInterfaceRef)value; - if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface)) { - SC_log(LOG_NOTICE, "Target interface (%@) already exists, not adding to NetworkInterfaces.plist", targetInterface); - return; // If the target interface already exists then do not add it to NetworkInterfaces.plist + matchIndex = CFArrayGetFirstIndexOfValue(ctx->externalInterfaceList, + CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), + targetInterface); + if (matchIndex != kCFNotFound) { + SCNetworkInterfaceRef matchInterface; + CFStringRef matchName; + CFStringRef targetName; + + matchInterface = CFArrayGetValueAtIndex(ctx->externalInterfaceList, matchIndex); + matchName = __SCNetworkInterfaceGetUserDefinedName(matchInterface); + targetName = __SCNetworkInterfaceGetUserDefinedName(targetInterface); + if (_SC_CFEqual(matchName, targetName)) { + // the target interface already exists; do not add it to NetworkInterfaces.plist + SC_log(LOG_DEBUG, + "Target interface already exists, not updating NetworkInterfaces.plist" + "\n %@", + targetInterface); + return; + } else { + // the target interface differs from the NetworkInterfaces.plist interface; replace it + SC_log(LOG_DEBUG, + "Current interface morphed, replacing" + "\n %@", + matchInterface); + CFArrayRemoveValueAtIndex(ctx->externalInterfaceList, matchIndex); + } } + ctx->foundNewInterfaces = TRUE; interface_entity = __SCNetworkInterfaceCopyStorageEntity(targetInterface); - if (interface_entity != NULL) { + SC_log(LOG_DEBUG, + "adding network interface entity" + "\n%@", + interface_entity); CFArrayAppendValue(ctx->networkInterfaceList, interface_entity); CFRelease(interface_entity); } @@ -2129,6 +2403,10 @@ _SCNetworkMigrationCreateNetworkInterfaceArray(SCPreferencesRef ni_prefs, CFDict context.networkInterfaceList = networkInterfaceList; context.foundNewInterfaces = FALSE; + SC_log(LOG_DEBUG, "Updating network interface list"); + logInterfaces(LOG_DEBUG, " externalInterfaceList", externalInterfaceList, FALSE); + logInterfaces(LOG_DEBUG, " networkInterfaceList" , networkInterfaceList, FALSE); + CFDictionaryApplyFunction(externalMapping, _SCNetworkConfigurationCollectInterfaceStorageEntity, &context); if (hasNewInterface != NULL) { @@ -2207,11 +2485,9 @@ _SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs) } for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) { service = CFArrayGetValueAtIndex(services, idx); - if (!CFDictionaryContainsKey(serviceSetMapping, service)) { - setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - CFDictionaryAddValue(serviceSetMapping, service, setList); - CFRelease(setList); - } + setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFDictionaryAddValue(serviceSetMapping, service, setList); + CFRelease(setList); } CFRelease(services); @@ -2256,10 +2532,12 @@ _SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs, CFMutableArrayRef targetSetsMutable = NULL; sourceSets = SCNetworkSetCopyAll(sourcePrefs); - targetSets = SCNetworkSetCopyAll(targetPrefs); + if (sourceSets == NULL) { + goto done; + } - if (sourceSets == NULL || - targetSets == NULL) { + targetSets = SCNetworkSetCopyAll(targetPrefs); + if (targetSets == NULL) { goto done; } targetSetsMutable = CFArrayCreateMutableCopy(NULL, 0, targetSets); @@ -2391,7 +2669,7 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef sour sourceInterface = SCNetworkServiceGetInterface(sourceService); if (sourceInterface == NULL) { - SC_log(LOG_NOTICE, "No source interface"); + SC_log(LOG_NOTICE, "source service with no interface, should never happen"); continue; } @@ -2401,7 +2679,7 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef sour CFEqual(sourceInterfaceType, kSCValNetInterfaceTypePPP))) { sourceInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(sourceInterface); if (!isA_CFString(sourceInterfaceSubType)) { - SC_log(LOG_NOTICE, "No source interface SubType"); + SC_log(LOG_NOTICE, "source service with VPN/PPP interface missing SubType"); continue; } } @@ -2433,17 +2711,18 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef sour targetInterface = SCNetworkServiceGetInterface(targetService); if (targetInterface == NULL) { - SC_log(LOG_NOTICE, "No target interface"); + SC_log(LOG_NOTICE, "target service with no interface, should never happen"); continue; } if (sourceBSDName != NULL) { targetBSDName = SCNetworkInterfaceGetBSDName(targetInterface); if (!isA_CFString(targetBSDName)) { - SC_log(LOG_NOTICE, "No target BSD name: %@", targetInterface); + // source interface w/BSD interface, target w/o BSD interface continue; } if (CFEqual(targetBSDName, targetBSDNameMapped)) { +// SC_log(LOG_NOTICE, "Removing target BSD name: %@", targetBSDName); CFDictionaryAddValue(serviceMapping, sourceService, targetService); CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2); break; @@ -2466,6 +2745,7 @@ _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(SCPreferencesRef sour // Check if the target interface type and the target interface sub type match if (CFEqual(targetInterfaceType, sourceInterfaceType) && CFEqual(targetInterfaceSubType, sourceInterfaceSubType)) { +// SC_log(LOG_NOTICE, "Removing target BSD Name: %@ for VPN", targetBSDName); CFDictionaryAddValue(serviceMapping, sourceService, targetService); CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2); break; @@ -2526,167 +2806,18 @@ ServiceMigrationAddOrReplace(const void *key, const void *value, void *context) if ((setMapping != NULL) || (sourceServiceSetMapping != NULL)) { if (isA_SCNetworkService(targetService)) { (void)SCNetworkServiceGetName(targetService); // ensures that the service name will be logged + SC_log(LOG_INFO, "Removing [target] service: %@", targetService); SCNetworkServiceRemove(targetService); } } + (void)SCNetworkServiceGetName(sourceService); // ensures that the service name will be logged + SC_log(LOG_INFO, "Adding [source] service: %@", sourceService); + if (!__SCNetworkServiceMigrateNew(targetPrefs, sourceService, bsdNameMapping, setMapping, sourceServiceSetMapping)) { (void)SCNetworkServiceGetName(sourceService); // ensures that the service name will be logged - SC_log(LOG_INFO, "*** [source] service add failed: %@", sourceService); - } -} - -static void -logConfiguration(const char *description, SCPreferencesRef prefs) -{ - CFArrayRef sets; - - sets = SCNetworkSetCopyAll(prefs); - if (sets != NULL) { - CFIndex n = CFArrayGetCount(sets); - - SC_log(LOG_NOTICE, "%s configuration", description); - for (CFIndex i = 0; i < n; i++) { - CFArrayRef services; - SCNetworkSetRef set; - - set = CFArrayGetValueAtIndex(sets, i); - SC_log(LOG_NOTICE, " Set %@ (%@)", - SCNetworkSetGetSetID(set), - SCNetworkSetGetName(set)); - - services = SCNetworkSetCopyServices(set); - if (services != NULL) { - CFIndex n; - CFIndex nOrder = 0; - CFArrayRef order; - - order = SCNetworkSetGetServiceOrder(set); - if (order != NULL) { - nOrder = CFArrayGetCount(order); - } - - n = CFArrayGetCount(services); - if (n > 1) { - CFMutableArrayRef sorted; - - sorted = CFArrayCreateMutableCopy(NULL, 0, services); - CFArraySortValues(sorted, - CFRangeMake(0, CFArrayGetCount(sorted)), - _SCNetworkServiceCompare, - (void *)order); - CFRelease(services); - services = sorted; - } - - for (CFIndex i = 0; i < n; i++) { - CFStringRef bsdName; - SCNetworkInterfaceRef interface; - CFIndex orderIndex = kCFNotFound; - SCNetworkServiceRef service; - CFStringRef serviceName; - CFStringRef serviceID; - - service = CFArrayGetValueAtIndex(services, i); - serviceID = SCNetworkServiceGetServiceID(service); - serviceName = SCNetworkServiceGetName(service); - if (serviceName == NULL) serviceName = CFSTR(""); - - interface = SCNetworkServiceGetInterface(service); - bsdName = SCNetworkInterfaceGetBSDName(interface); - - if (order != NULL) { - orderIndex = CFArrayGetFirstIndexOfValue(order, - CFRangeMake(0, nOrder), - serviceID); - } - if (orderIndex != kCFNotFound) { - SC_log(LOG_NOTICE, " Service %2ld : %@, %2d (%@%s%@)", - orderIndex + 1, - serviceID, - __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp? - serviceName, - bsdName != NULL ? ", " : "", - bsdName != NULL ? bsdName : CFSTR("")); - } else { - SC_log(LOG_NOTICE, " Service : %@, %2d (%@%s%@)", - serviceID, - __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp? - serviceName, - bsdName != NULL ? ", " : "", - bsdName != NULL ? bsdName : CFSTR("")); - } - } - - CFRelease(services); - } - } - - CFRelease(sets); + SC_log(LOG_INFO, "*** adding [source] service failed: %@", sourceService); } - - return; -} - -static void -logMapping(const void *key, const void *value, void *context) -{ -#pragma unused(context) - CFTypeRef mapping_key = NULL; - const char **mapping_name = (const char **)context; - CFTypeRef mapping_value = NULL; - Boolean mapping_value_new = FALSE; - - if (*mapping_name != NULL) { - SC_log(LOG_NOTICE, "%s =", *mapping_name); - *mapping_name = NULL; - } - - if (isA_SCNetworkService(key)) { - mapping_key = SCNetworkServiceGetServiceID(key); - } else if (isA_SCNetworkSet(key)) { - mapping_key = SCNetworkSetGetSetID(key); - } else { - mapping_key = key; - } - - if (isA_SCNetworkService(value)) { - mapping_value = SCNetworkServiceGetServiceID(value); - } else if (isA_SCNetworkSet(value)) { - mapping_value = SCNetworkSetGetSetID(value); - } else if (isA_CFBoolean(value)) { - mapping_value = CFSTR("None"); - } else if (isA_CFArray(value)) { - CFIndex n = CFArrayGetCount(value); - CFMutableStringRef str = CFStringCreateMutable(NULL, 0); - - CFStringAppendFormat(str, NULL, CFSTR("( ")); - for (CFIndex i = 0; i < n; i++) { - CFTypeRef val; - - val = CFArrayGetValueAtIndex(value, i); - if (isA_SCNetworkSet(val)) { - val = SCNetworkSetGetSetID(val); - } - CFStringAppendFormat(str, NULL, CFSTR("%s%@"), - i == 0 ? "" : ", ", - val); - - - } - CFStringAppendFormat(str, NULL, CFSTR(" )")); - mapping_value = str; - mapping_value_new = TRUE; - } else { - mapping_value = value; - } - - SC_log(LOG_NOTICE, " %@ --> %@", mapping_key, mapping_value); - - if (mapping_value_new) { - CFRelease(mapping_value); - } - return; } static Boolean @@ -2698,7 +2829,6 @@ _SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs, CFDictionaryRef serviceSetMapping) { serviceMigrationContext context; - const char *mapping_name; Boolean success = FALSE; if ((sourcePrefs == NULL) || @@ -2710,20 +2840,27 @@ _SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs, } if (bsdNameMapping != NULL) { - mapping_name = "BSD name mapping"; - CFDictionaryApplyFunction(bsdNameMapping, logMapping, &mapping_name); + logMapping(LOG_INFO, bsdNameMapping, "BSD name mapping"); + } else { + SC_log(LOG_NOTICE, "No BSD name mapping"); } + if (serviceMapping != NULL) { - mapping_name = "SCNetworkService mapping"; - CFDictionaryApplyFunction(serviceMapping, logMapping, &mapping_name); + logMapping(LOG_INFO, serviceMapping, "SCNetworkService mapping"); + } else { + SC_log(LOG_NOTICE, "No SCNetworkService mapping"); } + if (setMapping != NULL) { - mapping_name = "SCNetworkSet mapping"; - CFDictionaryApplyFunction(setMapping, logMapping, &mapping_name); + logMapping(LOG_INFO, setMapping, "SCNetworkSet mapping"); + } else { + SC_log(LOG_NOTICE, "No SCNetworkSet mapping"); } + if (serviceSetMapping != NULL) { - mapping_name = "SCNetworkService/SCNetworkSet mapping"; - CFDictionaryApplyFunction(serviceSetMapping, logMapping, &mapping_name); + logMapping(LOG_INFO, serviceSetMapping, "SCNetworkService/SCNetworkSet mapping"); + } else { + SC_log(LOG_NOTICE, "No SCNetworkService/SCNetworkSet mapping"); } context.targetPrefs = targetPrefs; @@ -3689,7 +3826,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD CFMutableDictionaryRef builtinMapping = NULL; // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef) CFMutableDictionaryRef externalMapping = NULL; // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef) Boolean migrationSuccess = FALSE; - CFArrayRef newTargetNetworkInterfaceEntity = NULL; // Array of Interface Entity which used to create new target interfaces created during migration + CFArrayRef newTargetNetworkInterfaceEntities = NULL; // Array of Interface Entity which used to create new target interfaces created during migration CFDictionaryRef serviceMapping = NULL; // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef) CFDictionaryRef setMapping = NULL; CFDictionaryRef sourceServiceSetMapping = NULL; @@ -3798,9 +3935,9 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD targetModel = SCPreferencesGetValue(targetPrefs, MODEL); isUpgradeScenario = (isA_CFString(sourceModel) && isA_CFString(targetModel) && CFEqual(sourceModel, targetModel)); if (isUpgradeScenario) { - SC_log(LOG_NOTICE, "Migrating network configuration: performing an \"upgrade\""); + SC_log(LOG_NOTICE, "Upgrading network configuration"); } else { - SC_log(LOG_NOTICE, "Migrating network configuration: performing a \"migration\""); + SC_log(LOG_NOTICE, "Migrating network configuration"); } SC_log(LOG_INFO, @@ -3832,6 +3969,10 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD __SCNetworkConfigurationBackup(targetNetworkInterfacePrefs, suffix, targetPrefs); CFRelease(suffix); + // log what we're starting with + __SCNetworkConfigurationReport(LOG_NOTICE, "Source", sourcePrefs, sourceNetworkInterfacePrefs); + __SCNetworkConfigurationReport(LOG_NOTICE, "Target", targetPrefs, targetNetworkInterfacePrefs); + // Create services for builtin interfaces at source if they don't exist (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(sourcePrefs, sourceNetworkInterfacePrefs); // Checking validity of the source and destination preferences before continuing @@ -3854,13 +3995,17 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD } // Upgrade scenario, source and target models match if (isUpgradeScenario) { - Boolean foundNewInterface = FALSE; + Boolean foundNewInterfaces = FALSE; + // Create SCPreferences to copy the target prefs SCPreferencesRef upgradeSourcePrefs = SCPreferencesCreate(NULL, CFSTR("Upgrade Source Prefs"), NULL); SCPreferencesRef upgradeSourceNIPrefs = SCPreferencesCreate(NULL, CFSTR("Upgrade Source NI Prefs"), INTERFACES_DEFAULT_CONFIG); + // Setting Bypass Interface to avoid looking at system interfaces + _SCNetworkConfigurationSetBypassSystemInterfaces(upgradeSourcePrefs, TRUE); + SC_log(LOG_INFO, - "Migrating network configuration:" + "Upgrading network configuration:" "\n upgradeSourcePrefs [temp] = %@" "\n upgradeSourceNIPrefs [temp] = %@" "\n Copying target --> upgrade, source --> target", @@ -3885,20 +4030,15 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD // Getting the mapping of the non builtin interfaces between source and target externalMapping = _SCNetworkConfigurationCopyExternalInterfaceMapping(upgradeSourceNIPrefs, targetNetworkInterfacePrefs); - SC_log(LOG_INFO, - "Upgradng, external interface mapping: %@", - externalMapping); - - newTargetNetworkInterfaceEntity = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping, &foundNewInterface); + if (externalMapping != NULL) { + logMapping(LOG_INFO, externalMapping, "Upgrading, external interface mapping"); + } - SC_log(LOG_INFO, - "Upgrading, %s new interfaces" - "\n newTargetNetworkInterfaceEntity = %@", - foundNewInterface ? "found" : "no", - newTargetNetworkInterfaceEntity); + newTargetNetworkInterfaceEntities = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping, &foundNewInterfaces); + SC_log(LOG_INFO, "Upgrading, %s new interfaces", foundNewInterfaces ? "found" : "no"); - if (foundNewInterface) { - if (newTargetNetworkInterfaceEntity == NULL) { + if (foundNewInterfaces) { + if (newTargetNetworkInterfaceEntities == NULL) { SC_log(LOG_NOTICE, "Upgrading, failed w/no new interface list"); CFRelease(upgradeSourcePrefs); CFRelease(upgradeSourceNIPrefs); @@ -3906,7 +4046,7 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD } // add new interface mapping to NetworkInterfaces.plist - if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity)) { + if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntities)) { SC_log(LOG_NOTICE, "Upgrading, failed to update NetworkInterfaces.plist"); CFRelease(upgradeSourcePrefs); CFRelease(upgradeSourceNIPrefs); @@ -3918,15 +4058,16 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDNameMapping(upgradeSourcePrefs, targetPrefs, bsdNameMapping); - logConfiguration("Source", upgradeSourcePrefs); - logConfiguration("Target", targetPrefs); + setMapping = _SCNetworkMigrationCreateSetMapping(upgradeSourcePrefs, targetPrefs); + + sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(upgradeSourcePrefs); + _SCNetworkMigrationDoServiceMigration(upgradeSourcePrefs, targetPrefs, serviceMapping, bsdNameMapping, - NULL, - NULL); - logConfiguration("Updated", targetPrefs); + setMapping, + sourceServiceSetMapping); } CFRelease(upgradeSourcePrefs); CFRelease(upgradeSourceNIPrefs); @@ -3935,14 +4076,14 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD externalMapping = _SCNetworkConfigurationCopyExternalInterfaceMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs); - newTargetNetworkInterfaceEntity = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping, NULL); - if (newTargetNetworkInterfaceEntity == NULL) { + newTargetNetworkInterfaceEntities = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping, NULL); + if (newTargetNetworkInterfaceEntities == NULL) { SC_log(LOG_NOTICE, "Migrating, failed w/no new interface list"); goto done; } // Write new interface mapping to NetworkInterfaces.plist - if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity)) { + if (!__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntities)) { SC_log(LOG_NOTICE, "Migrating, failed to update NetworkInterfaces.plist"); goto done; } @@ -3959,8 +4100,6 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs); - logConfiguration("Source", sourcePrefs); - logConfiguration("Target", targetPrefs); if (!_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs, serviceMapping, @@ -3982,7 +4121,6 @@ _SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetD if (!_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping)) { SC_log(LOG_NOTICE, "SCNetworkMigrationDoServiceMigration(): service order migration failed"); } - logConfiguration("Migrated", targetPrefs); } skipServiceMigration: @@ -3992,8 +4130,11 @@ skipServiceMigration: SC_log(LOG_NOTICE, "SCNetworkMigrationDoServiceMigration(): system setting migration failed"); } } + CFDictionaryAddValue(validityOptions, kSCNetworkConfigurationRepairModel, kCFBooleanTrue); if (!_SCNetworkConfigurationCheckValidityWithPreferences(targetPrefs, targetNetworkInterfacePrefs, validityOptions)) { - SC_log(LOG_NOTICE, "Migrated configuration not valid"); + SC_log(LOG_NOTICE, + "%s configuration not valid", + isUpgradeScenario ? "Upgraded" : "Migrated"); goto done; } if (!SCPreferencesCommitChanges(targetPrefs)) { @@ -4007,6 +4148,8 @@ skipServiceMigration: } migrationSuccess = TRUE; + __SCNetworkConfigurationReport(LOG_NOTICE, isUpgradeScenario ? "Upgraded" : "Migrated", targetPrefs, targetNetworkInterfacePrefs); + done: if (setMapping != NULL) { CFRelease(setMapping); @@ -4032,8 +4175,8 @@ done: if (targetNetworkInterfaceFileString != NULL) { CFRelease(targetNetworkInterfaceFileString); } - if (newTargetNetworkInterfaceEntity != NULL) { - CFRelease(newTargetNetworkInterfaceEntity); + if (newTargetNetworkInterfaceEntities != NULL) { + CFRelease(newTargetNetworkInterfaceEntities); } if (builtinMapping != NULL) { CFRelease(builtinMapping); diff --git a/SystemConfiguration.fproj/SCNetworkService.c b/SystemConfiguration.fproj/SCNetworkService.c index 2b164d4..27b4e24 100644 --- a/SystemConfiguration.fproj/SCNetworkService.c +++ b/SystemConfiguration.fproj/SCNetworkService.c @@ -2396,22 +2396,17 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef prefs, Boolean enabled; SCNetworkInterfaceRef interface = NULL; CFDictionaryRef interfaceEntity = NULL; - CFMutableDictionaryRef interfaceEntityMutable = NULL; SCNetworkSetRef newSet = NULL; - SCPreferencesRef ni_prefs = NULL; - SCNetworkInterfaceRef ni_interface = NULL; SCNetworkInterfaceRef newInterface = NULL; SCNetworkServiceRef newService = NULL; SCNetworkSetRef oldSet = NULL; + Boolean serviceAdded = FALSE; CFStringRef serviceID = NULL; SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service; CFArrayRef setList = NULL; Boolean success = FALSE; CFStringRef targetDeviceName = NULL; - CFStringRef userDefinedName = NULL; - CFStringRef userDefinedNameInterface = NULL; CFArrayRef protocols = NULL; - CFStringRef subType; if (!isA_SCNetworkService(service) || !isA_SCNetworkInterface(servicePrivate->interface) || @@ -2438,42 +2433,59 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef prefs, SC_log(LOG_INFO, "No interface entity"); goto done; } - interfaceEntityMutable = CFDictionaryCreateMutableCopy(NULL, 0, interfaceEntity); - CFRelease(interfaceEntity); - if (isA_CFDictionary(bsdNameMapping) != NULL) { - deviceName = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceDeviceName); - if (isA_CFString(deviceName) != NULL) { + if (bsdNameMapping != NULL) { + deviceName = CFDictionaryGetValue(interfaceEntity, kSCPropNetInterfaceDeviceName); + if (deviceName != NULL) { targetDeviceName = CFDictionaryGetValue(bsdNameMapping, deviceName); if (targetDeviceName != NULL) { + CFStringRef name; + CFMutableDictionaryRef newInterfaceEntity; + + SC_log(LOG_INFO, " mapping \"%@\" --> \"%@\"", deviceName, targetDeviceName); + + newInterfaceEntity = CFDictionaryCreateMutableCopy(NULL, 0, interfaceEntity); + // update mapping - CFDictionarySetValue(interfaceEntityMutable, kSCPropNetInterfaceDeviceName, targetDeviceName); - ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); - ni_interface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, targetDeviceName); - if (ni_interface != NULL) { - userDefinedNameInterface = __SCNetworkInterfaceGetUserDefinedName(ni_interface); + CFDictionarySetValue(newInterfaceEntity, kSCPropNetInterfaceDeviceName, targetDeviceName); + + // update interface name + name = CFDictionaryGetValue(newInterfaceEntity, kSCPropUserDefinedName); + if (name != NULL) { + CFMutableStringRef newName; + + /* + * the interface "entity" can include the a UserDefinedName + * like "Ethernet Adapter (en4)". If this interface name is + * mapped to another then we want to ensure that corresponding + * UserDefinedName is also updated to match. + */ + newName = CFStringCreateMutableCopy(NULL, 0, name); + CFStringFindAndReplace(newName, + deviceName, + targetDeviceName, + CFRangeMake(0, CFStringGetLength(newName)), + 0); + CFDictionarySetValue(newInterfaceEntity, kSCPropUserDefinedName, newName); + CFRelease(newName); } + + CFRelease(interfaceEntity); + interfaceEntity = newInterfaceEntity; } } - if (userDefinedNameInterface == NULL) { - userDefinedNameInterface = CFDictionaryGetValue(interfaceEntityMutable, kSCPropUserDefinedName); - } } + newInterface = _SCNetworkInterfaceCreateWithEntity(NULL, - interfaceEntityMutable, + interfaceEntity, __kSCNetworkInterfaceSearchExternal); - if (userDefinedNameInterface != NULL) { - __SCNetworkInterfaceSetUserDefinedName(newInterface, userDefinedNameInterface); - } - // Supporting PPPoE subtype - subType = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceSubType); - if (subType != NULL && - CFEqual(subType, kSCValNetInterfaceSubTypePPPoE)) { - SCNetworkInterfaceRef childInterface = SCNetworkInterfaceGetInterface(newInterface); - if (childInterface != NULL) { - __SCNetworkInterfaceSetUserDefinedName(childInterface, userDefinedNameInterface); - } + if ((setMapping == NULL) || + (serviceSetMapping == NULL) || + !CFDictionaryGetValueIfPresent(serviceSetMapping, service, (const void **)&setList)) { + // if no mapping + SC_log(LOG_INFO, "No mapping"); + goto done; } newService = SCNetworkServiceCreate(prefs, newInterface); @@ -2498,31 +2510,28 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef prefs, // Set service ID _SCNetworkServiceSetServiceID(newService, serviceID); - userDefinedName = SCNetworkServiceGetName(service); - if ((userDefinedName != NULL) && - !SCNetworkServiceSetName(newService, userDefinedName)) { - SC_log(LOG_INFO, "SCNetworkServiceSetName(, %@) failed", userDefinedName); - } - // Determine which sets to add service - if (setMapping != NULL && - serviceSetMapping != NULL) { - setList = CFDictionaryGetValue(serviceSetMapping, service); - if (setList != NULL) { - for (CFIndex idx = 0; idx < CFArrayGetCount(setList); idx++) { - oldSet = CFArrayGetValueAtIndex(setList, idx); - newSet = CFDictionaryGetValue(setMapping, oldSet); - if (newSet == NULL) { - continue; - } + for (CFIndex idx = 0; idx < CFArrayGetCount(setList); idx++) { + oldSet = CFArrayGetValueAtIndex(setList, idx); + newSet = CFDictionaryGetValue(setMapping, oldSet); + if (newSet == NULL) { + continue; + } - if (!SCNetworkSetAddService(newSet, newService)) { - SC_log(LOG_INFO, "SCNetworkSetAddService() failed"); - } - } + SC_log(LOG_INFO, " adding service to set: %@", SCNetworkSetGetSetID(newSet)); + if (SCNetworkSetAddService(newSet, newService)) { + serviceAdded = TRUE; + } else { + SC_log(LOG_INFO, "SCNetworkSetAddService() failed"); } } + if (!serviceAdded) { + SCNetworkServiceRemove(newService); + SC_log(LOG_INFO, " service not added to any sets"); + goto done; + } + protocols = SCNetworkServiceCopyProtocols(service); if (protocols != NULL) { @@ -2542,21 +2551,15 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef prefs, done: + if (interfaceEntity != NULL) { + CFRelease(interfaceEntity); + } if (newInterface != NULL) { CFRelease(newInterface); } - if (interfaceEntityMutable != NULL) { - CFRelease(interfaceEntityMutable); - } if (newService != NULL) { CFRelease(newService); } - if (ni_prefs != NULL) { - CFRelease(ni_prefs); - } - if (ni_interface != NULL) { - CFRelease(ni_interface); - } return success; } diff --git a/scutil.tproj/net.c b/scutil.tproj/net.c index 005606b..d1e32a6 100644 --- a/scutil.tproj/net.c +++ b/scutil.tproj/net.c @@ -1248,3 +1248,39 @@ do_net_snapshot(int argc, char **argv) return; } + +__private_extern__ +void +do_configuration(int argc, char **argv) +{ + const char *description = NULL; + SCPreferencesRef ni_prefs; + CFStringRef path = NULL; + SCPreferencesRef prefs; + int _sc_log_save; + + // scutil --configuration + // scutil --configuration + // scutil --configuraiton + + if (argc > 0) { + if (argc > 1) { + description = argv[0]; + } + path = CFStringCreateWithCString(NULL, + argc > 1 ? argv[1] : argv[0], + kCFStringEncodingUTF8); + } + prefs = SCPreferencesCreate(NULL, CFSTR("scutil --configuration"), path); + ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG); + + _sc_log_save = _sc_log; + _sc_log = kSCLogDestinationFile; + __SCNetworkConfigurationReport(LOG_NOTICE, description, prefs, ni_prefs); + _sc_log = _sc_log_save; + + if (path != NULL) CFRelease(path); + CFRelease(prefs); + CFRelease(ni_prefs); + exit(0); +} diff --git a/scutil.tproj/net.h b/scutil.tproj/net.h index b8c78c8..77dd447 100644 --- a/scutil.tproj/net.h +++ b/scutil.tproj/net.h @@ -132,6 +132,8 @@ void do_net_upgrade (int argc, char **argv); void do_net_snapshot (int argc, char **argv); +void do_configuration(int argc, char **argv); + __END_DECLS #endif /* !_NET_H */ diff --git a/scutil.tproj/scutil.c b/scutil.tproj/scutil.c index a5cc354..8f6e263 100644 --- a/scutil.tproj/scutil.c +++ b/scutil.tproj/scutil.c @@ -94,6 +94,7 @@ static const struct option longopts[] = { // { "timeout", required_argument, NULL, 't' }, // { "wait-key", required_argument, NULL, 'w' }, // { "watch-reachability", no_argument, NULL, 'W' }, + { "configuration", no_argument, NULL, 0 }, { "dns", no_argument, NULL, 0 }, { "get", required_argument, NULL, 0 }, { "error", required_argument, NULL, 0 }, @@ -406,11 +407,12 @@ prompt(EditLine *el) int main(int argc, char * const argv[]) { + const char * advisoryInterface = NULL; #if !TARGET_OS_IPHONE Boolean allowNewInterfaces = FALSE; #endif // !TARGET_OS_IPHONE + Boolean configuration = FALSE; Boolean disableUntilNeeded = FALSE; - const char * advisoryInterface = NULL; Boolean doAdvisory = FALSE; Boolean doDNS = FALSE; Boolean doNet = FALSE; @@ -468,7 +470,10 @@ main(int argc, char * const argv[]) watch = TRUE; break; case 0: - if (strcmp(longopts[opti].name, "dns") == 0) { + if (strcmp(longopts[opti].name, "configuration") == 0) { + configuration = TRUE; + xStore++; + } else if (strcmp(longopts[opti].name, "dns") == 0) { doDNS = TRUE; xStore++; } else if (strcmp(longopts[opti].name, "error") == 0) { @@ -538,6 +543,12 @@ main(int argc, char * const argv[]) usage(prog); } + /* are we asking for a configuration summary */ + if (configuration) { + do_configuration(argc, (char **)argv); + /* NOT REACHED */ + } + /* are we checking (or watching) the reachability of a host/address */ if (doReach) { if (argc < 1) { -- 2.45.2