/*
- * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2019 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*/
-#include <Availability.h>
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFRuntime.h>
#define kPCIThunderboltString "PCI-Thunderbolt"
#endif
+#if TARGET_OS_OSX
+#ifndef kUSBSupportsIPhoneOS
+#define kUSBSupportsIPhoneOS "SupportsIPhoneOS"
+#endif // !kUSBSupportsIPhoneOS
+#endif // TARGET_OS_OSX
+
#ifndef kIOUserEthernetInterfaceRoleKey
#define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
#endif
#include <pthread.h>
#include <ifaddrs.h>
+/* CrashReporter "Application Specific Information" */
+#include <CrashReporterClient.h>
+
static CFStringRef copy_interface_string (CFBundleRef bundle, CFStringRef key, Boolean localized);
static CFStringRef __SCNetworkInterfaceCopyDescription (CFTypeRef cf);
static Boolean __SCNetworkInterfaceEqual (CFTypeRef cf1, CFTypeRef cf2);
static CFHashCode __SCNetworkInterfaceHash (CFTypeRef cf);
static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName, CFArrayRef matchingInterfaces);
-static Boolean __SCNetworkInterfaceCacheIsOpen ();
+static Boolean __SCNetworkInterfaceCacheIsOpen (void);
static CFArrayRef __SCNetworkInterfaceCacheCopy (CFStringRef bsdName);
enum {
- kSortInternalModem,
+ kSortInternalModem = 0,
kSortUSBModem,
kSortModem,
kSortBluetooth,
kSortBluetoothPAN_NAP,
kSortBluetoothPAN_U,
kSortThunderbolt,
+ kSortCarPlay,
kSortBond,
kSortBridge,
kSortVLAN,
};
+static const char *sortOrderName[] = {
+ "InternalModem",
+ "USBModem",
+ "Modem",
+ "Bluetooth",
+ "IrDA",
+ "SerialPort",
+ "WWAN",
+ "EthernetPPP",
+ "AirportPPP",
+ "Ethernet",
+ "FireWire",
+ "AirPort",
+ "OtherWireless",
+ "Tethered",
+ "WWANEthernet",
+ "BluetoothPAN_GN",
+ "BluetoothPAN_NAP",
+ "BluetoothPAN_U",
+ "Thunderbolt",
+ "CarPlay",
+ "Bond",
+ "Bridge",
+ "VLAN",
+ "Unknown"
+};
+
+
const CFStringRef kSCNetworkInterfaceType6to4 = CFSTR("6to4");
const CFStringRef kSCNetworkInterfaceTypeBluetooth = CFSTR("Bluetooth");
const CFStringRef kSCNetworkInterfaceTypeBond = CFSTR("Bond");
{ &kSCNetworkInterfaceTypePPTP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone },
#pragma GCC diagnostic pop
{ &kSCNetworkInterfaceTypeSerial , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- { &kSCNetworkInterfaceTypeVLAN , &kSCEntNetEthernet , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeVLAN , &kSCEntNetEthernet , TRUE , doNone, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB },
{ &kSCNetworkInterfaceTypeVPN , &kSCEntNetVPN , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
{ &kSCNetworkInterfaceTypeWWAN , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
// ===================================== =================== ========== =============== ======================================= =========================================
if (interfacePrivate->hidden) {
CFStringAppendFormat(result, NULL, CFSTR(", hidden = TRUE"));
}
+#if TARGET_OS_IPHONE
+ if (interfacePrivate->trustRequired) {
+ CFStringAppendFormat(result, NULL, CFSTR(", trust required = TRUE"));
+ }
+#endif // TARGET_OS_IPHONE
if (interfacePrivate->location != NULL) {
CFStringAppendFormat(result, NULL, CFSTR(", location = %@"), interfacePrivate->location);
}
CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction);
}
if (interfacePrivate->overrides != NULL) {
- CFStringAppendFormat(result, formatOptions, CFSTR(", overrides = %p"), interfacePrivate->overrides);
+ CFStringRef str;
+
+ str = _SCCopyDescription(interfacePrivate->overrides, formatOptions);
+ CFStringAppendFormat(result, formatOptions, CFSTR(", overrides = %@"), str);
+ CFRelease(str);
}
- CFStringAppendFormat(result, NULL, CFSTR(", order = %d"), interfacePrivate->sort_order);
+ CFStringAppendFormat(result, NULL, CFSTR(", order = %d (%s)"),
+ interfacePrivate->sort_order,
+ interfacePrivate->sort_order <= kSortUnknown ? sortOrderName[interfacePrivate->sort_order] : "?");
if (interfacePrivate->prefs != NULL) {
CFStringAppendFormat(result, NULL, CFSTR(", prefs = %p"), interfacePrivate->prefs);
}
if (*pci_slot_name != NULL) CFRelease(*pci_slot_name);
*pci_slot_name = parent_pci_slot_name;
} else {
- CFRelease(parent_pci_slot_name);
+ if (parent_pci_slot_name != NULL) CFRelease(parent_pci_slot_name);
}
}
interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->sort_order = kSortBluetoothPAN_U;
+ } else if (CFEqual(val, CFSTR("CarPlay"))) {
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+ interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
+ interfacePrivate->sort_order = kSortCarPlay;
}
}
}
}
+#if TARGET_OS_OSX
+ if (interfacePrivate->interface_type == NULL) {
+ val = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ CFSTR(kUSBSupportsIPhoneOS),
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (val != NULL) {
+ if (isA_CFBoolean(val) && CFBooleanGetValue(val)) {
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+ interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
+ interfacePrivate->sort_order = kSortTethered;
+ }
+
+ CFRelease(val);
+ }
+ }
+#endif // TARGET_OS_OSX
+
if (interfacePrivate->interface_type == NULL) {
str = IODictionaryCopyCFStringValue(bus_dict, CFSTR("name"));
if (str != NULL) {
CFTypeRef val;
// Keys of interest
-#if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
-#else
const CFStringRef interface_dict_keys[] = {
CFSTR(kIOInterfaceType),
CFSTR(kIOBuiltin),
CFSTR(kIOSerialBSDTypeKey),
CFSTR(kIOLocation)
};
-#endif // !TARGET_OS_SIMULATOR
const CFStringRef controller_dict_keys[] = {
CFSTR(kIOFeatures),
}
}
-#if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
- // get the dictionary associated with the [interface] node
- kr = IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
- if (kr != kIOReturnSuccess) {
- SC_log(LOG_INFO, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr);
- goto done;
- }
-#else
interface_dict = copyIORegistryProperties(interface,
interface_dict_keys,
sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
-#endif // !TARGET_OS_SIMULATOR
// get the controller node
kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
interfacePrivate->hidden = TRUE;
CFRelease(val);
}
+
+#if TARGET_OS_IPHONE
+ // get TrustRequired preference
+ val = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ kSCNetworkInterfaceTrustRequiredKey,
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (val != NULL) {
+ if (isA_CFBoolean(val)) {
+ interfacePrivate->trustRequired = CFBooleanGetValue(val);
+ }
+ CFRelease(val);
+ }
+#endif // TARGET_OS_IPHONE
} else {
CFRelease(interfacePrivate);
interfacePrivate = NULL;
kSCNetworkInterfaceHiddenConfigurationKey,
kCFBooleanTrue);
}
+#if TARGET_OS_IPHONE
+ if (interfacePrivate->trustRequired) {
+ CFDictionarySetValue(entity,
+ kSCNetworkInterfaceTrustRequiredKey,
+ kCFBooleanTrue);
+ }
+#endif // TARGET_OS_IPHONE
// match the "hardware" with the lowest layer
while (TRUE) {
struct ifreq ifr;
SCNetworkInterfaceRef interface;
- bzero(&ifr, sizeof(ifr));
+ memset(&ifr, 0, sizeof(ifr));
if (_SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) {
int s;
}
+__private_extern__
void
-_SCNetworkInterfaceCacheOpen()
+_SCNetworkInterfaceCacheOpen(void)
{
if (!__SCNetworkInterfaceCacheIsOpen()) {
S_interface_cache = CFDictionaryCreateMutable(NULL,
}
+__private_extern__
void
-_SCNetworkInterfaceCacheClose()
+_SCNetworkInterfaceCacheClose(void)
{
if (__SCNetworkInterfaceCacheIsOpen()) {
SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): close", S_interface_cache);
static inline Boolean
-__SCNetworkInterfaceCacheIsOpen()
+__SCNetworkInterfaceCacheIsOpen(void)
{
return (S_interface_cache != NULL);
}
(((virtualInterface = findBridgeInterface(servicePref, ifDevice)) != NULL) ||
#if !TARGET_OS_IPHONE
((virtualInterface = findBondInterface(servicePref, ifDevice)) != NULL) ||
-#endif
+#endif // !TARGET_OS_IPHONE
((virtualInterface = findVLANInterface(servicePref, ifDevice)) != NULL))) {
CFRelease(interfacePrivate);
interfacePrivate = (SCNetworkInterfacePrivateRef)virtualInterface;
if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceHiddenConfigurationKey)) {
interfacePrivate->hidden = TRUE;
}
+#if TARGET_OS_IPHONE
+ if (CFDictionaryContainsKey(interface_entity, kSCNetworkInterfaceTrustRequiredKey)) {
+ interfacePrivate->trustRequired = TRUE;
+ }
+#endif // TARGET_OS_IPHONE
}
if (service != NULL) {
static void
__waitForInterfaces()
{
- CFStringRef key;
+ CFStringRef key = NULL;
CFArrayRef keys;
Boolean ok;
- SCDynamicStoreRef store;
+ SCDynamicStoreRef store = NULL;
+
+ CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL, NULL);
if (store == NULL) {
- return;
+ goto done;
}
key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
done :
- CFRelease(key);
- CFRelease(store);
+ CRSetCrashLogMessage(NULL);
+
+ if (key != NULL) CFRelease(key);
+ if (store != NULL) CFRelease(store);
return;
}
parentPrivate->hidden = childPrivate->hidden;
+#if TARGET_OS_IPHONE
+ parentPrivate->trustRequired = childPrivate->trustRequired;
+#endif // TARGET_OS_IPHONE
+
if (childPrivate->overrides != NULL) {
parentPrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, childPrivate->overrides);
}
knownStrKey,
localized);
-#if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE
/* ...and we want to know about it! */
_SC_crash("Failed to retrieve interface string", NULL, NULL);
-#endif //TARGET_OS_IPHONE
+#endif //TARGET_OS_IPHONE
reported = TRUE;
}
__private_extern__
-CFDictionaryRef
+CFPropertyListRef
__SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface, CFStringRef overrideType)
{
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
- CFDictionaryRef overrides = NULL;
+ CFPropertyListRef overrides = NULL;
if (interfacePrivate->overrides != NULL) {
overrides = CFDictionaryGetValue(interfacePrivate->overrides, overrideType);
#pragma mark SCNetworkInterface [Refresh Configuration] API
-#ifndef kSCEntNetRefreshConfiguration
-#define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
-#endif // kSCEntNetRefreshConfiguration
-
Boolean
_SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName)
{
}
+#if !TARGET_OS_IPHONE
Boolean
SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName)
{
return _SCNetworkInterfaceForceConfigurationRefresh(ifName);
}
+#endif // !TARGET_OS_IPHONE
#pragma mark -
return ok;
}
+#pragma mark -
+#pragma mark SCNetworkInterface [Advisory] SPIs
+#if TARGET_OS_SIMULATOR
+Boolean
+SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface,
+ SCNetworkInterfaceAdvisory advisory,
+ CFStringRef reason)
+{
+#pragma unused(interface)
+#pragma unused(advisory)
+#pragma unused(reason)
+ return (FALSE);
+}
+
+Boolean
+SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface)
+{
+#pragma unused(interface)
+ return (FALSE);
+}
+
+CFStringRef
+SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface)
+{
+#pragma unused(interface)
+ return (NULL);
+}
+
+#else /* TARGET_OS_SIMULATOR */
+Boolean
+SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface,
+ SCNetworkInterfaceAdvisory advisory,
+ CFStringRef reason)
+{
+ IPMonitorControlRef control;
+ SCNetworkInterfacePrivateRef interfacePrivate =
+ (SCNetworkInterfacePrivateRef)interface;
+ CFStringRef ifName;
+
+ ifName = SCNetworkInterfaceGetBSDName(interface);
+ if (ifName == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ control = interfacePrivate->IPMonitorControl;
+ if (control == NULL) {
+ control = IPMonitorControlCreate();
+ if (control == NULL) {
+ _SCErrorSet(kSCStatusFailed);
+ return (FALSE);
+ }
+ interfacePrivate->IPMonitorControl = control;
+ }
+ return IPMonitorControlSetInterfaceAdvisory(control,
+ ifName,
+ advisory,
+ reason);
+}
+
+Boolean
+SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface)
+{
+ IPMonitorControlRef control;
+ SCNetworkInterfacePrivateRef interfacePrivate =
+ (SCNetworkInterfacePrivateRef)interface;
+ CFStringRef ifName;
+
+ ifName = SCNetworkInterfaceGetBSDName(interface);
+ if (ifName == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ control = interfacePrivate->IPMonitorControl;
+ if (control == NULL) {
+ control = IPMonitorControlCreate();
+ if (control == NULL) {
+ _SCErrorSet(kSCStatusFailed);
+ return (FALSE);
+ }
+ interfacePrivate->IPMonitorControl = control;
+ }
+ return IPMonitorControlInterfaceAdvisoryIsSet(control, ifName);
+}
+
+CFStringRef
+SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface)
+{
+ CFStringRef ifName;
+
+ ifName = SCNetworkInterfaceGetBSDName(interface);
+ if (ifName == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (NULL);
+ }
+ return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName);
+}
+#endif /* TARGET_OS_SIMULATOR */
#pragma mark -
#pragma mark SCNetworkInterface [InterfaceNamer] SPIs
CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
struct ifreq ifr;
- bzero(&ifr, sizeof(ifr));
+ memset(&ifr, 0, sizeof(ifr));
if ((bsdName != NULL) &&
_SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) {
int s;
}
+Boolean
+_SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->trustRequired;
+}
+
+
#pragma mark -
#pragma mark SCNetworkInterface SPIs
-#if !TARGET_OS_EMBEDDED
+#if TARGET_OS_OSX
SCNetworkInterfaceRef
_SCNetworkInterfaceCopyBTPANInterface(void)
return interface;
}
-#endif // !TARGET_OS_EMBEDDED
+#endif // TARGET_OS_OSX
CFStringRef
#else // TARGET_OS_SIMULATOR
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
- if (!interfacePrivate->hidden) {
+ if (!_SCNetworkInterfaceIsHiddenConfiguration(interface)) {
// if not HiddenConfiguration
return FALSE;
}
return FALSE;
}
- if (interfacePrivate->builtin) {
+ if (_SCNetworkInterfaceIsBuiltin(interface)) {
// if built-in (and overrides are present)
return TRUE;
}
+ if (_SCNetworkInterfaceIsCarPlay(interface)) {
+ // if CarPlay (and overrides are present)
+ return TRUE;
+ }
+
if (isA_CFNumber(interfacePrivate->usb.vid)) {
int vid;
}
+Boolean
+_SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return (interfacePrivate->sort_order == kSortCarPlay);
+}
+
+
Boolean
_SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface)
{
newPrivate->configurationAction = CFRetain(oldPrivate->configurationAction);
}
newPrivate->hidden = oldPrivate->hidden;
+#if TARGET_OS_IPHONE
+ newPrivate->trustRequired = oldPrivate->trustRequired;
+#endif // TARGET_OS_IPHONE
if (oldPrivate->location != NULL) {
newPrivate->location = CFRetain(oldPrivate->location);
}