/*
- * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2019 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
-#include <Availability.h>
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFRuntime.h>
-#include <SystemConfiguration/SystemConfiguration.h>
#include "SCNetworkConfigurationInternal.h"
-#include <SystemConfiguration/SCValidation.h>
-#include <SystemConfiguration/SCPrivate.h>
#include "SCPreferencesInternal.h"
#include "SCHelper_client.h"
+#include "plugin_shared.h"
#if !TARGET_OS_IPHONE
#include <EAP8021X/EAPClientProperties.h>
#include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
#include <IOKit/serial/IOSerialKeys.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
-#include <IOKit/usb/USB.h>
+#if !TARGET_OS_SIMULATOR
+#include <IOKit/usb/IOUSBLib.h>
+#endif // !TARGET_OS_SIMULATOR
#include "dy_framework.h"
-#ifndef kIODeviceSupportsHoldKey
-#define kIODeviceSupportsHoldKey "V92Modem"
-#endif
-
#ifndef kPCIThunderboltString
#define kPCIThunderboltString "PCI-Thunderbolt"
#endif
-#ifndef kUSBProductString
-#define kUSBProductString "USB Product Name"
-#endif
+#if TARGET_OS_OSX
+#ifndef kUSBSupportsIPhoneOS
+#define kUSBSupportsIPhoneOS "SupportsIPhoneOS"
+#endif // !kUSBSupportsIPhoneOS
+#endif // TARGET_OS_OSX
#ifndef kIOUserEthernetInterfaceRoleKey
#define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
#endif
+#ifndef kIOUSBHostInterfaceClassName
+#define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
+#endif
+
#include <string.h>
+#include <sysdir.h>
#include <mach/mach.h>
#include <net/if.h>
#include <net/if_types.h>
+#include <net/if_dl.h>
#include <net/route.h>
+#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <pthread.h>
-#include <NSSystemDirectories.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 void __SCNetworkInterfaceDeallocate (CFTypeRef cf);
-static Boolean __SCNetworkInterfaceEqual (CFTypeRef cf1, CFTypeRef cf2);
-static CFHashCode __SCNetworkInterfaceHash (CFTypeRef cf);
+
+static CFStringRef copy_interface_string (CFBundleRef bundle, CFStringRef key, Boolean localized);
+static CFStringRef __SCNetworkInterfaceCopyDescription (CFTypeRef cf);
+static CFStringRef __SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf, CFDictionaryRef formatOptions);
+static void __SCNetworkInterfaceDeallocate (CFTypeRef cf);
+static Boolean __SCNetworkInterfaceEqual (CFTypeRef cf1, CFTypeRef cf2);
+static CFHashCode __SCNetworkInterfaceHash (CFTypeRef cf);
+static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName, CFArrayRef matchingInterfaces);
+static Boolean __SCNetworkInterfaceCacheIsOpen (void);
+static CFArrayRef __SCNetworkInterfaceCacheCopy (CFStringRef bsdName);
enum {
- kSortInternalModem,
+ kSortInternalModem = 0,
kSortUSBModem,
kSortModem,
kSortBluetooth,
kSortBluetoothPAN_GN,
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");
const CFStringRef kSCNetworkInterfaceTypeIPv4 = CFSTR("IPv4");
static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4 = {
- INIT_CFRUNTIME_BASE(), // cfBase
- NULL, // interface type
- NULL, // name
- NULL, // localized name
- NULL, // localization key
- NULL, // localization arg1
- NULL, // localization arg2
- NULL, // [layered] interface
- NULL, // prefs
- NULL, // store
- NULL, // serviceID
- NULL, // unsaved
- NULL, // entity_device
- NULL, // entity_device_unique
- NULL, // entity_type
- NULL, // entity_subtype
- NULL, // supported_interface_types
- NULL, // supported_protocol_types
- NULL, // address
- NULL, // addressString
- FALSE, // builtin
- NULL, // configurationAction
- FALSE, // hidden
- NULL, // location
- NULL, // path
- 0, // entryID
- NULL, // overrides
- FALSE, // modemIsV92
- NULL, // type
- NULL, // unit
- { NULL, 0, 0 }, // usb { name, vid, pid }
- kSortUnknown, // sort_order
- FALSE, // supportsBond
- { NULL, NULL, NULL }, // bond { interfaces, options, mode }
- FALSE, // supportsBridge
- { NULL, NULL }, // bridge { interfaces, options }
- FALSE, // supportsVLAN
- { NULL, NULL, NULL } // vlan { interface, tag, options }
+ .cfBase = INIT_CFRUNTIME_BASE(), // cfBase
+ .sort_order = kSortUnknown, // sort_order
};
const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4 = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceIPv4;
static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback = {
- INIT_CFRUNTIME_BASE(), // cfBase
- NULL, // interface type
- NULL, // name
- NULL, // localized name
- NULL, // localization key
- NULL, // localization arg1
- NULL, // localization arg2
- NULL, // [layered] interface
- NULL, // prefs
- NULL, // store
- NULL, // serviceID
- NULL, // unsaved
- NULL, // entity_device
- NULL, // entity_device_unique
- NULL, // entity_type
- NULL, // entity_subtype
- NULL, // supported_interface_types
- NULL, // supported_protocol_types
- NULL, // address
- NULL, // addressString
- FALSE, // builtin
- NULL, // configurationAction
- FALSE, // hidden
- NULL, // location
- NULL, // path
- 0, // entryID
- NULL, // overrides
- FALSE, // modemIsV92
- NULL, // type
- NULL, // unit
- { NULL, 0, 0 }, // usb { name, vid, pid }
- kSortUnknown, // sort_order
- FALSE, // supportsBond
- { NULL, NULL, NULL }, // bond { interfaces, options, mode }
- FALSE, // supportsBridge
- { NULL, NULL }, // bridge { interfaces, options }
- FALSE, // supportsVLAN
- { NULL, NULL, NULL } // vlan { interface, tag, options }
+ .cfBase = INIT_CFRUNTIME_BASE(), // cfBase
+ .sort_order = kSortUnknown, // sort_order
};
const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceLoopback;
static CFMutableSetRef vendor_interface_types = NULL;
+// A thread-specific convenience cache of all interfaces matching a bsd name
+// Key: CFStringRef (BSD name)
+// Value: CFArrayRef (matching interfaces)
+static __thread CFMutableDictionaryRef S_interface_cache = NULL;
+
#pragma mark -
#pragma mark SCNetworkInterface configuration details
const CFStringRef *ppp_subtype;
uint32_t supported_protocols;
} configurations[] = {
- // interface type entity_hardware if config? interface types PPP sub-type interface protocols
- // ===================================== ================= ========== =============== ======================================= =========================================
- { &kSCNetworkInterfaceType6to4 , &kSCEntNet6to4 , FALSE, doNone, NULL, doIPv6 },
- { &kSCNetworkInterfaceTypeBluetooth , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- { &kSCNetworkInterfaceTypeBond , &kSCEntNetEthernet, TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeBridge , &kSCEntNetEthernet, TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeEthernet , &kSCEntNetEthernet, TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeFireWire , &kSCEntNetFireWire, TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeIEEE80211 , &kSCEntNetAirPort , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeIPSec , &kSCEntNetIPSec , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeIrDA , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- { &kSCNetworkInterfaceTypeL2TP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypeL2TP, doNone },
- { &kSCNetworkInterfaceTypeModem , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- { &kSCNetworkInterfaceTypePPP , &kSCEntNetPPP , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypePPTP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone },
- { &kSCNetworkInterfaceTypeSerial , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- { &kSCNetworkInterfaceTypeVLAN , &kSCEntNetEthernet, TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeVPN , &kSCEntNetVPN , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
- { &kSCNetworkInterfaceTypeWWAN , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
- // ===================================== ================= ========== =============== ======================================= =========================================
- { &kSCNetworkInterfaceTypeLoopback , NULL , TRUE , doNone, NULL, doIPv4|doIPv6 },
- // ===================================== ================= ========== =============== ======================================= =========================================
- { &kSCNetworkInterfaceTypeIPv4 , NULL , FALSE, doOverIP, NULL, doNone }
+ // interface type entity_hardware if config? interface types PPP sub-type interface protocols
+ // ===================================== ==================== ========== =============== ======================================= =========================================
+ { &kSCNetworkInterfaceType6to4 , &kSCEntNet6to4 , FALSE, doNone, NULL, doIPv6 },
+ { &kSCNetworkInterfaceTypeBluetooth , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
+ { &kSCNetworkInterfaceTypeBond , &kSCEntNetEthernet , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeBridge , &kSCEntNetEthernet , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeEthernet , &kSCEntNetEthernet , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeFireWire , &kSCEntNetFireWire , TRUE , doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeIEEE80211 , &kSCEntNetAirPort , TRUE , doPPP, &kSCValNetInterfaceSubTypePPPoE, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeIPSec , &kSCEntNetIPSec , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+ { &kSCNetworkInterfaceTypeIrDA , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
+ { &kSCNetworkInterfaceTypeL2TP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypeL2TP, doNone },
+ { &kSCNetworkInterfaceTypeModem , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
+ { &kSCNetworkInterfaceTypePPP , &kSCEntNetPPP , FALSE, doNone, NULL, doDNS|doIPv4|doIPv6|doProxies|doSMB },
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+ { &kSCNetworkInterfaceTypePPTP , NULL , FALSE, doPPP, &kSCValNetInterfaceSubTypePPTP, doNone },
+#pragma GCC diagnostic pop
+ { &kSCNetworkInterfaceTypeSerial , &kSCEntNetModem , FALSE, doPPP, &kSCValNetInterfaceSubTypePPPSerial, doNone },
+ { &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 },
+ // ===================================== =================== ========== =============== ======================================= =========================================
+ { &kSCNetworkInterfaceTypeLoopback , NULL , TRUE , doNone, NULL, doIPv4|doIPv6 },
+ // ===================================== =================== ========== =============== ======================================= =========================================
+ { &kSCNetworkInterfaceTypeIPv4 , NULL , FALSE, doOverIP, NULL, doNone }
};
+#define kSCNetworkInterfaceActive "Active"
+#define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
+#define kSCNetworkInterfaceType "SCNetworkInterfaceType"
+#define kSCNetworkInterfaceBSDName kIOBSDNameKey
+#define kSCNetworkInterfaceIOBuiltin kIOBuiltin
+#define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
+#define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
+#define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
+#define kSCNetworkInterfaceIOMACAddress kIOMACAddress
+#define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
+
+
#define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
static CFBundleRef bundle = NULL;
static const CFRuntimeClass __SCNetworkInterfaceClass = {
- 0, // version
- "SCNetworkInterface", // className
- NULL, // init
- NULL, // copy
- __SCNetworkInterfaceDeallocate, // dealloc
- __SCNetworkInterfaceEqual, // equal
- __SCNetworkInterfaceHash, // hash
- NULL, // copyFormattingDesc
- __SCNetworkInterfaceCopyDescription // copyDebugDesc
+ 0, // version
+ "SCNetworkInterface", // className
+ NULL, // init
+ NULL, // copy
+ __SCNetworkInterfaceDeallocate, // dealloc
+ __SCNetworkInterfaceEqual, // equal
+ __SCNetworkInterfaceHash, // hash
+ __SCNetworkInterfaceCopyFormattingDescription, // copyFormattingDesc
+ __SCNetworkInterfaceCopyDescription // copyDebugDesc
};
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
static pthread_once_t iokit_quiet = PTHREAD_ONCE_INIT;
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static mach_port_t masterPort = MACH_PORT_NULL;
-
static CFStringRef
__SCNetworkInterfaceCopyDescription(CFTypeRef cf)
+{
+ return __SCNetworkInterfaceCopyFormattingDescription(cf, NULL);
+}
+
+static CFStringRef
+__SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions)
{
CFAllocatorRef allocator = CFGetAllocator(cf);
CFMutableStringRef result;
CFIndex dataLen;
CFIndex i;
- CFStringAppendFormat(result, NULL, CFSTR(", address = 0x"));
+ CFStringAppendFormat(result, NULL, CFSTR(", address = "));
data = CFDataGetBytePtr(interfacePrivate->address);
dataLen = CFDataGetLength(interfacePrivate->address);
for (i = 0; i < dataLen; i++) {
- CFStringAppendFormat(result, NULL, CFSTR("%02x"), data[i]);
+ CFStringAppendFormat(result, NULL, CFSTR("%s%02x"),
+ (i > 0) ? ":" : "",
+ data[i]);
}
}
CFStringAppendFormat(result, NULL, CFSTR(", builtin = %s"), interfacePrivate->builtin ? "TRUE" : "FALSE");
if (interfacePrivate->hidden) {
CFStringAppendFormat(result, NULL, CFSTR(", hidden = TRUE"));
}
- if (interfacePrivate->modemIsV92) {
- CFStringAppendFormat(result, NULL, CFSTR(", v.92"));
+#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);
}
if (interfacePrivate->unit != NULL) {
CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
}
+ if (interfacePrivate->family != NULL) {
+ CFStringAppendFormat(result, NULL, CFSTR(", family = %@"), interfacePrivate->family);
+ }
+ if (interfacePrivate->subfamily != NULL) {
+ CFStringAppendFormat(result, NULL, CFSTR(", subfamily = %@"), interfacePrivate->subfamily);
+ }
if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
- int pid;
- int vid;
+ int pid = 0;
+ int vid = 0;
if (!isA_CFNumber(interfacePrivate->usb.pid) ||
- !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &pid)) {
+ !CFNumberGetValue(interfacePrivate->usb.pid, kCFNumberIntType, &pid)) {
pid = 0;
}
if (!isA_CFNumber(interfacePrivate->usb.vid) ||
}
CFStringAppendFormat(result, NULL, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
- interfacePrivate->usb.vid,
- interfacePrivate->usb.pid);
+ vid,
+ pid);
}
if (interfacePrivate->configurationAction != NULL) {
CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction);
}
if (interfacePrivate->overrides != NULL) {
- CFStringAppendFormat(result, NULL, 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);
}
CFStringAppendFormat(result, NULL, CFSTR(", interface = %@"), interfacePrivate->interface);
}
if (interfacePrivate->unsaved != NULL) {
- CFStringAppendFormat(result, NULL, CFSTR(", unsaved = %@"), interfacePrivate->unsaved);
+ CFStringAppendFormat(result, formatOptions, CFSTR(", unsaved = %@"), interfacePrivate->unsaved);
}
if (interfacePrivate->bond.interfaces != NULL) {
member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i);
CFStringAppendFormat(result, NULL,
CFSTR("%s%@"),
- (i == 0) ? ", interfaces = " : ", ",
+ (i == 0) ? ", interfaces = " : ",",
SCNetworkInterfaceGetBSDName(member));
}
}
CFStringAppendFormat(result, NULL, CFSTR(", mode = %@"), interfacePrivate->bond.mode);
}
if (interfacePrivate->bond.options != NULL) {
- CFStringAppendFormat(result, NULL, CFSTR(", options = %@"), interfacePrivate->bond.options);
+ CFStringRef str;
+
+ str = _SCCopyDescription(interfacePrivate->bond.options, formatOptions);
+ CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str);
+ CFRelease(str);
}
if (interfacePrivate->bridge.interfaces != NULL) {
member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i);
CFStringAppendFormat(result, NULL,
CFSTR("%s%@"),
- (i == 0) ? ", interfaces = " : ", ",
+ (i == 0) ? ", interfaces = " : ",",
SCNetworkInterfaceGetBSDName(member));
}
}
if (interfacePrivate->bridge.options != NULL) {
- CFStringAppendFormat(result, NULL, CFSTR(", options = %@"), interfacePrivate->bridge.options);
+ CFStringRef str;
+
+ str = _SCCopyDescription(interfacePrivate->bridge.options, formatOptions);
+ CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str);
+ CFRelease(str);
}
if (interfacePrivate->vlan.interface != NULL) {
CFStringAppendFormat(result, NULL, CFSTR(", tag = %@"), interfacePrivate->vlan.tag);
}
if (interfacePrivate->vlan.options != NULL) {
- CFStringAppendFormat(result, NULL, CFSTR(", options = %@"), interfacePrivate->vlan.options);
+ CFStringRef str;
+
+ str = _SCCopyDescription(interfacePrivate->vlan.options, formatOptions);
+ CFStringAppendFormat(result, formatOptions, CFSTR(", options = %@"), str);
+ CFRelease(str);
}
CFStringAppendFormat(result, NULL, CFSTR("}"));
if (interfacePrivate->overrides != NULL)
CFRelease(interfacePrivate->overrides);
+ if (interfacePrivate->prefix != NULL)
+ CFRelease(interfacePrivate->prefix);
+
if (interfacePrivate->type != NULL)
CFRelease(interfacePrivate->type);
if (interfacePrivate->unit != NULL)
CFRelease(interfacePrivate->unit);
+ if (interfacePrivate->family != NULL)
+ CFRelease(interfacePrivate->family);
+
+ if (interfacePrivate->subfamily != NULL)
+ CFRelease(interfacePrivate->subfamily);
+
if (interfacePrivate->usb.name != NULL)
CFRelease(interfacePrivate->usb.name);
if (interfacePrivate->vlan.options != NULL)
CFRelease(interfacePrivate->vlan.options);
-
+#if !TARGET_OS_SIMULATOR
+ if (interfacePrivate->IPMonitorControl != NULL)
+ CFRelease(interfacePrivate->IPMonitorControl);
+#endif // !TARGET_OS_SIMULATOR
return;
}
// get mach port used to communication with IOKit
kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("__SCNetworkInterfaceInitialize(), could not get IOMasterPort, kr = 0x%x"),
- kr);
+ if (kr != kIOReturnSuccess) {
+ SC_log(LOG_NOTICE, "could not get IOMasterPort, kr = 0x%x", kr);
}
return;
return NULL;
}
- interfacePrivate->interface_type = NULL;
- interfacePrivate->name = NULL;
- interfacePrivate->localized_name = NULL;
- interfacePrivate->localized_key = NULL;
- interfacePrivate->localized_arg1 = NULL;
- interfacePrivate->localized_arg2 = NULL;
- interfacePrivate->interface = (interface != NULL) ? CFRetain(interface) : NULL;
- interfacePrivate->prefs = (prefs != NULL) ? CFRetain(prefs) : NULL;
- interfacePrivate->store = NULL;
- interfacePrivate->serviceID = (serviceID != NULL) ? CFRetain(serviceID) : NULL;
- interfacePrivate->unsaved = NULL;
- interfacePrivate->entity_device = NULL;
- interfacePrivate->entity_device_unique = NULL;
- interfacePrivate->entity_type = NULL;
- interfacePrivate->entity_subtype = NULL;
- interfacePrivate->supported_interface_types = NULL;
- interfacePrivate->supported_protocol_types = NULL;
- interfacePrivate->address = NULL;
- interfacePrivate->addressString = NULL;
- interfacePrivate->builtin = FALSE;
- interfacePrivate->configurationAction = NULL;
- interfacePrivate->hidden = FALSE;
- interfacePrivate->location = NULL;
- interfacePrivate->path = NULL;
- interfacePrivate->entryID = 0;
- interfacePrivate->overrides = NULL;
- interfacePrivate->modemIsV92 = FALSE;
- interfacePrivate->type = NULL;
- interfacePrivate->unit = NULL;
- interfacePrivate->usb.name = NULL;
- interfacePrivate->usb.vid = NULL;
- interfacePrivate->usb.pid = NULL;
- interfacePrivate->sort_order = kSortUnknown;
-
- interfacePrivate->supportsBond = FALSE;
- interfacePrivate->bond.interfaces = NULL;
- interfacePrivate->bond.mode = NULL;
- interfacePrivate->bond.options = NULL;
-
- interfacePrivate->supportsBridge = FALSE;
- interfacePrivate->bridge.interfaces = NULL;
- interfacePrivate->bridge.options = NULL;
-
- interfacePrivate->supportsVLAN = FALSE;
- interfacePrivate->vlan.interface = NULL;
- interfacePrivate->vlan.tag = NULL;
- interfacePrivate->vlan.options = NULL;
+ /* initialize non-zero/NULL members */
+ interfacePrivate->interface = (interface != NULL) ? CFRetain(interface) : NULL;
+ interfacePrivate->prefs = (prefs != NULL) ? CFRetain(prefs) : NULL;
+ interfacePrivate->serviceID = (serviceID != NULL) ? CFRetain(serviceID) : NULL;
+ interfacePrivate->sort_order = kSortUnknown;
return interfacePrivate;
}
mib[5] = if_index; /* ask for exactly one interface */
if (sysctl(mib, 6, NULL, &buf_len, NULL, 0) == -1) {
- SCLog(TRUE, LOG_ERR, CFSTR("sysctl() size failed: %s"), strerror(errno));
+ SC_log(LOG_NOTICE, "sysctl() size failed: %s", strerror(errno));
goto done;
}
buf = CFAllocatorAllocate(NULL, buf_len, 0);
if (sysctl(mib, 6, buf, &buf_len, NULL, 0) == -1) {
- SCLog(TRUE, LOG_ERR, CFSTR("sysctl() failed: %s"), strerror(errno));
+ SC_log(LOG_NOTICE, "sysctl() failed: %s", strerror(errno));
goto done;
}
}
+static CFDataRef
+__SCCopyMacAddress(CFStringRef ifname)
+{
+ struct ifaddrs *ifap;
+ char ifname_c[IFNAMSIZ];
+ struct ifaddrs *ifp;
+ CFDataRef macAddress = NULL;
+
+ if(_SC_cfstring_to_cstring(ifname,
+ ifname_c,
+ sizeof(ifname_c),
+ kCFStringEncodingUTF8) == NULL) {
+ return NULL;
+ }
+
+ if (getifaddrs(&ifap) == -1) {
+ _SCErrorSet(errno);
+ SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno));
+ return NULL;
+ }
+
+ for (ifp = ifap; ifp != NULL; ifp = ifp->ifa_next) {
+ struct sockaddr_dl *sdl;
+
+ if(strcmp(ifname_c, ifp->ifa_name) != 0) {
+ continue;
+ }
+
+ /* ALIGN: cast ok, this should be aligned (getifaddrs). */
+ sdl = (struct sockaddr_dl *)(void *)ifp->ifa_addr;
+ if (sdl->sdl_family != AF_LINK) {
+ continue;
+ }
+
+ macAddress = CFDataCreate(NULL, (UInt8 *)LLADDR(sdl), sdl->sdl_alen);
+ break;
+ }
+ freeifaddrs(ifap);
+ return macAddress;
+}
+
+
__private_extern__
SCNetworkInterfacePrivateRef
_SCBondInterfaceCreatePrivate(CFAllocatorRef allocator,
interfacePrivate->interface_type = kSCNetworkInterfaceTypeBond;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->entity_device = CFStringCreateCopy(allocator, bond_if);
+ interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device);
interfacePrivate->builtin = TRUE;
interfacePrivate->supportsVLAN = __SCNetworkInterfaceSupportsVLAN(bond_if);
interfacePrivate->sort_order = kSortBond;
interfacePrivate->interface_type = kSCNetworkInterfaceTypeBridge;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->entity_device = CFStringCreateCopy(allocator, bridge_if);
+ interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device);
interfacePrivate->builtin = TRUE;
interfacePrivate->supportsVLAN = __SCNetworkInterfaceSupportsVLAN(bridge_if);
interfacePrivate->sort_order = kSortBridge;
interfacePrivate->interface_type = kSCNetworkInterfaceTypeVLAN;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->entity_device = CFStringCreateCopy(allocator, vlan_if);
+ interfacePrivate->address = __SCCopyMacAddress(interfacePrivate->entity_device);
interfacePrivate->builtin = TRUE;
interfacePrivate->sort_order = kSortVLAN;
CFComparisonResult
_SCNetworkInterfaceCompare(const void *val1, const void *val2, void *context)
{
+#pragma unused(context)
SCNetworkInterfacePrivateRef dev1 = (SCNetworkInterfacePrivateRef)val1;
SCNetworkInterfacePrivateRef dev2 = (SCNetworkInterfacePrivateRef)val2;
CFComparisonResult res = kCFCompareEqualTo;
static void
sort_interfaces(CFMutableArrayRef all_interfaces)
{
- int n = CFArrayGetCount(all_interfaces);
+ CFIndex n;
+ n = CFArrayGetCount(all_interfaces);
if (n < 2) {
return;
}
}
+static CFStringRef
+IODictionaryCopyBSDName(CFDictionaryRef io_dict)
+{
+ CFStringRef if_bsdName;
+ CFStringRef if_prefix;
+ CFNumberRef if_unit;
+
+ if_bsdName = CFDictionaryGetValue(io_dict, CFSTR(kIOBSDNameKey));
+ if (if_bsdName != NULL) {
+ return IOCopyCFStringValue(if_bsdName);
+ }
+
+ // no BSD name, get interface prefix and unit
+ if_prefix = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceNamePrefix));
+ if_unit = CFDictionaryGetValue(io_dict, CFSTR(kIOInterfaceUnit));
+ if (isA_CFString(if_prefix) && isA_CFNumber(if_unit)) {
+ // if both prefix and unit available, construct BSD name
+ if_bsdName = CFStringCreateWithFormat(NULL,
+ NULL,
+ CFSTR("%@%@"),
+ if_prefix,
+ if_unit);
+ }
+
+ return if_bsdName;
+};
+
+
static CFStringRef
IODictionaryCopyCFStringValue(CFDictionaryRef io_dict, CFStringRef io_key)
{
slot_name = IORegistryEntryCreateCFProperty(interface, CFSTR("AAPL,slot-name"), NULL, 0);
if (slot_name != NULL) {
- CFIndex i;
-
slot = CFStringCreateMutable(NULL, 0);
if (isA_CFString(slot_name)) {
if (pci_slot_name != NULL) *pci_slot_name = CFStringCreateCopy(NULL, slot_name);
kCFStringEncodingUTF8);
}
- for (i = 0; i < sizeof(slot_prefixes)/sizeof(slot_prefixes[0]); i++) {
+ for (size_t i = 0; i < sizeof(slot_prefixes)/sizeof(slot_prefixes[0]); i++) {
CFIndex len;
len = CFStringGetLength(slot_prefixes[i]);
}
}
- for (i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) {
+ for (size_t i = 0; i < sizeof(slot_mappings)/sizeof(slot_mappings[0]); i++) {
if (CFStringCompare(slot,
slot_mappings[i].name,
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
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);
}
}
// if we have hit the root node
break;
default :
- SCLog(TRUE, LOG_DEBUG, CFSTR("pci_slot IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr);
break;
}
static CFComparisonResult
compare_bsdNames(const void *val1, const void *val2, void *context)
{
+#pragma unused(context)
CFStringRef bsd1 = (CFStringRef)val1;
CFStringRef bsd2 = (CFStringRef)val2;
kr = IOServiceGetMatchingServices(masterPort, matching, &slot_iterator);
if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("pci_port IOServiceGetMatchingServices() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
return MACH_PORT_NULL;
}
kIORegistryIterateRecursively,
&child_iterator);
if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("pci_port IORegistryEntryCreateIterator() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr);
CFRelease(port_names);
return MACH_PORT_NULL;
}
while ((child = IOIteratorNext(child_iterator)) != MACH_PORT_NULL) {
if (IOObjectConformsTo(child, kIONetworkInterfaceClass)) {
- CFNumberRef child_if_type;
- int child_ift = ift;
-
- child_if_type = IORegistryEntryCreateCFProperty(child,
- CFSTR(kIOInterfaceType),
- NULL,
- 0);
- if (child_if_type != NULL) {
- if (!isA_CFNumber(child_if_type) ||
- !CFNumberGetValue(child_if_type, kCFNumberIntType, &child_ift)) {
- // assume that it's a match
- child_ift = ift;
+ CFMutableDictionaryRef interface_dict = NULL;
+
+ (void) IORegistryEntryCreateCFProperties(child, &interface_dict, NULL, kNilOptions);
+ if (interface_dict != NULL) {
+ CFNumberRef child_if_type;
+ int child_ift = ift;
+
+ child_if_type = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType));
+ if (child_if_type != NULL) {
+ if (!isA_CFNumber(child_if_type) ||
+ !CFNumberGetValue(child_if_type, kCFNumberIntType, &child_ift)) {
+ // assume that it's a match
+ child_ift = ift;
+ }
}
- CFRelease(child_if_type);
- }
- if (ift == child_ift) {
- CFStringRef if_bsdName;
+ if (ift == child_ift) {
+ CFStringRef if_bsdName;
- if_bsdName = IORegistryEntryCreateCFProperty(child,
- CFSTR(kIOBSDNameKey),
- NULL,
- 0);
- if (if_bsdName != NULL) {
- CFArrayAppendValue(port_names, if_bsdName);
- CFRelease(if_bsdName);
+ if_bsdName = IODictionaryCopyBSDName(interface_dict);
+ if (if_bsdName != NULL) {
+ CFArrayAppendValue(port_names, if_bsdName);
+ CFRelease(if_bsdName);
+ }
}
+
+ CFRelease(interface_dict);
}
}
IOObjectRelease(child);
CFArraySortValues(port_names, CFRangeMake(0, n), compare_bsdNames, NULL);
n = CFArrayGetFirstIndexOfValue(port_names, CFRangeMake(0, n), bsdName);
if (n != kCFNotFound) {
- port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), n + 1);
+ port_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), n + 1);
}
}
static Boolean
pci_slot_info(io_registry_entry_t interface, int ift, CFStringRef *slot_name, CFStringRef *port_name)
{
- CFStringRef bsd_name;
- Boolean ok = FALSE;
- CFTypeRef pci_slot_name;
+ CFStringRef bsd_name = NULL;
+ CFMutableDictionaryRef interface_dict = NULL;
+ Boolean ok = FALSE;
+ CFTypeRef pci_slot_name;
*slot_name = NULL;
*port_name = NULL;
- bsd_name = IORegistryEntryCreateCFProperty(interface, CFSTR(kIOBSDNameKey), NULL, 0);
+ (void) IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
+ if (interface_dict != NULL) {
+ bsd_name = IODictionaryCopyBSDName(interface_dict);
+ CFRelease(interface_dict);
+ }
+
if (bsd_name == NULL) {
return FALSE;
}
&iter);
if ((kr != kIOReturnSuccess) || (iter == MACH_PORT_NULL)) {
if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("isBluetoothBuiltin IOServiceGetMatchingServices() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
}
*haveController = FALSE;
return FALSE;
hciController = IOIteratorNext(iter);
IOObjectRelease(iter);
if(hciController != MACH_PORT_NULL) {
+#if !TARGET_OS_SIMULATOR
CFNumberRef idVendor;
idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0);
CFRelease(idVendor);
}
+#endif // !TARGET_OS_SIMULATOR
IOObjectRelease(hciController);
}
io_registry_entry_t bus,
CFDictionaryRef bus_dict)
{
+#if TARGET_OS_SIMULATOR
+#pragma unused(interfacePrivate)
+#pragma unused(interface)
+#endif // TARGET_OS_SIMULATOR
+#pragma unused(interface_dict)
+#pragma unused(controller)
+#pragma unused(controller_dict)
+#pragma unused(bus)
+#pragma unused(bus_dict)
+#if !TARGET_OS_SIMULATOR
// capture USB info
- interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
- kIOServicePlane,
- CFSTR(kUSBProductString),
- NULL,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
- interfacePrivate->usb.vid = IORegistryEntrySearchCFProperty(interface,
- kIOServicePlane,
- CFSTR(kUSBVendorID),
- NULL,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
- interfacePrivate->usb.pid = IORegistryEntrySearchCFProperty(interface,
- kIOServicePlane,
- CFSTR(kUSBProductID),
- NULL,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (interfacePrivate->usb.name == NULL) {
+ interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ CFSTR(kUSBProductString),
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ }
+ if (interfacePrivate->usb.vid == NULL) {
+ interfacePrivate->usb.vid = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ CFSTR(kUSBVendorID),
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ }
+ if (interfacePrivate->usb.pid == NULL) {
+ interfacePrivate->usb.pid = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ CFSTR(kUSBProductID),
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ }
+#endif // !TARGET_OS_SIMULATOR
return;
}
interfacePrivate->name = CFRetain(productName);
if (interfacePrivate->localized_name != NULL) {
CFRelease(interfacePrivate->localized_name);
+ interfacePrivate->localized_name = NULL;
+ }
+ if (bundle != NULL) {
+ interfacePrivate->localized_name = copy_interface_string(bundle, productName, TRUE);
}
- interfacePrivate->localized_name = copy_interface_string(bundle, productName, TRUE);
updated = TRUE;
}
CFNumberGetValue(num, kCFNumberIntType, &ift)) {
interfacePrivate->type = CFRetain(num);
} else {
- SCLog(TRUE, LOG_DEBUG, CFSTR("processNetworkInterface() failed, no interface type"));
+ SC_log(LOG_INFO, "no interface type: %@", interface_dict);
return FALSE;
}
case IFT_ETHER :
// Type, Hardware
- if ((IOObjectConformsTo(controller, "IO80211Controller")) ||
- (IOObjectConformsTo(controller, "AirPortPCI" )) ||
- (IOObjectConformsTo(controller, "AirPortDriver" ))) {
+ if (IOObjectConformsTo(controller, "IO80211Controller") ||
+ IOObjectConformsTo(controller, "AirPortPCI" ) ||
+ IOObjectConformsTo(controller, "AirPortDriver" )) {
interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->sort_order = kSortAirPort;
+ } else if (IOObjectConformsTo(controller, "AppleThunderboltIPPort")) {
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+ interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
+ interfacePrivate->sort_order = kSortThunderbolt;
} else if (IOObjectConformsTo(controller, "IOBluetoothBNEPDriver")) {
interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
kIORegistryIterateRecursively | kIORegistryIterateParents);
if (val != NULL) {
if (isA_CFString(val)) {
- if (CFEqual(val, CFSTR("Bluetooth PAN"))) {
+ if (CFEqual(val, CFSTR(BT_PAN_NAME))) {
interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet;
interfacePrivate->sort_order = kSortBluetoothPAN_GN;
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) {
// location
interfacePrivate->location = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOLocation));
+ if ((interfacePrivate->location != NULL) &&
+ (CFStringGetLength(interfacePrivate->location) == 0)) {
+ CFRelease(interfacePrivate->location);
+ interfacePrivate->location = NULL;
+ }
// VLAN support
num = CFDictionaryGetValue(controller_dict, CFSTR(kIOFeatures));
// localized name
if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
interfacePrivate->localized_key = CFSTR("airport");
+ } else if (interfacePrivate->sort_order == kSortThunderbolt) {
+ if ((interfacePrivate->location == NULL) ||
+ (CFStringGetLength(interfacePrivate->location) == 0)) {
+ interfacePrivate->localized_key = CFSTR("thunderbolt");
+ } else {
+ interfacePrivate->localized_key = CFSTR("multithunderbolt");
+ interfacePrivate->localized_arg1 = CFRetain(interfacePrivate->location);
+ }
} else if (interfacePrivate->sort_order == kSortBluetoothPAN_GN) {
interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
} else if (interfacePrivate->sort_order == kSortBluetoothPAN_NAP) {
}
}
}
- } else if (CFEqual(provider, CFSTR("IOUSBDevice")) ||
- CFEqual(provider, CFSTR("IOUSBInterface"))) {
- // get USB info (if available)
- processUSBInterface(interfacePrivate,
- interface,
- interface_dict,
- controller,
- controller_dict,
- bus,
- bus_dict);
+ } else {
+ io_registry_entry_t node = interface;
+
+ while (provider != NULL) {
+#if !TARGET_OS_SIMULATOR
+ if (CFEqual(provider, CFSTR(kIOUSBDeviceClassName)) ||
+ CFEqual(provider, CFSTR(kIOUSBInterfaceClassName)) ||
+ CFEqual(provider, CFSTR(kIOUSBHostInterfaceClassName))) {
+ // get USB info (if available)
+ processUSBInterface(interfacePrivate,
+ interface,
+ interface_dict,
+ controller,
+ controller_dict,
+ bus,
+ bus_dict);
+
+ // set interface "name"
+ if (!update_interface_name(interfacePrivate, interface, TRUE)) {
+ interfacePrivate->localized_key = CFSTR("usb-ether");
+ interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict);
+ }
+ break;
+ }
+#endif // !TARGET_OS_SIMULATOR
+
+ if (node == interface) {
+ node = controller;
+ } else if (node == controller ) {
+ node = bus;
+ } else {
+ break;
+ }
+
+ CFRelease(provider);
+ provider = IORegistryEntrySearchCFProperty(node,
+ kIOServicePlane,
+ CFSTR(kIOProviderClassKey),
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ }
- // set interface "name"
- if (!update_interface_name(interfacePrivate, interface, TRUE)) {
- interfacePrivate->localized_key = CFSTR("usb-ether");
- interfacePrivate->localized_arg1 = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+ if (interfacePrivate->localized_key == NULL) {
+ update_interface_name(interfacePrivate, interface, FALSE);
}
}
- CFRelease(provider);
+
+ if (provider != NULL) CFRelease(provider);
}
if (interfacePrivate->localized_key == NULL) {
// if no provider, not a PCI device, or no slot information
interfacePrivate->localized_key = CFSTR("generic-ether");
- interfacePrivate->localized_arg1 = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+ interfacePrivate->localized_arg1 = IODictionaryCopyBSDName(interface_dict);
}
}
break;
default :
- SCLog(TRUE, LOG_DEBUG, CFSTR("processNetworkInterface() failed, unknown interface type = %d"), ift);
+ SC_log(LOG_INFO, "unknown interface type = %d", ift);
return FALSE;
}
// Device
- interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOBSDNameKey));
+ interfacePrivate->entity_device = IODictionaryCopyBSDName(interface_dict);
// Hardware (MAC) address
data = CFDictionaryGetValue(controller_dict, CFSTR(kIOMACAddress));
interfacePrivate->address = CFRetain(data);
}
+ // interface prefix
+ str = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceNamePrefix));
+ if (isA_CFString(str)) {
+ interfacePrivate->prefix = CFRetain(str);
+ }
+
// interface unit
num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceUnit));
if (isA_CFNumber(num) &&
static Boolean
is_valid_connection_script(CFStringRef script)
{
- char ccl[MAXPATHLEN];
- char path[MAXPATHLEN];
- NSSearchPathEnumerationState state;
+ char ccl[MAXPATHLEN];
+ char path[MAXPATHLEN];
+ sysdir_search_path_enumeration_state state;
(void) _SC_cfstring_to_cstring(script,
ccl,
sizeof(ccl),
kCFStringEncodingUTF8);
- state = NSStartSearchPathEnumeration(NSLibraryDirectory,
- NSLocalDomainMask|NSSystemDomainMask);
- while ((state = NSGetNextSearchPathEnumeration(state, path))) {
+ state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY,
+ SYSDIR_DOMAIN_MASK_LOCAL|SYSDIR_DOMAIN_MASK_SYSTEM);
+ while ((state = sysdir_get_next_search_path_enumeration(state, path))) {
size_t n;
struct stat statBuf;
goto bundle;
}
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("processSerialInterface stat() failed: %s"),
- strerror(errno));
+ SC_log(LOG_INFO, "stat() failed: %s", strerror(errno));
continue;
}
if (S_ISREG(statBuf.st_mode)) {
continue;
}
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("processSerialInterface stat() failed: %s"),
- strerror(errno));
+ SC_log(LOG_INFO, "stat() failed: %s", strerror(errno));
continue;
}
}
Boolean ok = FALSE;
CFTypeRef val;
- // check if hidden
- val = IORegistryEntrySearchCFProperty(interface,
- kIOServicePlane,
- kSCNetworkInterfaceHiddenPortKey,
- NULL,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
- if (val != NULL) {
- CFRelease(val);
- return FALSE; // if this interface should not be exposed
- }
-
// check if initializing
val = IORegistryEntrySearchCFProperty(interface,
kIOServicePlane,
// Modem
interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem;
interfacePrivate->sort_order = kSortModem;
-
- // V.92 support
- val = IORegistryEntrySearchCFProperty(interface,
- kIOServicePlane,
- CFSTR(kIODeviceSupportsHoldKey),
- NULL,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
- if (val != NULL) {
- uint32_t v92;
-
- if (isA_CFNumber(val) &&
- CFNumberGetValue(val, kCFNumberSInt32Type, &v92)) {
- interfacePrivate->modemIsV92 = (v92 == 1);
- }
- CFRelease(val);
- }
}
// Entity (Type)
return str;
}
+static CFMutableDictionaryRef
+copyIORegistryProperties(io_registry_entry_t reg_ent, const CFStringRef *reg_keys, CFIndex numKeys)
+{
+ CFIndex idx = 0;
+ CFMutableDictionaryRef reg_dict = NULL;
+ CFTypeRef value = NULL;
+
+ reg_dict = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks ,
+ &kCFTypeDictionaryValueCallBacks);
+
+ for (; idx < numKeys; idx++) {
+ value = IORegistryEntryCreateCFProperty(reg_ent, reg_keys[idx], NULL, 0);
+ if (value != NULL) {
+ CFDictionaryAddValue(reg_dict, reg_keys[idx], value);
+ CFRelease(value);
+ }
+ }
+
+ return reg_dict;
+}
static SCNetworkInterfaceRef
-createInterface(io_registry_entry_t interface, processInterface func)
+createInterface(io_registry_entry_t interface, processInterface func,
+ CFStringRef hidden_key)
{
io_registry_entry_t bus = MACH_PORT_NULL;
CFMutableDictionaryRef bus_dict = NULL;
kern_return_t kr;
CFTypeRef val;
- kr = IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
- if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
- goto done;
+ // Keys of interest
+ const CFStringRef interface_dict_keys[] = {
+ CFSTR(kIOInterfaceType),
+ CFSTR(kIOBuiltin),
+ CFSTR(kIOBSDNameKey),
+ CFSTR(kIOPrimaryInterface),
+ CFSTR(kIOInterfaceNamePrefix),
+ CFSTR(kIOInterfaceUnit),
+ CFSTR(kIOTTYDeviceKey),
+ CFSTR(kIOTTYBaseNameKey),
+ CFSTR(kIOSerialBSDTypeKey),
+ CFSTR(kIOLocation)
+ };
+
+ const CFStringRef controller_dict_keys[] = {
+ CFSTR(kIOFeatures),
+ CFSTR(kIOMACAddress)
+ };
+
+ const CFStringRef bus_dict_keys[] = {
+ CFSTR("name")
+ };
+
+ if (hidden_key != NULL) {
+ // check if hidden
+ val = IORegistryEntrySearchCFProperty(interface,
+ kIOServicePlane,
+ hidden_key,
+ NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (val != NULL) {
+ CFRelease(val);
+ goto done; // if this interface should not be exposed
+ }
}
- /* get the controller node */
+ interface_dict = copyIORegistryProperties(interface,
+ interface_dict_keys,
+ sizeof(interface_dict_keys)/sizeof(interface_dict_keys[0]));
+
+ // get the controller node
kr = IORegistryEntryGetParentEntry(interface, kIOServicePlane, &controller);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
+ if (kr != kIOReturnSuccess) {
+ SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr);
goto done;
}
- /* get the dictionary associated with the node */
- kr = IORegistryEntryCreateCFProperties(controller, &controller_dict, NULL, kNilOptions);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
- goto done;
- }
+ controller_dict = copyIORegistryProperties(controller,
+ controller_dict_keys,
+ sizeof(controller_dict_keys)/sizeof(controller_dict_keys[0]));
- /* get the bus node */
+ // get the bus node
kr = IORegistryEntryGetParentEntry(controller, kIOServicePlane, &bus);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetParentEntry() failed, kr = 0x%x"), kr);
+ if (kr != kIOReturnSuccess) {
+ SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr);
goto done;
}
- /* get the dictionary associated with the node */
- kr = IORegistryEntryCreateCFProperties(bus, &bus_dict, NULL, kNilOptions);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
- goto done;
- }
+ bus_dict = copyIORegistryProperties(bus,
+ bus_dict_keys,
+ sizeof(bus_dict_keys)/sizeof(bus_dict_keys[0]));
- /* get the registry entry ID */
+ // get the registry entry ID
kr = IORegistryEntryGetRegistryEntryID(interface, &entryID);
- if (kr != KERN_SUCCESS) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x"), kr);
+ if (kr != kIOReturnSuccess) {
+ SC_log(LOG_INFO, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr);
goto done;
}
interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
+ assert(interfacePrivate != NULL);
interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
interfacePrivate->entryID = entryID;
}
if ((*func)(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict)) {
- /* get user-notification / auto-configuration preference */
+ // get user-notification / auto-configuration preference
val = IORegistryEntrySearchCFProperty(interface,
kIOServicePlane,
kSCNetworkInterfaceConfigurationActionKey,
CFRelease(val);
}
- /* get HiddenConfiguration preference */
+ // get HiddenConfiguration preference
val = IORegistryEntrySearchCFProperty(interface,
kIOServicePlane,
kSCNetworkInterfaceHiddenConfigurationKey,
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;
static CF_RETURNS_RETAINED CFArrayRef
-findMatchingInterfaces(CFDictionaryRef matching, processInterface func)
+findMatchingInterfaces(CFDictionaryRef matching,
+ processInterface func,
+ CFStringRef hidden_key,
+ Boolean keep_pre_configured)
{
CFMutableArrayRef interfaces;
io_registry_entry_t interface;
kr = IOServiceGetMatchingServices(masterPort, matching, &iterator);
if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("findMatchingInterfaces IOServiceGetMatchingServices() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
return NULL;
}
while ((interface = IOIteratorNext(iterator)) != MACH_PORT_NULL) {
SCNetworkInterfaceRef match;
- match = createInterface(interface, func);
+ match = createInterface(interface, func, hidden_key);
if (match != NULL) {
- CFArrayAppendValue(interfaces, match);
+ if (keep_pre_configured || !_SCNetworkInterfaceIsApplePreconfigured(match)) {
+ CFArrayAppendValue(interfaces, match);
+ }
CFRelease(match);
}
static CFIndex
findConfiguration(CFStringRef interface_type)
{
- CFIndex i;
-
- for (i = 0; i < sizeof(configurations)/sizeof(configurations[0]); i++) {
+ for (size_t i = 0; i < sizeof(configurations)/sizeof(configurations[0]); i++) {
if (CFEqual(interface_type, *configurations[i].interface_type)) {
return i;
}
/*
* ???
- * Do we match specific/known extended configuration types (e.g. EAPOL)
- * and ensure that any non-standard extended configuration types be of
- * the form com.myCompany.myType?
+ * Should we check/match and specifically allow known extended
+ * configuration types (e.g. EAPOL)?
+ *
+ * Should we check/match and specifically block known internal
+ * configuration types (e.g. QoSMarking)?
+ *
+ * Lastly, should we ensure that any non-standard extended configuration
+ * types be of the form com.myCompany.myType?
* ???
*/
static void
__addExtendedConfigurationType(const void *key, const void *value, void *context)
{
+#pragma unused(value)
CFStringRef extendedType = (CFStringRef)key;
extendedConfigurationRef myContextRef = (extendedConfigurationRef)context;
}
+static CFIndex
+findPerInterfaceConfiguration(SCNetworkInterfaceRef interface)
+{
+ CFIndex interfaceIndex;
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ interfaceIndex = findConfiguration(interfacePrivate->interface_type);
+ if (interfaceIndex == kCFNotFound) {
+ // if per-service (not per interface) configuration
+ return kCFNotFound;
+ }
+
+ if (!configurations[interfaceIndex].per_interface_config) {
+ // if per-interface configuration not allowed
+ return kCFNotFound;
+ }
+
+ return interfaceIndex;
+}
+
+
static CF_RETURNS_RETAINED CFArrayRef
extendedConfigurationTypes(SCNetworkInterfaceRef interface)
{
goto done;
}
- interfaceIndex = findConfiguration(interfacePrivate->interface_type);
+ interfaceIndex = findPerInterfaceConfiguration(interface);
if (interfaceIndex == kCFNotFound) {
- // we don't allow per-service extended configurations
- goto done;
- }
-
- if (!configurations[interfaceIndex].per_interface_config) {
- // known interface type but we still don't allow
- // per-service extended configurations
+ // if no per-interface configuration
goto done;
}
return myContext.types;
}
+static CFArrayRef
+stringCreateArray(CFStringRef str)
+{
+ return (CFArrayCreate(NULL, (const void **)&str, 1, &kCFTypeArrayCallBacks));
+}
static CFArrayRef
-copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate,
- CFStringRef extendedType)
+copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate,
+ CFStringRef extendedType)
{
- CFMutableArrayRef array;
+ CFMutableArrayRef array = NULL;
CFIndex i;
- CFIndex interfaceIndex;
CFIndex n;
CFStringRef path;
SCNetworkServiceRef service;
CFArrayRef sets;
- array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
- interfaceIndex = findConfiguration(interfacePrivate->interface_type);
- if (interfaceIndex == kCFNotFound) {
- // unknown interface type, use per-service configuration preferences
- path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator
- interfacePrivate->serviceID, // service
- extendedType); // entity
- CFArrayAppendValue(array, path);
- CFRelease(path);
- return array;
- }
-
- if (!configurations[interfaceIndex].per_interface_config) {
- // known interface type, per-service configuration preferences
- path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator
- interfacePrivate->serviceID, // service
- extendedType); // entity
- CFArrayAppendValue(array, path);
- CFRelease(path);
- return array;
- }
-
// known interface type, per-interface configuration preferences
//
// 1. look for all sets which contain the associated service
SCNetworkSetGetSetID(set), // set
interfacePrivate->entity_device, // service
extendedType); // entity
+ if (array == NULL) {
+ array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
CFArrayAppendValue(array, path);
CFRelease(path);
}
CFRelease(services);
}
- if (CFArrayGetCount(array) == 0) {
- CFRelease(array);
- array = NULL;
- }
-
CFRelease(service);
if (sets != NULL) CFRelease(sets);
return array;
+
+}
+
+static CFArrayRef
+copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate,
+ CFStringRef extendedType)
+{
+ CFArrayRef array = NULL;
+ CFIndex interfaceIndex;
+ CFStringRef path;
+
+ interfaceIndex = findConfiguration(interfacePrivate->interface_type);
+ if (interfaceIndex == kCFNotFound) {
+ // unknown interface type, use per-service configuration preferences
+ path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator
+ interfacePrivate->serviceID, // service
+ extendedType); // entity
+ array = stringCreateArray(path);
+ CFRelease(path);
+ }
+
+ else if (!configurations[interfaceIndex].per_interface_config) {
+ // known interface type, per-service configuration preferences
+ path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator
+ interfacePrivate->serviceID, // service
+ extendedType); // entity
+ array = stringCreateArray(path);
+ CFRelease(path);
+ }
+
+ else if (interfacePrivate->serviceID != NULL) {
+ array = copyPerInterfaceConfigurationPaths(interfacePrivate, extendedType);
+ }
+
+ return (array);
}
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) {
kSCPropUserDefinedName,
SCNetworkInterfaceGetLocalizedDisplayName(interface));
- // note that this is a V.92 capable modem
- if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeModem) &&
- interfacePrivate->modemIsV92) {
- int one = 1;
- CFNumberRef num;
-
- num = CFNumberCreate(NULL, kCFNumberIntType, &one);
- CFDictionarySetValue(entity,
- kSCPropNetInterfaceSupportsModemOnHold,
- num);
- CFRelease(num);
- }
-
return entity;
}
}
-SCNetworkInterfaceRef
-_SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator,
- CFStringRef bsdName,
- UInt32 flags)
-{
- CFMutableDictionaryRef entity;
- SCNetworkInterfaceRef interface;
+#define N_QUICK 32
- entity = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, bsdName);
+
+static CFMutableDictionaryRef
+copy_ppp_entity(CFStringRef bsdName)
+{
+ CFMutableDictionaryRef entity = NULL;
+ CFStringRef pattern;
+ CFMutableArrayRef patterns;
+ CFDictionaryRef dict;
+
+ patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetPPP);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetInterface);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ dict = SCDynamicStoreCopyMultiple(NULL, NULL, patterns);
+ CFRelease(patterns);
+ if (dict != NULL) {
+ CFIndex i;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex n;
+ const void * vals_q[N_QUICK];
+ const void ** vals = vals_q;
+
+ n = CFDictionaryGetCount(dict);
+ if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ vals = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ }
+ CFDictionaryGetKeysAndValues(dict, keys, vals);
+ for (i = 0; i < n; i++) {
+ CFArrayRef components;
+ CFStringRef interfaceKey;
+ CFDictionaryRef interfaceVal;
+ CFStringRef ifName;
+ CFStringRef pppKey = (CFStringRef)keys[i];
+ CFDictionaryRef pppVal = (CFDictionaryRef)vals[i];
+ CFStringRef serviceID;
+
+ if (!CFStringHasSuffix(pppKey, kSCEntNetPPP) ||
+ !CFDictionaryGetValueIfPresent(pppVal, kSCPropInterfaceName, (const void **)&ifName) ||
+ !CFEqual(bsdName, ifName)) {
+ // if not matching PPP interface
+ continue;
+ }
+
+ components = CFStringCreateArrayBySeparatingStrings(NULL, pppKey, CFSTR("/"));
+ serviceID = CFArrayGetValueAtIndex(components, 3);
+ interfaceKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, serviceID, kSCEntNetInterface);
+ interfaceVal = CFDictionaryGetValue(dict, interfaceKey);
+ CFRelease(interfaceKey);
+ CFRelease(components);
+ if (interfaceVal != NULL) {
+ entity = CFDictionaryCreateMutableCopy(NULL, 0, interfaceVal);
+ break;
+ }
+ }
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, vals);
+ }
+
+ CFRelease(dict);
+ }
+
+ return entity;
+}
+
+
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator,
+ CFStringRef bsdName,
+ UInt32 flags)
+{
+#pragma unused(allocator)
+ CFMutableDictionaryRef entity = NULL;
+ struct ifreq ifr;
+ SCNetworkInterfaceRef interface;
+
+ memset(&ifr, 0, sizeof(ifr));
+ if (_SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) {
+ int s;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s != -1) {
+ if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
+ ifr.ifr_flags = 0;
+ }
+ close(s);
+ }
+
+ if ((ifr.ifr_flags & IFF_POINTOPOINT) != 0) {
+ // if PPP
+ entity = copy_ppp_entity(bsdName);
+ }
+ }
+
+ if (entity == NULL) {
+ entity = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, bsdName);
+ }
#if !TARGET_OS_IPHONE
if ((flags & kIncludeBondInterfaces) == 0) {
}
+static CFStringRef
+_SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName)
+{
+ CFMutableStringRef interfacePrefix = NULL;
+ UniChar lastChar;
+ CFIndex length = 0;
+
+ if (isA_CFString(bsdName) == NULL) {
+ SC_log(LOG_DEBUG, "no BSD name");
+ goto done;
+ }
+
+ interfacePrefix = CFStringCreateMutableCopy(NULL, 0, bsdName);
+ length = CFStringGetLength(interfacePrefix);
+
+ while (length > 0) {
+ lastChar = CFStringGetCharacterAtIndex(interfacePrefix, length - 1);
+ if (lastChar >= '0' && lastChar <= '9') {
+ CFStringDelete(interfacePrefix,
+ CFRangeMake(length-1, 1));
+ }
+ else {
+ break;
+ }
+ length = CFStringGetLength(interfacePrefix);
+ }
+done:
+ return interfacePrefix;
+}
+
+
+static void
+__SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface,
+ CFStringRef prefix);
+
+
+static Boolean
+__SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface, CFStringRef currentBSDName, CFStringRef newBSDName)
+{
+ Boolean success = FALSE;
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if (isA_SCNetworkInterface(interface) == NULL) {
+ SC_log(LOG_INFO, "No interface");
+ goto done;
+ }
+
+ if (CFEqual(currentBSDName, newBSDName)) {
+ // if no change
+ goto done;
+ }
+
+ if (interfacePrivate->entity_device != NULL) {
+ CFRelease(interfacePrivate->entity_device);
+ }
+ interfacePrivate->entity_device = CFRetain(newBSDName);
+ success = TRUE;
+done:
+ return success;
+}
+
+
+static Boolean
+__SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface)
+{
+ Boolean success = FALSE;
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+ CFStringRef oldPath = NULL;
+ CFStringRef newPath = NULL;
+
+ // Using the BSD Name update the path
+ oldPath = interfacePrivate->path;
+ if (isA_CFString(oldPath) == NULL) {
+ goto done;
+ }
+ newPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Migrated_From: %@"), oldPath);
+ if (interfacePrivate->path != NULL) {
+ CFRelease(interfacePrivate->path);
+ }
+ interfacePrivate->path = CFRetain(newPath);
+ success = TRUE;
+
+done:
+ if (newPath != NULL) {
+ CFRelease(newPath);
+ }
+ return success;
+}
+
+
+static void
+__SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface,
+ CFStringRef prefix)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate;
+
+ if (isA_CFString(prefix) == NULL) {
+ return;
+ }
+
+ interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
+
+ CFRetain(prefix);
+
+ if (interfacePrivate->prefix != NULL) {
+ CFRelease(interfacePrivate->prefix);
+ }
+
+ interfacePrivate->prefix = prefix;
+ return;
+}
+
+
+__private_extern__
+void
+__SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface,
+ CFNumberRef unit)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate;
+ CFStringRef newBSDName = NULL;
+ CFStringRef oldBSDName = NULL;
+
+ if (isA_CFNumber(unit) == NULL) {
+ return;
+ }
+ interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
+
+ oldBSDName = SCNetworkInterfaceGetBSDName(interface);
+
+ if (interfacePrivate->prefix == NULL) {
+ if (isA_CFString(interfacePrivate->entity_device) != NULL) {
+ CFStringRef interfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate->entity_device);
+ if (interfaceNamePrefix == NULL) {
+ SC_log(LOG_INFO, "interfaceNamePrefix is NULL");
+ }
+ else {
+ __SCNetworkInterfaceSetIOInterfacePrefix(interface, interfaceNamePrefix);
+ CFRelease(interfaceNamePrefix);
+ }
+ }
+ }
+
+ if (interfacePrivate->prefix != NULL) {
+ newBSDName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), interfacePrivate->prefix, unit);
+ }
+
+ // Update the BSD Name
+ if ((newBSDName == NULL) ||
+ (!__SCNetworkInterfaceUpdateBSDName(interface, oldBSDName, newBSDName))) {
+ SC_log(LOG_INFO, "BSD name update failed");
+ }
+
+ // Update the path
+ if (!__SCNetworkInterfaceUpdateIOPath(interface)) {
+ SC_log(LOG_INFO, "IOPath update failed");
+ }
+
+ CFRetain(unit);
+ if (interfacePrivate->unit != NULL) {
+ CFRelease(interfacePrivate->unit);
+ }
+ interfacePrivate->unit = unit;
+
+
+ if (newBSDName != NULL) {
+ CFRelease(newBSDName);
+ }
+ return;
+}
+
+
+__private_extern__
+CFDictionaryRef
+__SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
+{
+ CFMutableDictionaryRef interface_entity = NULL;
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+ CFBooleanRef active = NULL;
+ CFStringRef bsdName = NULL;
+ CFBooleanRef builtin = NULL;
+ CFStringRef interfaceNamePrefix = NULL;
+ CFNumberRef interfaceType = NULL;
+ CFNumberRef interfaceUnit = NULL;
+ CFDataRef macAddress = NULL;
+ CFStringRef pathMatch = NULL;
+ CFDictionaryRef info = NULL;
+ CFStringRef type = NULL;
+
+ if (interfacePrivate->active) {
+ active = kCFBooleanTrue;
+ }
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (!isA_CFString(bsdName)) {
+ goto done;
+ }
+
+ builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse;
+ interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
+ if (!isA_CFString(interfaceNamePrefix)) {
+ goto done;
+ }
+
+ interfaceType = _SCNetworkInterfaceGetIOInterfaceType(interface);
+ if (!isA_CFNumber(interfaceType)) {
+ goto done;
+ }
+
+ interfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
+ if (!isA_CFNumber(interfaceUnit)) {
+ goto done;
+ }
+
+ macAddress = _SCNetworkInterfaceGetHardwareAddress(interface);
+ if (!isA_CFData(macAddress)) {
+ goto done;
+ }
+
+ pathMatch = _SCNetworkInterfaceGetIOPath(interface);
+ if (!isA_CFString(pathMatch)) {
+ goto done;
+ }
+
+ info = _SCNetworkInterfaceCopyInterfaceInfo(interface);
+ if (!isA_CFDictionary(info)) {
+ goto done;
+ }
+
+ type = SCNetworkInterfaceGetInterfaceType(interface);
+ if (!isA_CFString(type)) {
+ goto done;
+ }
+
+ interface_entity = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ if (isA_CFBoolean(active) != NULL) {
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), active);
+ }
+
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName), bsdName);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin), builtin);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix), interfaceNamePrefix);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType), interfaceType);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit), interfaceUnit);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress), macAddress);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch), pathMatch);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo), info);
+ CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceType), type);
+done:
+ if (info != NULL) {
+ CFRelease(info);
+ }
+ return interface_entity;
+}
+
+
static void
__SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface,
SCNetworkServiceRef service)
}
-static Boolean
-_SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
+__private_extern__
+Boolean
+__SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
{
Boolean match;
CFStringRef str;
if (bundle == NULL) {
- // if no bundle
+ SC_log(LOG_NOTICE, "no bundle information to compare interface names");
return FALSE;
}
}
+#define kInterfaceTypeEthernetValue 6
+#define kInterfaceTypeFirewireValue 144
+
+
+static SCNetworkInterfaceRef
+__SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator,
+ CFDictionaryRef interface_entity)
+{
+#pragma unused(allocator)
+ SCNetworkInterfacePrivateRef interfacePrivate = NULL;
+ CFBooleanRef active = NULL;
+ CFStringRef bsdName = NULL;
+ CFBooleanRef ioBuiltin = NULL;
+ CFStringRef ioInterfaceNamePrefix = NULL;
+ CFNumberRef ioInterfaceType = NULL;
+ int ioInterfaceTypeNum;
+ CFNumberRef ioInterfaceUnit = NULL;
+ CFDataRef ioMACAddress = NULL;
+ CFStringRef ioPathMatch = NULL;
+ CFDictionaryRef SCNetworkInterfaceInfo = NULL;
+ CFStringRef userDefinedName = NULL;
+ CFStringRef usbProductName = NULL;
+ CFNumberRef idProduct = NULL;
+ CFNumberRef idVendor = NULL;
+ CFStringRef type = NULL;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+ if (isA_CFDictionary(interface_entity) == NULL) {
+ SC_log(LOG_INFO, "No interface entity");
+ goto done;
+ }
+ active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive));
+ if (isA_CFBoolean(active) == NULL) {
+ active = kCFBooleanFalse;
+ }
+ bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName));
+ if (isA_CFString(bsdName) == NULL) {
+ SC_log(LOG_INFO, "No BSD name");
+ goto done;
+ }
+ ioBuiltin = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOBuiltin));
+ if (isA_CFBoolean(ioBuiltin) == NULL) {
+ SC_log(LOG_INFO, "No IOBuiltin property");
+ goto done;
+ }
+ ioInterfaceNamePrefix = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix));
+ if (isA_CFString(ioInterfaceNamePrefix) == NULL) {
+ ioInterfaceNamePrefix = _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName);
+ if (ioInterfaceNamePrefix == NULL) {
+ SC_log(LOG_INFO, "No BSD interface name prefix");
+ goto done;
+ }
+ } else {
+ CFRetain(ioInterfaceNamePrefix);
+ }
+ ioInterfaceType = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceType));
+ if (isA_CFNumber(ioInterfaceType) == NULL) {
+ SC_log(LOG_INFO, "No IOInterfaceType");
+ goto done;
+ }
+ if (!CFNumberGetValue(ioInterfaceType, kCFNumberIntType, &ioInterfaceTypeNum)) {
+ SC_log(LOG_NOTICE, "Count not extract value from ioInterfaceType");
+ }
+ ioInterfaceUnit = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOInterfaceUnit));
+ if (isA_CFNumber(ioInterfaceUnit) == NULL) {
+ SC_log(LOG_INFO, "No IOInterfaceUnit");
+
+ goto done;
+ }
+ ioMACAddress = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOMACAddress));
+ if (isA_CFData(ioMACAddress) == NULL) {
+ SC_log(LOG_INFO, "No IOMACAddress");
+ goto done;
+ }
+ ioPathMatch = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceIOPathMatch));
+ if (isA_CFString(ioPathMatch) == NULL) {
+ SC_log(LOG_INFO, "No IOPathMatch");
+ goto done;
+ } else {
+ // Check if Path contains the BSD Name in the end
+ }
+ SCNetworkInterfaceInfo = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceInfo));
+ if (isA_CFDictionary(SCNetworkInterfaceInfo) == NULL) {
+ SC_log(LOG_INFO, "No SCNetworkInterfaceInfo");
+ goto done;
+ }
+ userDefinedName = CFDictionaryGetValue(SCNetworkInterfaceInfo, kSCPropUserDefinedName);
+#if !TARGET_OS_SIMULATOR
+ usbProductName = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductString));
+ idProduct = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBProductID));
+ idVendor = CFDictionaryGetValue(SCNetworkInterfaceInfo, CFSTR(kUSBVendorID));
+#endif // !TARGET_OS_SIMULATOR
+
+ type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
+ if (isA_CFString(type) == NULL) {
+ SC_log(LOG_INFO, "No SCNetworkInterfaceType");
+ goto done;
+ }
+
+ interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
+ interfacePrivate->active = CFBooleanGetValue(active);
+ interfacePrivate->entity_device = CFRetain(bsdName);
+ interfacePrivate->builtin = CFBooleanGetValue(ioBuiltin);
+ interfacePrivate->prefix = CFRetain(ioInterfaceNamePrefix);
+ interfacePrivate->type = CFRetain(ioInterfaceType);
+ interfacePrivate->unit = CFRetain(ioInterfaceUnit);
+ interfacePrivate->address = CFRetain(ioMACAddress);
+ interfacePrivate->path = CFRetain(ioPathMatch);
+ interfacePrivate->name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
+ interfacePrivate->localized_name = ((userDefinedName != NULL) ? CFRetain(userDefinedName) : NULL);
+ interfacePrivate->usb.name = ((usbProductName != NULL) ? CFRetain(usbProductName) : NULL);
+ interfacePrivate->usb.pid = ((idProduct != NULL) ? CFRetain(idProduct) : NULL);
+ interfacePrivate->usb.vid = ((idVendor != NULL) ? CFRetain(idVendor) : NULL);
+
+ // Handling interface types to be seen in NetworkInterfaces.plist
+ CFIndex interfaceIndex;
+
+ interfaceIndex = findConfiguration(type);
+ if (interfaceIndex != kCFNotFound) {
+ interfacePrivate->interface_type = *configurations[interfaceIndex].interface_type;
+ } else {
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+ }
+
+ // Extracting entity type from value of interface type
+ if (ioInterfaceTypeNum == kInterfaceTypeEthernetValue) {
+ interfacePrivate->entity_type = kSCValNetInterfaceTypeEthernet; // kSCNetworkInterfaceTypeEthernet;
+ } else if (ioInterfaceTypeNum == kInterfaceTypeFirewireValue) {
+ interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
+ }
+done:
+ if (ioInterfaceNamePrefix != NULL) {
+ CFRelease(ioInterfaceNamePrefix);
+ }
+
+ return (SCNetworkInterfaceRef)interfacePrivate;
+}
+
+
+__private_extern__
+void
+_SCNetworkInterfaceCacheOpen(void)
+{
+ if (!__SCNetworkInterfaceCacheIsOpen()) {
+ S_interface_cache = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): open", S_interface_cache);
+ }
+}
+
+
+__private_extern__
+void
+_SCNetworkInterfaceCacheClose(void)
+{
+ if (__SCNetworkInterfaceCacheIsOpen()) {
+ SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): close", S_interface_cache);
+ CFRelease(S_interface_cache);
+ S_interface_cache = NULL;
+ }
+}
+
+
+static void
+__SCNetworkInterfaceCacheAdd(CFStringRef bsdName, CFArrayRef matchingInterfaces)
+{
+ if (__SCNetworkInterfaceCacheIsOpen() &&
+ bsdName != NULL &&
+ matchingInterfaces != NULL) {
+ SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): add %@", S_interface_cache, bsdName);
+ CFDictionaryAddValue(S_interface_cache, bsdName, matchingInterfaces);
+ }
+}
+
+
+static inline Boolean
+__SCNetworkInterfaceCacheIsOpen(void)
+{
+ return (S_interface_cache != NULL);
+}
+
+
+static CFArrayRef
+__SCNetworkInterfaceCacheCopy(CFStringRef bsdName)
+{
+ if (__SCNetworkInterfaceCacheIsOpen() &&
+ bsdName != NULL) {
+ CFArrayRef matchingInterfaces = CFDictionaryGetValue(S_interface_cache, bsdName);
+ if (matchingInterfaces) {
+ CFRetain(matchingInterfaces);
+ SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache, bsdName);
+ } else {
+ SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache, bsdName);
+ }
+
+ return matchingInterfaces;
+ }
+
+ return NULL;
+}
+
+
SCNetworkInterfaceRef
-_SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator,
- CFDictionaryRef interface_entity,
- SCNetworkServiceRef service)
+_SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator,
+ CFDictionaryRef interface_entity,
+ SCNetworkServiceRef service)
{
+#pragma unused(allocator)
SCNetworkInterfacePrivateRef interfacePrivate = NULL;
CFStringRef ifDevice;
CFStringRef ifName = NULL;
CFStringRef ifType;
CFStringRef ifUnique;
CFArrayRef matching_interfaces = NULL;
+ SCPreferencesRef servicePref = NULL;
+ Boolean useSystemInterfaces = TRUE;
/* initialize runtime (and kSCNetworkInterfaceIPv4) */
pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+ if (service != NULL) {
+ servicePref = ((SCNetworkServicePrivateRef)service)->prefs;
+ useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePref)) &&
+ (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref)));
+ }
+
ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
if (ifType == NULL) {
/*
* assumption that this is an "Ethernet" interface. If a
* real interface exists with the provided interface name
* then the actual type will be set accordingly. If not, we'll
- * end up crafting an "Ethernet" SCNetworkInterface which
+ * end up crafting an "Ethernet" SCNetworkInterface that
* will keep the rest of the configuration APIs happy.
*/
ifType = kSCValNetInterfaceTypeEthernet;
interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL);
goto done;
}
+ if (useSystemInterfaces) {
+ // Check to see if we already have the info in the cache
+ matching_interfaces = __SCNetworkInterfaceCacheCopy(ifDevice);
+ if (matching_interfaces == NULL) {
+ if (_SC_cfstring_to_cstring(ifDevice, bsdName, sizeof(bsdName), kCFStringEncodingASCII) == NULL) {
+ goto done;
+ }
- if (_SC_cfstring_to_cstring(ifDevice, bsdName, sizeof(bsdName), kCFStringEncodingASCII) == NULL) {
- goto done;
- }
+ matching = IOBSDNameMatching(masterPort, 0, bsdName);
+ if (matching == NULL) {
+ goto done;
+ }
+ matching_interfaces = findMatchingInterfaces(matching,
+ processNetworkInterface,
+ kSCNetworkInterfaceHiddenInterfaceKey,
+ TRUE);
- matching = IOBSDNameMatching(masterPort, 0, bsdName);
- if (matching == NULL) {
- goto done;
+ __SCNetworkInterfaceCacheAdd(ifDevice, matching_interfaces);
+ CFRelease(matching);
+ }
}
- matching_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
- CFRelease(matching);
} else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) {
CFDictionaryRef matching;
return NULL;
}
- match_keys[0] = CFSTR(kIOProviderClassKey);
- match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
-
- match_keys[1] = CFSTR(kIOTTYBaseNameKey);
- match_vals[1] = ifDevice;
-
- matching = CFDictionaryCreate(NULL,
- (const void **)match_keys,
- (const void **)match_vals,
- sizeof(match_keys)/sizeof(match_keys[0]),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- matching_interfaces = findMatchingInterfaces(matching, processSerialInterface);
- CFRelease(matching);
-
+ if (useSystemInterfaces) {
+ match_keys[0] = CFSTR(kIOProviderClassKey);
+ match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+
+ match_keys[1] = CFSTR(kIOTTYBaseNameKey);
+ match_vals[1] = ifDevice;
+
+ matching = CFDictionaryCreate(NULL,
+ (const void **)match_keys,
+ (const void **)match_vals,
+ sizeof(match_keys)/sizeof(match_keys[0]),
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ matching_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ TRUE);
+ CFRelease(matching);
+ }
if (ifUnique == NULL) {
CFIndex n;
Boolean useDeviceName = TRUE;
}
}
- if (useDeviceName) {
+ if (useDeviceName && useSystemInterfaces) {
if (matching_interfaces != NULL) {
CFRelease(matching_interfaces);
}
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- matching_interfaces = findMatchingInterfaces(matching, processSerialInterface);
+ matching_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ TRUE);
CFRelease(matching);
}
}
} else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypeL2TP)) {
interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
kSCNetworkInterfaceTypeL2TP);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
} else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPTP)) {
interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
kSCNetworkInterfaceTypePPTP);
+#pragma GCC diagnostic pop
} else {
// XXX do we allow non-Apple variants of PPP??? XXX
interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
if (matching_interfaces != NULL) {
CFIndex n;
SCPreferencesRef prefs;
+ Boolean temp_preferences = FALSE;
n = CFArrayGetCount(matching_interfaces);
switch (n) {
if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
break;
}
- prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
+
+ if (CFDictionaryGetValueIfPresent(interface_entity,
+ kSCPropUserDefinedName,
+ (const void **)&ifName) &&
+ CFEqual(ifName, CFSTR(BT_PAN_NAME))) {
+ break;
+ }
+
+ prefs = (service != NULL) ? ((SCNetworkServicePrivateRef)service)->prefs : NULL;
+ if (prefs == NULL) {
+ prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
+ if (prefs != NULL) {
+ temp_preferences = TRUE;
+ }
+ }
if (prefs == NULL) {
break;
}
&& !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
}
- CFRelease(prefs);
+ if (temp_preferences) CFRelease(prefs);
break;
default :
if (ifUnique != NULL) {
}
}
} else if (CFDictionaryGetValueIfPresent(interface_entity,
- kSCPropUserDefinedName,
- (const void **)&ifName)) {
+ kSCPropUserDefinedName,
+ (const void **)&ifName)) {
CFIndex i;
// we don't have a unique ID but do have an interface
}
}
if (interfacePrivate == NULL) {
- SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice);
+ SC_log(LOG_NOTICE, "more than one interface matches %@", ifDevice);
interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0);
}
CFRetain(interfacePrivate);
done :
- if (interfacePrivate == NULL) {
+ if ((interfacePrivate == NULL) || !useSystemInterfaces) {
/*
* if device not present on this system
*/
+ if (!useSystemInterfaces) {
+ if (interfacePrivate != NULL) {
+ CFRelease(interfacePrivate);
+ }
+ }
+
interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
- interfacePrivate->entity_type = ifType;
- interfacePrivate->entity_subtype = ifSubType;
+ interfacePrivate->entity_type = (ifType != NULL) ? ifType : NULL;
+ interfacePrivate->entity_subtype = (ifSubType != NULL) ? ifSubType : NULL;
interfacePrivate->entity_device = (ifDevice != NULL) ? CFStringCreateCopy(NULL, ifDevice) : NULL;
interfacePrivate->entity_device_unique = (ifUnique != NULL) ? CFStringCreateCopy(NULL, ifUnique) : NULL;
+ // Using UserDefinedName to check the validity of preferences file
+ // when useSystemInterfaces is FALSE
+ if (!useSystemInterfaces) {
+ CFStringRef userDefinedName = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
+ if (isA_CFString(userDefinedName) != NULL) {
+ CFRetain(userDefinedName);
+ if (interfacePrivate->name != NULL) {
+ CFRelease(interfacePrivate->name);
+ }
+ interfacePrivate->name = userDefinedName;
+
+ CFRetain(userDefinedName);
+ if (interfacePrivate->localized_name != NULL) {
+ CFRelease(interfacePrivate->localized_name);
+ }
+ interfacePrivate->localized_name = userDefinedName;
+ }
+ }
+
if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
CFStringRef entity_hardware;
+ SCNetworkInterfaceRef virtualInterface;
- entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware);
- if (isA_CFString((entity_hardware)) &&
- CFEqual(entity_hardware, kSCEntNetAirPort)) {
- interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
- interfacePrivate->localized_key = CFSTR("airport");
- interfacePrivate->sort_order = kSortAirPort;
+ if (!useSystemInterfaces &&
+ (((virtualInterface = findBridgeInterface(servicePref, ifDevice)) != NULL) ||
+#if !TARGET_OS_IPHONE
+ ((virtualInterface = findBondInterface(servicePref, ifDevice)) != NULL) ||
+#endif // !TARGET_OS_IPHONE
+ ((virtualInterface = findVLANInterface(servicePref, ifDevice)) != NULL))) {
+ CFRelease(interfacePrivate);
+ interfacePrivate = (SCNetworkInterfacePrivateRef)virtualInterface;
} else {
- CFStringRef name;
-
- interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
-
- name = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
- if (_SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) {
- interfacePrivate->localized_key = CFSTR("iPhone");
- interfacePrivate->sort_order = kSortTethered;
- } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) {
- interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
- interfacePrivate->sort_order = kSortBluetoothPAN_GN;
- } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-nap"))) {
- interfacePrivate->localized_key = CFSTR("bluetooth-pan-nap");
- interfacePrivate->sort_order = kSortBluetoothPAN_NAP;
- } else if (_SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-u"))) {
- interfacePrivate->localized_key = CFSTR("bluetooth-pan-u");
- interfacePrivate->sort_order = kSortBluetoothPAN_U;
+ entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware);
+ if (isA_CFString((entity_hardware)) &&
+ CFEqual(entity_hardware, kSCEntNetAirPort)) {
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
+ interfacePrivate->localized_key = CFSTR("airport");
+ interfacePrivate->sort_order = kSortAirPort;
} else {
- interfacePrivate->sort_order = kSortEthernet;
+ CFStringRef name;
+
+ interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+
+ name = CFDictionaryGetValue(interface_entity, kSCPropUserDefinedName);
+ if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPhone"))) {
+ interfacePrivate->localized_key = CFSTR("iPhone");
+ interfacePrivate->sort_order = kSortTethered;
+ } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("iPad"))) {
+ interfacePrivate->localized_key = CFSTR("iPad");
+ interfacePrivate->sort_order = kSortTethered;
+ } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("thunderbolt"))) {
+ interfacePrivate->localized_key = CFSTR("thunderbolt");
+ interfacePrivate->sort_order = kSortThunderbolt;
+ } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-gn"))) {
+ interfacePrivate->localized_key = CFSTR("bluetooth-pan-gn");
+ interfacePrivate->sort_order = kSortBluetoothPAN_GN;
+ } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-nap"))) {
+ interfacePrivate->localized_key = CFSTR("bluetooth-pan-nap");
+ interfacePrivate->sort_order = kSortBluetoothPAN_NAP;
+ } else if (__SCNetworkInterfaceMatchesName(name, CFSTR("bluetooth-pan-u"))) {
+ interfacePrivate->localized_key = CFSTR("bluetooth-pan-u");
+ interfacePrivate->sort_order = kSortBluetoothPAN_U;
+ } else {
+ interfacePrivate->sort_order = kSortEthernet;
+ }
}
}
} else if (CFEqual(ifType, kSCValNetInterfaceTypeFireWire)) {
interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
interfacePrivate->sort_order = kSortFireWire;
- } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
+ } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP) && (ifSubType != NULL)) {
if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) {
CFStringRef entity_hardware;
}
} else {
SCNetworkInterfaceRef child;
-
// PPTP, L2TP, ...
CFRelease(interfacePrivate);
child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
return NULL;
}
}
- } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) {
+ } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN) && (ifSubType != NULL)) {
SCNetworkInterfaceRef child;
-
CFRelease(interfacePrivate);
child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
interfacePrivate = (SCNetworkInterfacePrivateRef)child;
if (interfacePrivate == NULL) {
return NULL;
}
+ } else if (CFEqual(ifType, kSCValNetInterfaceTypeIPSec)) {
+ CFRelease(interfacePrivate);
+ interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+ kSCNetworkInterfaceTypeIPSec);
+ } else if (CFEqual(ifType, kSCValNetInterfaceType6to4)) {
+ CFRelease(interfacePrivate);
+ if (!isA_CFString(ifDevice)) {
+ return NULL;
+ }
+ interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+ kSCNetworkInterfaceType6to4);
+ } else if (CFEqual(ifType, kSCValNetInterfaceTypeLoopback)) {
+ CFRelease(interfacePrivate);
+ interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL);
} else if (CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) {
// if vendor interface
+ pthread_mutex_lock(&lock);
if (vendor_interface_types == NULL) {
vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
}
CFSetAddValue(vendor_interface_types, ifType);
-
interfacePrivate->interface_type = CFSetGetValue(vendor_interface_types, ifType);
+ pthread_mutex_unlock(&lock);
} else {
// if unknown interface
CFRelease(interfacePrivate);
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) {
__SCNetworkInterfaceSetService(member, service);
}
}
-
// set prefs & serviceID to VLAN pyhsical interface
if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeVLAN)) {
SCNetworkInterfaceRef vlan_physical;
__private_extern__
CFArrayRef
-__SCNetworkInterfaceCopyAll_IONetworkInterface(void)
+__SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured)
{
CFDictionaryRef matching;
CFArrayRef new_interfaces;
- // get Ethernet, Firewire, and AirPort interfaces
+ // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
matching = IOServiceMatching(kIONetworkInterfaceClass);
- new_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
+ new_interfaces = findMatchingInterfaces(matching,
+ processNetworkInterface,
+ kSCNetworkInterfaceHiddenInterfaceKey,
+ keep_pre_configured);
CFRelease(matching);
return new_interfaces;
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- new_interfaces = findMatchingInterfaces(matching, processSerialInterface);
+ new_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ FALSE);
CFRelease(matching);
return new_interfaces;
sizeof(match_keys)/sizeof(match_keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- new_interfaces = findMatchingInterfaces(matching, processSerialInterface);
+ new_interfaces = findMatchingInterfaces(matching,
+ processSerialInterface,
+ kSCNetworkInterfaceHiddenPortKey,
+ FALSE);
CFRelease(matching);
return new_interfaces;
#if !TARGET_OS_IPHONE
static void
-addBTPANInterface(SCPreferencesRef prefs, CFMutableArrayRef all_interfaces)
+addBTPANInterface(CFMutableArrayRef all_interfaces)
{
- CFIndex i;
- CFIndex n;
- CFArrayRef services;
+ CFIndex i;
+ SCNetworkInterfaceRef interface;
+ CFIndex n;
n = CFArrayGetCount(all_interfaces);
for (i = 0; i < n; i++) {
}
}
- services = SCNetworkServiceCopyAll(prefs);
- if (services != NULL) {
- n = CFArrayGetCount(services);
- for (i = 0; i < n; i++) {
- SCNetworkInterfaceRef interface;
- SCNetworkServiceRef service;
-
- service = CFArrayGetValueAtIndex(services, i);
- interface = SCNetworkServiceGetInterface(service);
- if ((interface != NULL) &&
- _SCNetworkInterfaceIsBluetoothPAN(interface)) {
- // include BT-PAN interface
- CFArrayAppendValue(all_interfaces, interface);
- break;
- }
- }
-
- CFRelease(services);
+ interface = _SCNetworkInterfaceCopyBTPANInterface();
+ if (interface != NULL) {
+ // include BT-PAN interface
+ CFArrayAppendValue(all_interfaces, interface);
+ CFRelease(interface);
}
return;
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);
ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
CFRelease(keys);
if (!ok) {
- SCLog(TRUE, LOG_ERR,
- CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
+ SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
goto done;
}
dict = SCDynamicStoreCopyValue(store, key);
if (dict != NULL) {
if (isA_CFDictionary(dict) &&
- (CFDictionaryContainsKey(dict, CFSTR("*QUIET*")) ||
- CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*")))) {
+ (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet) ||
+ CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout))) {
quiet = TRUE;
}
CFRelease(dict);
ok = SCDynamicStoreNotifyWait(store);
if (!ok) {
- SCLog(TRUE, LOG_ERR,
- CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
+ SC_log(LOG_NOTICE, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
goto done;
}
done :
- CFRelease(key);
- CFRelease(store);
+ CRSetCrashLogMessage(NULL);
+
+ if (key != NULL) CFRelease(key);
+ if (store != NULL) CFRelease(store);
return;
}
all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- // get Ethernet, Firewire, and AirPort interfaces
- new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
+ // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
+ new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE);
if (new_interfaces != NULL) {
add_interfaces(all_interfaces, new_interfaces);
CFRelease(new_interfaces);
#if !TARGET_OS_IPHONE
// add BT-PAN interface
- addBTPANInterface(prefs, all_interfaces);
+ addBTPANInterface(all_interfaces);
#endif // !TARGET_OS_IPHONE
if (temp_preferences) CFRelease(prefs);
if (configurations[i].supported_interfaces & doPPP) {
CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPP);
}
- if (configurations[i].supported_interfaces & doPPTP) {
- CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPTP);
- }
if (configurations[i].supported_interfaces & doIPSec) {
CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeIPSec);
}
parentPrivate->interface_type = kSCNetworkInterfaceTypeL2TP;
parentPrivate->localized_key = CFSTR("l2tp");
parentPrivate->entity_type = kSCEntNetL2TP; // interface config goes into "L2TP"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) {
if ((childIndex == kCFNotFound) ||
((configurations[childIndex].supported_interfaces & doPPTP) != doPPTP)) {
parentPrivate->interface_type = kSCNetworkInterfaceTypePPTP;
parentPrivate->localized_key = CFSTR("pptp");
parentPrivate->entity_type = kSCEntNetPPTP; // interface config goes into "PPTP"
+#pragma GCC diagnostic pop
} else if (CFEqual(interfaceType, kSCNetworkInterfaceType6to4)) {
if ((childIndex == kCFNotFound) ||
((configurations[childIndex].supported_interfaces & do6to4) != do6to4)) {
}
} else if (CFStringFind(interfaceType, CFSTR("."), 0).location != kCFNotFound) {
// if custom interface type
+ pthread_mutex_lock(&lock);
if (vendor_interface_types == NULL) {
vendor_interface_types = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
}
CFSetAddValue(vendor_interface_types, interfaceType);
-
parentPrivate->interface_type = CFSetGetValue(vendor_interface_types, interfaceType);
+ pthread_mutex_unlock(&lock);
+
parentPrivate->entity_type = parentPrivate->interface_type; // interface config goes into a
// a dictionary with the same
// name as the interfaceType
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);
}
}
+__private_extern__
+CFStringRef
+__SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->entity_type;
+}
+
+
+__private_extern__
+CFStringRef
+__SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
+
+ return interfacePrivate->entity_subtype;
+}
+
+
CFStringRef
SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface)
{
(interfacePrivate->addressString == NULL)) {
uint8_t *bp;
char *cp;
- CFIndex n;
+ size_t n;
char mac[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
char *mac_p = mac;
n = CFDataGetLength(interfacePrivate->address) * 3;
if (n > sizeof(mac)) {
- mac_p = CFAllocatorAllocate(NULL, 0, n);
+ mac_p = CFAllocatorAllocate(NULL, n, 0);
}
for (cp = mac_p; n > 0; n -= 3) {
static CFStringRef
-copy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized)
+copy_string_from_bundle(CFBundleRef bundle, CFStringRef key, Boolean localized)
{
CFStringRef str = NULL;
}
+static CFStringRef
+copy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized)
+{
+ static Boolean reported = FALSE;
+ CFStringRef str = NULL;
+
+ str = copy_string_from_bundle(bundle, key, localized);
+
+ if (str == NULL) {
+ SC_log(LOG_ERR, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle,
+ key,
+ localized);
+ goto done;
+ }
+
+ if (CFEqual(str, key) && !reported) {
+ const CFStringRef knownStrKey = CFSTR("airport");
+ CFStringRef knownStrValue = NULL;
+
+ knownStrValue = copy_string_from_bundle(bundle, knownStrKey, localized);
+ if (knownStrValue == NULL || CFEqual(knownStrValue, knownStrKey)) {
+ /* We are here because we requested for a localized/non-localized string
+ based on the localization key, but we were given the same key/NULL back,
+ implying a bad...bad thing!
+ */
+ SC_log(LOG_ERR, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle,
+ knownStrKey,
+ localized);
+
+#if TARGET_OS_IPHONE
+ /* ...and we want to know about it! */
+ _SC_crash("Failed to retrieve interface string", NULL, NULL);
+#endif //TARGET_OS_IPHONE
+ reported = TRUE;
+ }
+
+ if (knownStrValue != NULL) {
+ CFRelease(knownStrValue);
+ }
+ }
+
+done:
+ return str;
+}
+
+
static CFStringRef
copy_display_name(SCNetworkInterfaceRef interface, Boolean localized, Boolean oldLocalization)
{
}
-#if !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_IPHONE
__private_extern__
CFStringRef
__SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface)
localized_name = copy_display_name(interface, FALSE, TRUE);
return localized_name;
}
-#endif // !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
+#endif // !TARGET_OS_IPHONE
+
+__private_extern__
+void
+__SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface, CFStringRef name)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if (!isA_SCNetworkInterface(interface)) {
+ return;
+ }
+ if (name != NULL) {
+ CFRetain(name);
+ }
+ if (interfacePrivate->name != NULL) {
+ CFRelease(interfacePrivate->name);
+ }
+ interfacePrivate->name = name;
+
+ if (name != NULL) {
+ CFRetain(name);
+ }
+ if (interfacePrivate->localized_name != NULL) {
+ CFRelease(interfacePrivate->localized_name);
+ }
+ interfacePrivate->localized_name = name;
+}
+
+__private_extern__
+CFStringRef
+__SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if (!isA_SCNetworkInterface(interface)) {
+ return NULL;
+ }
+
+ return interfacePrivate->name;
+}
__private_extern__
__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);
SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionaryRef config)
{
CFStringRef defaultType;
+ Boolean ok;
if (!isA_SCNetworkInterface(interface)) {
_SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
}
- return __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
+ ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
+ if (ok) {
+ SC_log(LOG_DEBUG, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
+ interface,
+ config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+ }
+
+ return ok;
}
CFStringRef extendedType,
CFDictionaryRef config)
{
+ Boolean ok;
+
if (!isA_SCNetworkInterface(interface)) {
_SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
return FALSE;
}
- return __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE);
+ ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE);
+ if (ok) {
+ SC_log(LOG_DEBUG, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
+ interface,
+ config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+ }
+
+ return ok;
}
#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
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
CFStringRef name;
+ if (interface == NULL) {
+ return NULL;
+ }
+
info = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
// add USB info
if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
+#if !TARGET_OS_SIMULATOR
if (interfacePrivate->usb.name != NULL) {
CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name);
}
if (interfacePrivate->usb.pid != NULL) {
CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
}
+#endif // !TARGET_OS_SIMULATOR
}
if (CFDictionaryGetCount(info) == 0) {
pthread_once(&initialized, __SCNetworkInterfaceInitialize);
if (IOObjectConformsTo(if_obj, kIONetworkInterfaceClass)) {
- interface = createInterface(if_obj, processNetworkInterface);
+ interface = createInterface(if_obj, processNetworkInterface, NULL);
} else if (IOObjectConformsTo(if_obj, kIOSerialBSDServiceValue)) {
- interface = createInterface(if_obj, processSerialInterface);
+ interface = createInterface(if_obj, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
}
return interface;
}
+CFStringRef
+_SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->prefix;
+}
+
+
CFNumberRef
_SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
{
}
+static void
+update_ift_family(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ // note: family/subfamily are not in IORegistry, fetch with ioctl()
+
+ if ((interfacePrivate->family == NULL) && (interfacePrivate->subfamily == NULL)) {
+ CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+ struct ifreq 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;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s != -1) {
+ if (ioctl(s, SIOCGIFTYPE, (caddr_t)&ifr) == -1) {
+ ifr.ifr_type.ift_family = 0;
+ ifr.ifr_type.ift_subfamily = 0;
+ }
+ close(s);
+ }
+ }
+
+ interfacePrivate->family = CFNumberCreate(NULL,
+ kCFNumberSInt32Type,
+ &ifr.ifr_type.ift_family);
+ interfacePrivate->subfamily = CFNumberCreate(NULL,
+ kCFNumberSInt32Type,
+ &ifr.ifr_type.ift_subfamily);
+ }
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ // note: family not in IORegistry, fetch with ioctl()
+
+ if (interfacePrivate->family == NULL) {
+ update_ift_family(interface);
+ }
+
+ return interfacePrivate->family;
+}
+
+
+CFNumberRef
+_SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ // note: subfamily not in IORegistry, fetch with ioctl()
+
+ if (interfacePrivate->subfamily == NULL) {
+ update_ift_family(interface);
+ }
+
+ return interfacePrivate->subfamily;
+}
+
+
CFStringRef
_SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface)
{
}
+__private_extern__
+Boolean
+__SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->active;
+}
+
+
Boolean
_SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface)
{
}
+Boolean
+_SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ return interfacePrivate->trustRequired;
+}
+
+
#pragma mark -
#pragma mark SCNetworkInterface SPIs
+#if TARGET_OS_OSX
+
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCopyBTPANInterface(void)
+{
+ CFDictionaryRef dict;
+ SCNetworkInterfaceRef interface = NULL;
+ CFStringRef key;
+
+ key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
+ dict = SCDynamicStoreCopyValue(NULL, key);
+ CFRelease(key);
+ if (dict != NULL) {
+ CFDataRef addr;
+ CFStringRef if_name;
+ SCNetworkInterfacePrivateRef interfacePrivate;
+
+ if (isA_CFDictionary(dict) &&
+ CFDictionaryGetValueIfPresent(dict,
+ kInterfaceNamerKey_BT_PAN_Name,
+ (const void **)&if_name) &&
+ isA_CFString(if_name)) {
+ CFMutableDictionaryRef entity;
+
+ entity = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(entity,
+ kSCPropNetInterfaceType,
+ kSCValNetInterfaceTypeEthernet);
+ CFDictionarySetValue(entity,
+ kSCPropNetInterfaceDeviceName,
+ if_name);
+ CFDictionarySetValue(entity,
+ kSCPropUserDefinedName,
+ CFSTR(BT_PAN_NAME));
+ interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL);
+ CFRelease(entity);
+ }
+
+ interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if ((interfacePrivate != NULL) &&
+ (interfacePrivate->address == NULL) &&
+ CFDictionaryGetValueIfPresent(dict,
+ kInterfaceNamerKey_BT_PAN_Mac,
+ (const void **)&addr) &&
+ isA_CFData(addr)) {
+ interfacePrivate->address = CFRetain(addr);
+ }
+
+ CFRelease(dict);
+ }
+
+ return interface;
+}
+#endif // TARGET_OS_OSX
+
+
CFStringRef
_SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface)
{
// note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
kr = IOServiceGetMatchingServices(masterPort, matching, &device_iterator);
if (kr != kIOReturnSuccess) {
- SCLog(TRUE, LOG_DEBUG, CFSTR("IOServiceGetMatchingServices() failed, kr = 0x%x"), kr);
+ SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
goto done;
}
IOObjectRelease(device_iterator);
- done :
+ done :
+
+ if (device_path == NULL) {
+ // if we haven't found an exact match to our UniqueIdentifier
+ // so we simply return the base name.
+ device_path = SCNetworkInterfaceGetBSDName(interface);
+ if (device_path != NULL) {
+ CFRetain(device_path);
+ }
+ }
+
+ return device_path;
+}
+
+
+#pragma mark -
+
+
+Boolean
+_SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface)
+{
+#if TARGET_OS_SIMULATOR
+#pragma unused(interface)
+#else // TARGET_OS_SIMULATOR
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+
+ if (!_SCNetworkInterfaceIsHiddenConfiguration(interface)) {
+ // if not HiddenConfiguration
+ return FALSE;
+ }
+
+ if ((interfacePrivate->overrides == NULL) ||
+ (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) &&
+ !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) {
+ // if no [IPv4/IPv6] configuration overrides
+ return FALSE;
+ }
+
+ 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;
- if (device_path == NULL) {
- // if we haven't found an exact match to our UniqueIdentifier
- // so we simply return the base name.
- device_path = SCNetworkInterfaceGetBSDName(interface);
- if (device_path != NULL) {
- CFRetain(device_path);
+ if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) &&
+ (vid == kIOUSBVendorIDAppleComputer)) {
+ // if Apple interface (and overrides are present)
+ return TRUE;
}
}
+#endif // TARGET_OS_SIMULATOR
- return device_path;
+ return FALSE;
}
Boolean
-_SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface)
+_SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface)
{
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
- return interfacePrivate->hidden;
+ return (interfacePrivate->sort_order == kSortCarPlay);
}
Boolean
-_SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface)
+_SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface)
{
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
- return interfacePrivate->modemIsV92;
+ return interfacePrivate->hidden;
}
}
+Boolean
+_SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface)
+{
+ SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+ CFStringRef interfaceType;
+
+ if (!isA_SCNetworkInterface(interface)) {
+ return FALSE;
+ }
+
+ interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+ if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) {
+ CFIndex i;
+ CFArrayRef members;
+ CFIndex n;
+
+ members = SCBridgeInterfaceGetMemberInterfaces(interface);
+ n = (members != NULL) ? CFArrayGetCount(members) : 0;
+ if (n == 0) {
+ // if an empty bridge
+ return FALSE;
+ }
+
+ for (i = 0; i < n; i++) {
+ SCNetworkInterfaceRef member;
+ SCNetworkInterfacePrivateRef memberPrivate;
+
+ member = CFArrayGetValueAtIndex(members, i);
+ memberPrivate = (SCNetworkInterfacePrivateRef)member;
+ if (memberPrivate->sort_order != kSortThunderbolt) {
+ return FALSE;
+ }
+ }
+
+ // if Ethernet Bridge interface with only Thunderbolt [IP] members
+ return TRUE;
+ }
+
+ return (interfacePrivate->sort_order == kSortThunderbolt);
+}
+
+
+#pragma mark -
+
+
+CFDictionaryRef
+SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface)
+{
+ CFDictionaryRef policy;
+
+ if (!isA_SCNetworkInterface(interface)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ policy = __SCNetworkInterfaceGetConfiguration(interface, kSCEntNetQoSMarkingPolicy);
+ if (policy == NULL) {
+ _SCErrorSet(kSCStatusOK);
+ }
+
+ return policy;
+}
+
+Boolean
+SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface, CFDictionaryRef policy)
+{
+ Boolean ok;
+
+ if (!isA_SCNetworkInterface(interface)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ ok = __SCNetworkInterfaceSetConfiguration(interface, kSCEntNetQoSMarkingPolicy, policy, FALSE);
+ if (ok) {
+ SC_log(LOG_DEBUG, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
+ interface,
+ policy != NULL ? policy : (CFDictionaryRef)CFSTR("NULL"));
+ }
+
+ return ok;
+}
+
+
#pragma mark -
#pragma mark SCNetworkInterface [internal] SPIs
SCPreferencesRef prefs,
CFStringRef serviceID)
{
+#pragma unused(allocator)
SCNetworkInterfacePrivateRef oldPrivate = (SCNetworkInterfacePrivateRef)interface;
SCNetworkInterfacePrivateRef newPrivate;
if (oldPrivate->name != NULL) {
newPrivate->name = CFRetain(oldPrivate->name);
}
+ if (oldPrivate->prefix != NULL) {
+ newPrivate->prefix = CFRetain(oldPrivate->prefix);
+ }
if (oldPrivate->localized_name != NULL) {
newPrivate->localized_name = CFRetain(oldPrivate->localized_name);
}
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);
}
if (oldPrivate->overrides != NULL) {
newPrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, oldPrivate->overrides);
}
- newPrivate->modemIsV92 = oldPrivate->modemIsV92;
if (oldPrivate->type != NULL) {
newPrivate->type = CFRetain(oldPrivate->type);
}
if (oldPrivate->unit != NULL) {
newPrivate->unit = CFRetain(oldPrivate->unit);
}
+ if (oldPrivate->family != NULL) {
+ newPrivate->family = CFRetain(oldPrivate->family);
+ }
+ if (oldPrivate->subfamily != NULL) {
+ newPrivate->subfamily = CFRetain(oldPrivate->subfamily);
+ }
if (oldPrivate->usb.name != NULL) {
newPrivate->usb.name = CFRetain(oldPrivate->usb.name);
}
for (i = 0; interface != NULL; i++) {
CFStringRef defaultType;
CFDictionaryRef interfaceConfiguration;
+ Boolean ok;
interfaceConfiguration = (configs != NULL) ? CFArrayGetValueAtIndex(configs, i) : NULL;
}
if (set == NULL) {
// if service is not associated with the set
- if (!__SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE)) {
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
- interface,
- defaultType);
- }
+ ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE);
} else {
// apply default configuration to this set
- if (!__SCNetworkInterfaceSetDefaultConfiguration(set, interface, defaultType, config, TRUE)) {
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetDefaultConfiguration() failed, interface=%@, type=%@"),
- interface,
- defaultType);
- }
+ ok = __SCNetworkInterfaceSetDefaultConfiguration(set, interface, defaultType, config, TRUE);
+ }
+ if (ok) {
+ SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
+ interface,
+ defaultType,
+ config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+ } else {
+ SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
+ interface,
+ defaultType);
}
extendedTypes = extendedConfigurationTypes(interface);
extendedType = CFArrayGetValueAtIndex(extendedTypes, j);
config = (interfaceConfiguration != NULL) ? CFDictionaryGetValue(interfaceConfiguration, extendedType)
- : NULL;
+ : NULL;
if (config == (CFDictionaryRef)kCFNull) {
config = NULL;
}
- if (!__SCNetworkInterfaceSetConfiguration(interface, extendedType, config, TRUE)) {
- SCLog(TRUE, LOG_DEBUG,
- CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
- interface,
- defaultType);
+ ok = __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, TRUE);
+ if (ok) {
+ SC_log(LOG_DEBUG, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
+ interface,
+ extendedType,
+ config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+ } else {
+ SC_log(LOG_INFO, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
+ interface,
+ extendedType);
}
}
}
+#if !TARGET_OS_SIMULATOR
SCNetworkServicePrimaryRank
SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface)
{
- CFDictionaryRef entity;
- SCNetworkInterfacePrivateRef interfacePrivate =
- (SCNetworkInterfacePrivateRef)interface;
+ IPMonitorControlRef control;
+ SCNetworkInterfacePrivateRef interfacePrivate =
+ (SCNetworkInterfacePrivateRef)interface;
+ SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault;
+
+ control = interfacePrivate->IPMonitorControl;
+ if (control != NULL) {
+ CFStringRef ifName;
+
+ ifName = SCNetworkInterfaceGetBSDName(interface);
+ if (ifName != NULL) {
+ rank = IPMonitorControlGetInterfacePrimaryRank(control,
+ ifName);
+ }
+ else {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ }
+ }
+ return rank;
+}
+
+Boolean
+SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface,
+ SCNetworkServicePrimaryRank newRank)
+{
+ IPMonitorControlRef control;
+ SCNetworkInterfacePrivateRef interfacePrivate =
+ (SCNetworkInterfacePrivateRef)interface;
CFStringRef ifName;
- Boolean ok = FALSE;
- CFStringRef path;
- SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault;
- SCDynamicStoreRef session;
ifName = SCNetworkInterfaceGetBSDName(interface);
- if ((ifName == NULL) || (interfacePrivate->store == NULL)) {
+ if (ifName == NULL) {
_SCErrorSet(kSCStatusInvalidArgument);
- return rank;
+ return (FALSE);
+ }
+ control = interfacePrivate->IPMonitorControl;
+ if (control == NULL) {
+ control = IPMonitorControlCreate();
+ if (control == NULL) {
+ _SCErrorSet(kSCStatusFailed);
+ return (FALSE);
+ }
+ interfacePrivate->IPMonitorControl = control;
}
+ return IPMonitorControlSetInterfacePrimaryRank(control,
+ ifName,
+ newRank);
+}
- session = interfacePrivate->store;
+Boolean
+SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
+{
+ Boolean disable_until_needed = FALSE;
+ CFNumberRef disable_prop = NULL;
+ CFIndex interfaceIndex;
+ SCNetworkInterfacePrivateRef interfacePrivate
+ = (SCNetworkInterfacePrivateRef)interface;
+ CFArrayRef path_list;
- path = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
- kSCDynamicStoreDomainState,
- ifName,
- kSCEntNetService);
- entity = SCDynamicStoreCopyValue(session, path);
- CFRelease(path);
+ if (interfacePrivate->prefs == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ interfaceIndex = findPerInterfaceConfiguration(interface);
+ if (interfaceIndex == kCFNotFound) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ path_list = copyPerInterfaceConfigurationPaths(interfacePrivate, NULL);
+ if (path_list != NULL) {
+ CFDictionaryRef config;
+ CFStringRef path = CFArrayGetValueAtIndex(path_list, 0);
- if (entity != NULL) {
- if (isA_CFDictionary(entity)) {
- CFStringRef rankStr =
- CFDictionaryGetValue(entity, kSCPropNetServicePrimaryRank);
- ok = __str_to_rank(rankStr, &rank);
+ config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+ CFRelease(path_list);
+ if (config != NULL) {
+ int disable = 0;
+
+ disable_prop = CFDictionaryGetValue(config, kSCPropDisableUntilNeeded);
+ disable_prop = isA_CFNumber(disable_prop);
+ if (disable_prop != NULL) {
+ if (CFNumberGetValue(disable_prop, kCFNumberIntType, &disable)) {
+ disable_until_needed = (disable != 0) ? TRUE : FALSE;
+ }
+ else {
+ /* invalid property, ignore it */
+ disable_prop = NULL;
+ }
+ }
}
- CFRelease(entity);
}
+ if (disable_prop == NULL) {
+ disable_until_needed
+ = _SCNetworkInterfaceIsTethered(interface);
+ }
+ _SCErrorSet(kSCStatusOK);
+ return (disable_until_needed);
+}
- if (!ok) {
- rank = kSCNetworkServicePrimaryRankDefault;
+Boolean
+__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable)
+{
+ CFIndex count;
+ CFIndex i;
+ CFIndex interfaceIndex;
+ SCNetworkInterfacePrivateRef interfacePrivate
+ = (SCNetworkInterfacePrivateRef)interface;
+ Boolean ok = TRUE;
+ CFArrayRef path_list;
+
+ if (interfacePrivate->prefs == NULL) {
_SCErrorSet(kSCStatusInvalidArgument);
- } else if (rank == kSCNetworkServicePrimaryRankDefault) {
- _SCErrorSet(kSCStatusOK);
+ return (FALSE);
+ }
+ if ((disable != NULL) && !isA_CFNumber(disable)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ interfaceIndex = findPerInterfaceConfiguration(interface);
+ if (interfaceIndex == kCFNotFound) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
}
+ path_list = copyPerInterfaceConfigurationPaths(interfacePrivate, NULL);
+ if (path_list == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+ }
+ count = CFArrayGetCount(path_list);
+ for (i = 0; i < count; i++) {
+ CFDictionaryRef config;
+ CFMutableDictionaryRef new_config;
+ CFStringRef path = CFArrayGetValueAtIndex(path_list, i);
+
+ config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+ if (config != NULL) {
+ new_config
+ = CFDictionaryCreateMutableCopy(NULL, 0, config);
+ } else {
+ new_config
+ = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ if (disable != NULL) {
+ CFDictionarySetValue(new_config, kSCPropDisableUntilNeeded, disable);
+ } else {
+ CFDictionaryRemoveValue(new_config, kSCPropDisableUntilNeeded);
+ }
+ ok = __setPrefsConfiguration(interfacePrivate->prefs,
+ path,
+ (CFDictionaryGetCount(new_config) > 0) ? new_config : NULL,
+ FALSE);
+ CFRelease(new_config);
+ if (!ok) {
+ break;
+ }
+ }
+ CFRelease(path_list);
+ return (ok);
+}
+
+Boolean
+SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable)
+{
+ Boolean ok;
+ const int one = 1;
+ CFNumberRef num;
+ const int zero = 0;
- return (rank);
+ num = CFNumberCreate(NULL, kCFNumberIntType, disable ? &one : &zero);
+ ok = __SCNetworkInterfaceSetDisableUntilNeededValue(interface, num);
+ CFRelease(num);
+
+ return ok;
+}
+
+#else // !TARGET_OS_SIMULATOR
+
+SCNetworkServicePrimaryRank
+SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface)
+{
+#pragma unused(interface)
+ return (kSCNetworkServicePrimaryRankDefault);
}
Boolean
SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface,
SCNetworkServicePrimaryRank newRank)
{
- CFDictionaryRef entity;
- SCNetworkInterfacePrivateRef interfacePrivate =
- (SCNetworkInterfacePrivateRef)interface;
- CFStringRef ifName;
- CFMutableDictionaryRef newEntity;
- Boolean ok = TRUE;
- CFStringRef path = NULL;
- CFStringRef rankStr;
- SCDynamicStoreRef session;
+#pragma unused(interface)
+#pragma unused(newRank)
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+}
- ifName = SCNetworkInterfaceGetBSDName(interface);
- if ((ifName == NULL) || (interfacePrivate->store == NULL)) {
- _SCErrorSet(kSCStatusInvalidArgument);
- return FALSE;
+Boolean
+SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
+{
+#pragma unused(interface)
+ return (FALSE);
+}
+
+Boolean
+__SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface, CFTypeRef disable)
+{
+#pragma unused(interface)
+#pragma unused(disable)
+ return (FALSE);
+}
+
+Boolean
+SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface, Boolean disable)
+{
+#pragma unused(interface)
+#pragma unused(disable)
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return (FALSE);
+}
+
+#endif // !TARGET_OS_SIMULATOR
+
+
+__private_extern__
+CFArrayRef // SCNetworkInterfaceRef
+__SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs)
+{
+ CFStringRef defaultNetworkInterfacePath = NULL;
+ CFArrayRef if_list;
+ CFMutableArrayRef interfaceList = NULL;
+ SCNetworkInterfaceRef interfaceNamer = NULL;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+ if (ni_prefs == NULL) {
+ defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+ assert(defaultNetworkInterfacePath != NULL);
+ ni_prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
}
- session = interfacePrivate->store;
+ if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
+ if (isA_CFArray(if_list)) {
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(if_list);
- ok = __rank_to_str(newRank, &rankStr);
- if (!ok) {
- _SCErrorSet(kSCStatusInvalidArgument);
- return FALSE;
+ interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ for (i = 0; i < n; i++) {
+ CFDictionaryRef dict;
+
+ dict = CFArrayGetValueAtIndex(if_list, i);
+ if (isA_CFDictionary(dict) != NULL) {
+ interfaceNamer = __SCNetworkInterfaceCreateWithStorageEntity(NULL, dict);
+
+ if (interfaceNamer != NULL) {
+ CFArrayAppendValue(interfaceList, interfaceNamer);
+ CFRelease(interfaceNamer);
+ }
+ }
+ }
+ }
+
+ if (defaultNetworkInterfacePath != NULL) {
+ CFRelease(defaultNetworkInterfacePath);
+ // prefs were created in the function, and hence need to be released
+ CFRelease(ni_prefs);
}
+ return interfaceList;
+}
- path = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
- kSCDynamicStoreDomainState,
- ifName,
- kSCEntNetService);
- entity = SCDynamicStoreCopyValue(session, path);
- if (entity != NULL) {
- if (!isA_CFDictionary(entity)) {
- CFRelease(entity);
- _SCErrorSet(kSCStatusFailed);
- goto done;
+__private_extern__
+Boolean
+__SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs, CFArrayRef interfacesToSave)
+{
+ CFStringRef defaultNetworkInterfacePath = NULL;
+ Boolean success = FALSE;
+
+ if (prefs == NULL) { // TODO: Get the default preferences on the system
+ defaultNetworkInterfacePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+ assert(defaultNetworkInterfacePath != NULL);
+ prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
+ }
+
+ if (isA_CFArray(interfacesToSave) == NULL) {
+ SC_log(LOG_INFO, "No interfaces to save");
+ goto done;
+ }
+ SCPreferencesSetValue(prefs, INTERFACES, interfacesToSave);
+ success = TRUE;
+done:
+ if (defaultNetworkInterfacePath != NULL) {
+ CFRelease(defaultNetworkInterfacePath);
+ // prefs were created in the function, and hence need to be released
+ CFRelease(prefs);
+ }
+
+ return success;
+}
+
+__private_extern__
+SCNetworkInterfaceRef
+__SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator, SCPreferencesRef ni_prefs, CFStringRef bsdName)
+{
+ CFArrayRef if_list;
+ SCNetworkInterfaceRef interface = NULL;
+ CFStringRef defaultNetworkInterfacePath;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+ if (ni_prefs == NULL) {
+ defaultNetworkInterfacePath = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+ ni_prefs = SCPreferencesCreate(allocator, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath);
+ CFRelease(defaultNetworkInterfacePath);
+ }
+ else {
+ CFRetain(ni_prefs);
+ }
+
+ if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
+
+ if (isA_CFArray(if_list) != NULL) {
+ CFIndex idx;
+ CFIndex count = CFArrayGetCount(if_list);
+
+ for (idx = 0; idx < count; idx++) {
+ CFDictionaryRef dict;
+ CFStringRef tmp_bsdName;
+
+ dict = CFArrayGetValueAtIndex(if_list, idx);
+ if (isA_CFDictionary(dict) == NULL) {
+ continue;
+ }
+
+ tmp_bsdName = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceBSDName));
+ if (tmp_bsdName == NULL) {
+ continue;
+ }
+ if (CFEqual(bsdName, tmp_bsdName)) {
+ interface = __SCNetworkInterfaceCreateWithStorageEntity(allocator, dict);
+ break;
+ }
}
- newEntity = CFDictionaryCreateMutableCopy(NULL, 0, entity);
- CFRelease(entity);
- } else {
- newEntity = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
}
- if (rankStr != NULL) {
- CFDictionarySetValue(newEntity, kSCPropNetServicePrimaryRank, rankStr);
- } else {
- CFDictionaryRemoveValue(newEntity, kSCPropNetServicePrimaryRank);
+ CFRelease(ni_prefs);
+ return interface;
+}
+
+__private_extern__
+CFDictionaryRef
+__SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces)
+{
+ CFMutableDictionaryRef mappingBSDToInterface = NULL;
+ CFStringRef bsdName = NULL;
+ SCNetworkInterfaceRef interface = NULL;
+ CFIndex count;
+
+ count = CFArrayGetCount(interfaces);
+ if (count == 0) {
+ SC_log(LOG_INFO, "No interfaces");
+ return NULL;
}
+ mappingBSDToInterface = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (CFDictionaryGetCount(newEntity) > 0) {
- ok = SCDynamicStoreSetValue(session, path, newEntity);
- } else {
- ok = SCDynamicStoreRemoveValue(session, path);
+ for (CFIndex idx = 0; idx < count; idx++) {
+ interface = (SCNetworkInterfaceRef) CFArrayGetValueAtIndex(interfaces, idx);
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (isA_CFString(bsdName) == NULL) {
+ SC_log(LOG_INFO, "No BSD name");
+ continue;
+ }
+ CFDictionaryAddValue(mappingBSDToInterface, bsdName, interface);
+ }
+ if (CFDictionaryGetCount(mappingBSDToInterface) == 0) {
+ CFRelease(mappingBSDToInterface);
+ mappingBSDToInterface = NULL;
+ SC_log(LOG_INFO, "No mappings");
}
- CFRelease(newEntity);
+ return mappingBSDToInterface;
+}
- done :
+__private_extern__ Boolean
+__SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity)
+{
+ CFStringRef intfSubtype;
- if (path != NULL) CFRelease(path);
- return ok;
+ if (entity == NULL) {
+ return FALSE;
+ }
+
+ intfSubtype = CFDictionaryGetValue(entity, kSCPropNetInterfaceSubType);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+ if (intfSubtype != NULL && CFEqual(intfSubtype, kSCValNetInterfaceSubTypePPTP)) {
+ return TRUE;
+ }
+#pragma GCC diagnostic pop
+
+ return FALSE;
}