]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCNetworkInterface.c
configd-1061.40.2.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkInterface.c
index d695a6a889ec4bca9cdf4fc88c7a300eb32efdda..32c6c61f2441e9da698d9b9a79726a6a1cc18ff0 100644 (file)
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2007 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,
@@ -17,7 +17,7 @@
  * 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 <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 <SystemConfiguration/BondConfiguration.h>
-#include <SystemConfiguration/VLANConfiguration.h>
 #include "SCPreferencesInternal.h"
 #include "SCHelper_client.h"
+#include "plugin_shared.h"
 
+#if    !TARGET_OS_IPHONE
 #include <EAP8021X/EAPClientProperties.h>
+#else  // !TARGET_OS_IPHONE
+#ifndef        kEAPClientPropUserName
+#define kEAPClientPropUserName CFSTR("UserName")
+#endif
+#ifndef        kEAPClientPropUserPasswordKeychainItemID
+#define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
+#endif
+#endif // !TARGET_OS_IPHONE
 
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOCFBundle.h>
 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
 #include <IOKit/serial/IOSerialKeys.h>
 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
+#if    !TARGET_OS_SIMULATOR
+#include <IOKit/usb/IOUSBLib.h>
+#endif // !TARGET_OS_SIMULATOR
+
 #include "dy_framework.h"
 
-#ifndef        kIODeviceSupportsHoldKey
-#define        kIODeviceSupportsHoldKey        "V92Modem"
+#ifndef        kPCIThunderboltString
+#define kPCIThunderboltString          "PCI-Thunderbolt"
+#endif
+
+#if    TARGET_OS_OSX
+#ifndef        kUSBSupportsIPhoneOS
+#define kUSBSupportsIPhoneOS           "SupportsIPhoneOS"
+#endif // !kUSBSupportsIPhoneOS
+#endif // TARGET_OS_OSX
+
+#ifndef        kIOUserEthernetInterfaceRoleKey
+#define        kIOUserEthernetInterfaceRoleKey "InterfaceRole"
+#endif
+
+#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>
 
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
-#error MAC_OS_X_VERSION_MIN_REQUIRED < 1040, Check MACOSX_DEPLOYMENT_TARGET
-#endif
+/* 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,
        kSortIrDA,
        kSortSerialPort,
        kSortWWAN,
+       kSortEthernetPPP,
+       kSortAirportPPP,
        kSortEthernet,
        kSortFireWire,
        kSortAirPort,
        kSortOtherWireless,
-       kSortBluetoothPAN,
+       kSortTethered,
+       kSortWWANEthernet,
+       kSortBluetoothPAN_GN,
+       kSortBluetoothPAN_NAP,
+       kSortBluetoothPAN_U,
+       kSortThunderbolt,
+       kSortCarPlay,
        kSortBond,
+       kSortBridge,
        kSortVLAN,
        kSortUnknown
 };
 
 
+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 kSCNetworkInterfaceTypeBridge                = CFSTR("Bridge");
 const CFStringRef kSCNetworkInterfaceTypeEthernet      = CFSTR("Ethernet");
 const CFStringRef kSCNetworkInterfaceTypeFireWire      = CFSTR("FireWire");
 const CFStringRef kSCNetworkInterfaceTypeIEEE80211     = CFSTR("IEEE80211");   // IEEE 802.11, AirPort
+const CFStringRef kSCNetworkInterfaceTypeIPSec         = CFSTR("IPSec");
 const CFStringRef kSCNetworkInterfaceTypeIrDA          = CFSTR("IrDA");
 const CFStringRef kSCNetworkInterfaceTypeL2TP          = CFSTR("L2TP");
+const CFStringRef kSCNetworkInterfaceTypeLoopback      = CFSTR("Loopback");
 const CFStringRef kSCNetworkInterfaceTypeModem         = CFSTR("Modem");
 const CFStringRef kSCNetworkInterfaceTypePPP           = CFSTR("PPP");
 const CFStringRef kSCNetworkInterfaceTypePPTP          = CFSTR("PPTP");
 const CFStringRef kSCNetworkInterfaceTypeSerial                = CFSTR("Serial");
 const CFStringRef kSCNetworkInterfaceTypeVLAN          = CFSTR("VLAN");
+const CFStringRef kSCNetworkInterfaceTypeVPN           = CFSTR("VPN");
 const CFStringRef kSCNetworkInterfaceTypeWWAN          = CFSTR("WWAN");
 
 const CFStringRef kSCNetworkInterfaceTypeIPv4          = CFSTR("IPv4");
 
-static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4      = {
-       INIT_CFRUNTIME_BASE(NULL, 0, 0x0080),   // cfBase
-       NULL,                                   // interface type
-       NULL,                                   // name
-       NULL,                                   // localized name
-       NULL,                                   // localization key
-       NULL,                                   // localization arg1
-       NULL,                                   // localization arg2
-       NULL,                                   // [layered] interface
-       NULL,                                   // prefs
-       NULL,                                   // serviceID
-       NULL,                                   // unsaved
-       NULL,                                   // entity_device
-       NULL,                                   // entity_type
-       NULL,                                   // entity_subtype
-       NULL,                                   // supported_interface_types
-       NULL,                                   // supported_protocol_types
-       NULL,                                   // address
-       NULL,                                   // addressString
-       FALSE,                                  // builtin
-       NULL,                                   // location
-       NULL,                                   // path
-       NULL,                                   // overrides
-       FALSE,                                  // modemIsV92
-       FALSE,                                  // supportsBond
-       FALSE,                                  // supportsVLAN
-       NULL,                                   // type
-       NULL,                                   // unit
-       kSortUnknown,                           // sort_order
-       { NULL, NULL},                          // bond { interfaces, options }
-       { NULL, NULL, NULL }                    // vlan { interface, tag, options }
+static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4     = {
+       .cfBase         = INIT_CFRUNTIME_BASE(),        // cfBase
+       .sort_order     = kSortUnknown,                 // sort_order
 };
 
-const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4     = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceIPv4;
+const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4    = (SCNetworkInterfaceRef)&__kSCNetworkInterfaceIPv4;
+
+static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback = {
+       .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
@@ -166,13 +222,18 @@ const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4     = (SCNetworkInterfaceRef
 #define doL2TP         1<<1
 #define doPPP          1<<2
 #define doPPTP         1<<3
+#define doIPSec                1<<4
+#define doOverIP       do6to4|doL2TP|doPPTP|doIPSec
 
-#define doAppleTalk     1<<0
 #define doDNS          1<<1
 #define doIPv4         1<<2
 #define doIPv6         1<<3
 #define doProxies       1<<4
+#if    !TARGET_OS_IPHONE
 #define doSMB          1<<5
+#else  // !TARGET_OS_IPHONE
+#define doSMB          0
+#endif // !TARGET_OS_IPHONE
 
 static const struct {
        const CFStringRef       *interface_type;
@@ -182,27 +243,47 @@ static const struct {
        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,                                   doAppleTalk|doDNS|doIPv4|doIPv6|doProxies|doSMB },
-       { &kSCNetworkInterfaceTypeEthernet      , &kSCEntNetEthernet, TRUE ,    doPPP,                  &kSCValNetInterfaceSubTypePPPoE,        doAppleTalk|doDNS|doIPv4|doIPv6|doProxies|doSMB },
-       { &kSCNetworkInterfaceTypeFireWire      , &kSCEntNetFireWire, TRUE ,    doNone,                 NULL,                                   doDNS|doIPv4|doIPv6|doProxies|doSMB             },
-       { &kSCNetworkInterfaceTypeIEEE80211     , &kSCEntNetAirPort , TRUE ,    doPPP,                  &kSCValNetInterfaceSubTypePPPoE,        doAppleTalk|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,                                   doAppleTalk|doDNS|doIPv4|doIPv6|doProxies|doSMB },
-       { &kSCNetworkInterfaceTypeWWAN          , &kSCEntNetModem   , FALSE,    doPPP,                  &kSCValNetInterfaceSubTypePPPSerial,    doNone                                          },
-       // =====================================  =================  ========== ======================= ======================================= =========================================
-       { &kSCNetworkInterfaceTypeIPv4          , NULL              , FALSE,    do6to4|doL2TP|doPPTP,   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;
 
@@ -211,27 +292,33 @@ static CFTypeID __kSCNetworkInterfaceTypeID       = _kCFRuntimeNotATypeID;
 
 
 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;
@@ -241,6 +328,9 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
        CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkInterface %p [%p]> {"), cf, allocator);
        CFStringAppendFormat(result, NULL, CFSTR("type = %@"), interfacePrivate->interface_type);
        CFStringAppendFormat(result, NULL, CFSTR(", entity_device = %@"), interfacePrivate->entity_device);
+       if (interfacePrivate->entity_device_unique != NULL) {
+               CFStringAppendFormat(result, NULL, CFSTR("+%@"), interfacePrivate->entity_device_unique);
+       }
        CFStringAppendFormat(result, NULL, CFSTR(", entity_type = %@"), interfacePrivate->entity_type);
        if (interfacePrivate->entity_subtype != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(" / %@"), interfacePrivate->entity_subtype);
@@ -266,34 +356,81 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                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->modemIsV92) {
-               CFStringAppendFormat(result, NULL, CFSTR(", v.92"));
+       if (interfacePrivate->hidden) {
+               CFStringAppendFormat(result, NULL, CFSTR(", hidden = TRUE"));
+       }
+#if    TARGET_OS_IPHONE
+       if (interfacePrivate->trustRequired) {
+               CFStringAppendFormat(result, NULL, CFSTR(", trust required = TRUE"));
        }
+#endif // TARGET_OS_IPHONE
        if (interfacePrivate->location != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", location = %@"), interfacePrivate->location);
        }
+       if (interfacePrivate->path != NULL) {
+               CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path);
+       }
+       if (interfacePrivate->entryID != 0) {
+               CFStringAppendFormat(result, NULL, CFSTR(", entryID = 0x%llx"), interfacePrivate->entryID);
+       }
        if (interfacePrivate->type != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", type = %@"), interfacePrivate->type);
        }
        if (interfacePrivate->unit != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
        }
-       if (interfacePrivate->path != NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path);
+       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     = 0;
+               int     vid     = 0;
+
+               if (!isA_CFNumber(interfacePrivate->usb.pid) ||
+                   !CFNumberGetValue(interfacePrivate->usb.pid, kCFNumberIntType, &pid)) {
+                       pid = 0;
+               }
+               if (!isA_CFNumber(interfacePrivate->usb.vid) ||
+                   !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid)) {
+                       vid = 0;
+               }
+
+               if (interfacePrivate->usb.name != NULL) {
+                       CFStringAppendFormat(result, NULL, CFSTR(", USB name = %@"),
+                                            interfacePrivate->usb.name);
+               }
+
+               CFStringAppendFormat(result, NULL, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
+                                    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);
        }
@@ -304,8 +441,9 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                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) {
                CFIndex i;
                CFIndex n;
@@ -317,7 +455,7 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                        member = CFArrayGetValueAtIndex(interfacePrivate->bond.interfaces, i);
                        CFStringAppendFormat(result, NULL,
                                             CFSTR("%s%@"),
-                                            (i == 0) ? ", interfaces = " : ", ",
+                                            (i == 0) ? ", interfaces = " : ",",
                                             SCNetworkInterfaceGetBSDName(member));
                }
        }
@@ -325,11 +463,36 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                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->bond.mode != NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR(", mode = %@"), interfacePrivate->bond.mode);
+
+       if (interfacePrivate->bridge.interfaces != NULL) {
+               CFIndex i;
+               CFIndex n;
+
+               n = CFArrayGetCount(interfacePrivate->bridge.interfaces);
+               for (i = 0; i < n; i++) {
+                       SCNetworkInterfaceRef   member;
+
+                       member = CFArrayGetValueAtIndex(interfacePrivate->bridge.interfaces, i);
+                       CFStringAppendFormat(result, NULL,
+                                            CFSTR("%s%@"),
+                                            (i == 0) ? ", interfaces = " : ",",
+                                            SCNetworkInterfaceGetBSDName(member));
+               }
+       }
+       if (interfacePrivate->bridge.options != NULL) {
+               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(", interface = %@"),
@@ -339,8 +502,13 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
                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("}"));
 
        return result;
@@ -354,9 +522,6 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
 
        /* release resources */
 
-       if (interfacePrivate->interface != NULL)
-               CFRelease(interfacePrivate->interface);
-
        if (interfacePrivate->name != NULL)
                CFRelease(interfacePrivate->name);
 
@@ -369,9 +534,15 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->localized_arg2 != NULL)
                CFRelease(interfacePrivate->localized_arg2);
 
+       if (interfacePrivate->interface != NULL)
+               CFRelease(interfacePrivate->interface);
+
        if (interfacePrivate->prefs != NULL)
                CFRelease(interfacePrivate->prefs);
 
+       if (interfacePrivate->store != NULL)
+               CFRelease(interfacePrivate->store);
+
        if (interfacePrivate->serviceID != NULL)
                CFRelease(interfacePrivate->serviceID);
 
@@ -381,6 +552,9 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->entity_device != NULL)
                CFRelease(interfacePrivate->entity_device);
 
+       if (interfacePrivate->entity_device_unique != NULL)
+               CFRelease(interfacePrivate->entity_device_unique);
+
        if (interfacePrivate->supported_interface_types != NULL)
                CFRelease(interfacePrivate->supported_interface_types);
 
@@ -393,6 +567,9 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->addressString != NULL)
                CFRelease(interfacePrivate->addressString);
 
+       if (interfacePrivate->configurationAction != NULL)
+               CFRelease(interfacePrivate->configurationAction);
+
        if (interfacePrivate->location != NULL)
                CFRelease(interfacePrivate->location);
 
@@ -402,12 +579,30 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        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->usb.pid != NULL)
+               CFRelease(interfacePrivate->usb.pid);
+
+       if (interfacePrivate->usb.vid != NULL)
+               CFRelease(interfacePrivate->usb.vid);
+
        if (interfacePrivate->bond.interfaces != NULL)
                CFRelease(interfacePrivate->bond.interfaces);
 
@@ -417,6 +612,12 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->bond.options != NULL)
                CFRelease(interfacePrivate->bond.options);
 
+       if (interfacePrivate->bridge.interfaces != NULL)
+               CFRelease(interfacePrivate->bridge.interfaces);
+
+       if (interfacePrivate->bridge.options != NULL)
+               CFRelease(interfacePrivate->bridge.options);
+
        if (interfacePrivate->vlan.interface != NULL)
                CFRelease(interfacePrivate->vlan.interface);
 
@@ -425,7 +626,10 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
 
        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;
 }
 
@@ -447,6 +651,21 @@ __SCNetworkInterfaceEqual(CFTypeRef cf1, CFTypeRef cf2)
                return FALSE; // if not the same device
        }
 
+       if ((if1->entity_device_unique != NULL) && (if2->entity_device_unique != NULL)) {
+               if (!_SC_CFEqual(if1->entity_device_unique, if2->entity_device_unique)) {
+                       return FALSE; // if not the same device unique identifier
+               }
+       } else if ((if1->entity_device_unique != NULL) || (if2->entity_device_unique != NULL)) {
+               CFStringRef     name1;
+               CFStringRef     name2;
+
+               name1 = __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef)if1);
+               name2 = __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef)if2);
+               if ((name1 != NULL) && (name2 != NULL) && !_SC_CFEqual(name1, name2)) {
+                       return FALSE; // if same device but not the same display name
+               }
+       }
+
        if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeBond)) {
                if (!_SC_CFEqual(if1->bond.interfaces, if2->bond.interfaces)) {
                        return FALSE; // if not the same interfaces
@@ -456,6 +675,12 @@ __SCNetworkInterfaceEqual(CFTypeRef cf1, CFTypeRef cf2)
                }
        }
 
+       if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeBridge)) {
+               if (!_SC_CFEqual(if1->bridge.interfaces, if2->bridge.interfaces)) {
+                       return FALSE; // if not the same interfaces
+               }
+       }
+
        if (CFEqual(if1->interface_type, kSCNetworkInterfaceTypeVLAN)) {
                if (!_SC_CFEqual(if1->vlan.interface, if2->vlan.interface)) {
                        return FALSE;   // if not the same physical interface
@@ -465,7 +690,7 @@ __SCNetworkInterfaceEqual(CFTypeRef cf1, CFTypeRef cf2)
                }
        }
 
-       if (!CFEqual(if1->interface, if2->interface)) {
+       if (!_SC_CFEqual(if1->interface, if2->interface)) {
                return FALSE;   // if not the same layering
        }
 
@@ -476,13 +701,24 @@ __SCNetworkInterfaceEqual(CFTypeRef cf1, CFTypeRef cf2)
 static CFHashCode
 __SCNetworkInterfaceHash(CFTypeRef cf)
 {
+       CFHashCode                      hash                    = 0;
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)cf;
 
        if (interfacePrivate->entity_device != NULL) {
-               return CFHash(interfacePrivate->entity_device);
+               if (interfacePrivate->entity_device_unique == NULL) {
+                       hash = CFHash(interfacePrivate->entity_device);
+               } else {
+                       CFStringRef     str;
+
+                       str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@+%@"),
+                                                      interfacePrivate->entity_device,
+                                                      interfacePrivate->entity_device_unique);
+                       hash = CFHash(str);
+                       CFRelease(str);
+               }
        }
 
-       return 0;
+       return hash;
 }
 
 
@@ -495,19 +731,24 @@ __SCNetworkInterfaceInitialize(void)
        __kSCNetworkInterfaceTypeID = _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass);
 
        // initialize __kSCNetworkInterfaceIPv4
-       _CFRuntimeSetInstanceTypeID(&__kSCNetworkInterfaceIPv4, __kSCNetworkInterfaceTypeID);
+       _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4, __kSCNetworkInterfaceTypeID);
        __kSCNetworkInterfaceIPv4.interface_type = kSCNetworkInterfaceTypeIPv4;
        __kSCNetworkInterfaceIPv4.localized_key  = CFSTR("ipv4");
 
+       // initialize __kSCNetworkInterfaceLoopback
+       _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback, __kSCNetworkInterfaceTypeID);
+       __kSCNetworkInterfaceLoopback.interface_type = kSCNetworkInterfaceTypeLoopback;
+       __kSCNetworkInterfaceLoopback.localized_key  = CFSTR("loopback");
+       __kSCNetworkInterfaceLoopback.entity_device  = CFRetain(CFSTR("lo0"));
+       __kSCNetworkInterfaceLoopback.entity_type    = kSCValNetInterfaceTypeLoopback;
+
        // get CFBundleRef for SystemConfiguration.framework
        bundle = _SC_CFBundleGet();
 
        // 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;
@@ -519,8 +760,7 @@ SCNetworkInterfacePrivateRef
 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef       allocator,
                                  SCNetworkInterfaceRef interface,
                                  SCPreferencesRef      prefs,
-                                 CFStringRef           serviceID,
-                                 io_string_t           path)
+                                 CFStringRef           serviceID)
 {
        SCNetworkInterfacePrivateRef            interfacePrivate;
        uint32_t                                size;
@@ -538,40 +778,11 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef  allocator,
                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->serviceID                     = (serviceID != NULL) ? CFRetain(serviceID) : NULL;
-       interfacePrivate->unsaved                       = NULL;
-       interfacePrivate->entity_device                 = 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->path                          = (path != NULL) ? CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8)
-                                                                        : NULL;
-       interfacePrivate->location                      = NULL;
-       interfacePrivate->overrides                     = NULL;
-       interfacePrivate->modemIsV92                    = FALSE;
-       interfacePrivate->supportsBond                  = FALSE;
-       interfacePrivate->supportsVLAN                  = FALSE;
-       interfacePrivate->type                          = NULL;
-       interfacePrivate->unit                          = NULL;
-       interfacePrivate->sort_order                    = kSortUnknown;
-       interfacePrivate->bond.interfaces               = NULL;
-       interfacePrivate->bond.mode                     = NULL;
-       interfacePrivate->bond.options                  = NULL;
-       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;
 }
@@ -608,17 +819,18 @@ __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if)
        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;
        }
 
        // check the link type and hwassist flags
-       ifm = (struct if_msghdr *)buf;
+       // ALIGN: buf is aligned
+       ifm = (struct if_msghdr *)(void *)buf;
        switch (ifm->ifm_type) {
                case RTM_IFINFO : {
 #if    defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
@@ -641,6 +853,48 @@ __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if)
 }
 
 
+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,
@@ -648,14 +902,15 @@ _SCBondInterfaceCreatePrivate(CFAllocatorRef      allocator,
 {
        SCNetworkInterfacePrivateRef    interfacePrivate;
 
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL, NULL);
+       interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL);
        if (interfacePrivate == NULL) {
                return NULL;
        }
 
        interfacePrivate->interface_type        = kSCNetworkInterfaceTypeBond;
-       interfacePrivate->entity_type           = kSCEntNetEthernet;
+       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;
@@ -671,6 +926,36 @@ _SCBondInterfaceCreatePrivate(CFAllocatorRef       allocator,
 }
 
 
+__private_extern__
+SCNetworkInterfacePrivateRef
+_SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator,
+                               CFStringRef     bridge_if)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate;
+
+       interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL);
+       if (interfacePrivate == NULL) {
+               return NULL;
+       }
+
+       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->localized_key         = CFSTR("bridge");
+       interfacePrivate->localized_arg1        = CFRetain(interfacePrivate->entity_device);
+
+       interfacePrivate->bridge.interfaces     = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
+//     interfacePrivate->bridge.options        = NULL;
+
+       return interfacePrivate;
+}
+
+
 __private_extern__
 SCNetworkInterfacePrivateRef
 _SCVLANInterfaceCreatePrivate(CFAllocatorRef           allocator,
@@ -678,14 +963,15 @@ _SCVLANInterfaceCreatePrivate(CFAllocatorRef              allocator,
 {
        SCNetworkInterfacePrivateRef    interfacePrivate;
 
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL, NULL);
+       interfacePrivate = __SCNetworkInterfaceCreatePrivate(allocator, NULL, NULL, NULL);
        if (interfacePrivate == NULL) {
                return NULL;
        }
 
        interfacePrivate->interface_type        = kSCNetworkInterfaceTypeVLAN;
-       interfacePrivate->entity_type           = kSCEntNetEthernet;
+       interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
        interfacePrivate->entity_device         = CFStringCreateCopy(allocator, vlan_if);
+       interfacePrivate->address               = __SCCopyMacAddress(interfacePrivate->entity_device);
        interfacePrivate->builtin               = TRUE;
        interfacePrivate->sort_order            = kSortVLAN;
 
@@ -704,7 +990,7 @@ _SCVLANInterfaceCreatePrivate(CFAllocatorRef                allocator,
 #pragma mark Interface ordering
 
 
-static CFArrayRef
+static CF_RETURNS_RETAINED CFArrayRef
 split_path(CFStringRef path)
 {
        CFArrayRef              components;
@@ -729,6 +1015,7 @@ split_path(CFStringRef path)
 CFComparisonResult
 _SCNetworkInterfaceCompare(const void *val1, const void *val2, void *context)
 {
+#pragma unused(context)
        SCNetworkInterfacePrivateRef    dev1            = (SCNetworkInterfacePrivateRef)val1;
        SCNetworkInterfacePrivateRef    dev2            = (SCNetworkInterfacePrivateRef)val2;
        CFComparisonResult              res             = kCFCompareEqualTo;
@@ -851,9 +1138,20 @@ _SCNetworkInterfaceCompare(const void *val1, const void *val2, void *context)
                }
        }
 
-       /* ... and lastly, sort by BSD interface name */
+       /* ... and, then sort by BSD interface name */
        if ((dev1->entity_device != NULL) && (dev2->entity_device != NULL)) {
                res = CFStringCompare(dev1->entity_device, dev2->entity_device, 0);
+               if (res != kCFCompareEqualTo) {
+                       return (res);
+               }
+       }
+
+       /* ... and lastly, sort by BSD interface unique identifier */
+       if ((dev1->entity_device_unique != NULL) && (dev2->entity_device_unique != NULL)) {
+               res = CFStringCompare(dev1->entity_device_unique, dev2->entity_device_unique, 0);
+//             if (res != kCFCompareEqualTo) {
+//                     return (res);
+//             }
        }
 
        return res;
@@ -863,8 +1161,9 @@ _SCNetworkInterfaceCompare(const void *val1, const void *val2, void *context)
 static void
 sort_interfaces(CFMutableArrayRef all_interfaces)
 {
-       int     n       = CFArrayGetCount(all_interfaces);
+       CFIndex         n;
 
+       n = CFArrayGetCount(all_interfaces);
        if (n < 2) {
                return;
        }
@@ -905,6 +1204,34 @@ IOCopyCFStringValue(CFTypeRef ioVal)
 }
 
 
+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)
 {
@@ -920,7 +1247,7 @@ IOStringValueHasPrefix(CFTypeRef ioVal, CFStringRef prefix)
 {
        Boolean         match           = FALSE;
        CFIndex         prefixLen       = CFStringGetLength(prefix);
-       CFStringRef     str             = ioVal;
+       CFStringRef     str             = NULL;
 
        if (!isA_CFString(ioVal)) {
                if (isA_CFData(ioVal)) {
@@ -928,21 +1255,22 @@ IOStringValueHasPrefix(CFTypeRef ioVal, CFStringRef prefix)
                                                              (const char *)CFDataGetBytePtr(ioVal),
                                                              kCFStringEncodingUTF8,
                                                              kCFAllocatorNull);
+                       ioVal = str;
                } else {
                        return FALSE;
                }
        }
 
-       if ((str != NULL) &&
-           (CFStringGetLength(str) >= prefixLen) &&
-           (CFStringCompareWithOptions(str,
+       if ((ioVal != NULL) &&
+           (CFStringGetLength(ioVal) >= prefixLen) &&
+           (CFStringCompareWithOptions(ioVal,
                                        prefix,
                                        CFRangeMake(0, prefixLen),
                                        kCFCompareCaseInsensitive) == kCFCompareEqualTo)) {
                match = TRUE;
        }
 
-       if (str != ioVal)       CFRelease(str);
+       if (str != NULL) CFRelease(str);
        return match;
 }
 
@@ -977,7 +1305,14 @@ static const struct {
 };
 
 
-static CFStringRef
+static const CFStringRef       slot_prefixes[] = {
+       CFSTR("thunderbolt slot "),
+       CFSTR("pci slot "),
+       CFSTR("slot-"),
+};
+
+
+static CF_RETURNS_RETAINED CFStringRef
 pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
 {
        kern_return_t           kr;
@@ -990,8 +1325,6 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
 
        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);
@@ -1003,15 +1336,20 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
                                              kCFStringEncodingUTF8);
                }
 
-               if (CFStringGetLength(slot) > 5) {
-                       (void) CFStringFindAndReplace(slot,
-                                                     CFSTR("slot-"),
-                                                     CFSTR(""),
-                                                     CFRangeMake(0, 5),
-                                                     kCFCompareCaseInsensitive|kCFCompareAnchored);
+               for (size_t i = 0; i < sizeof(slot_prefixes)/sizeof(slot_prefixes[0]); i++) {
+                       CFIndex         len;
+
+                       len = CFStringGetLength(slot_prefixes[i]);
+                       if (CFStringGetLength(slot) > len) {
+                               (void) CFStringFindAndReplace(slot,
+                                                             slot_prefixes[i],
+                                                             CFSTR(""),
+                                                             CFRangeMake(0, len),
+                                                             kCFCompareCaseInsensitive|kCFCompareAnchored);
+                       }
                }
 
-               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) {
@@ -1039,7 +1377,7 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
                                        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);
                                }
                        }
 
@@ -1050,7 +1388,7 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *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;
        }
 
@@ -1061,6 +1399,7 @@ pci_slot(io_registry_entry_t interface, CFTypeRef *pci_slot_name)
 static CFComparisonResult
 compare_bsdNames(const void *val1, const void *val2, void *context)
 {
+#pragma unused(context)
        CFStringRef     bsd1    = (CFStringRef)val1;
        CFStringRef     bsd2    = (CFStringRef)val2;
 
@@ -1068,8 +1407,8 @@ compare_bsdNames(const void *val1, const void *val2, void *context)
 }
 
 
-static CFStringRef
-pci_port(CFTypeRef slot_name, CFStringRef bsdName)
+static CF_RETURNS_RETAINED CFStringRef
+pci_port(CFTypeRef slot_name, int ift, CFStringRef bsdName)
 {
        CFIndex                 n;
        CFStringRef             port_name       = NULL;
@@ -1110,7 +1449,7 @@ pci_port(CFTypeRef slot_name, CFStringRef bsdName)
 
        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;
        }
 
@@ -1125,21 +1464,40 @@ pci_port(CFTypeRef slot_name, CFStringRef bsdName)
                                                   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)) {
-                               CFStringRef     if_bsdName;
+                               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;
+                                               }
+                                       }
 
-                               if_bsdName = IORegistryEntryCreateCFProperty(child,
-                                                                            CFSTR(kIOBSDNameKey),
-                                                                            NULL,
-                                                                            0);
-                               if (if_bsdName != NULL) {
-                                       CFArrayAppendValue(port_names, if_bsdName);
-                                       CFRelease(if_bsdName);
+                                       if (ift == child_ift) {
+                                               CFStringRef     if_bsdName;
+
+                                               if_bsdName = IODictionaryCopyBSDName(interface_dict);
+                                               if (if_bsdName != NULL) {
+                                                       CFArrayAppendValue(port_names, if_bsdName);
+                                                       CFRelease(if_bsdName);
+                                               }
+                                       }
+
+                                       CFRelease(interface_dict);
                                }
                        }
                        IOObjectRelease(child);
@@ -1154,7 +1512,7 @@ pci_port(CFTypeRef slot_name, CFStringRef bsdName)
                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);
                }
        }
 
@@ -1164,16 +1522,22 @@ pci_port(CFTypeRef slot_name, CFStringRef bsdName)
 
 
 static Boolean
-pci_slot_info(io_registry_entry_t interface, CFStringRef *slot_name, CFStringRef *port_name)
+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;
        }
@@ -1181,7 +1545,7 @@ pci_slot_info(io_registry_entry_t interface, CFStringRef *slot_name, CFStringRef
        *slot_name = pci_slot(interface, &pci_slot_name);
        if (*slot_name != NULL) {
                if (pci_slot_name != NULL) {
-                       *port_name = pci_port(pci_slot_name, bsd_name);
+                       *port_name = pci_port(pci_slot_name, ift, bsd_name);
                        CFRelease(pci_slot_name);
                }
                ok = TRUE;
@@ -1208,95 +1572,372 @@ isBuiltin(io_registry_entry_t interface)
 }
 
 
-#pragma mark -
-#pragma mark Interface enumeration
+static Boolean
+isBluetoothBuiltin(Boolean *haveController)
+{
+       Boolean         builtin         = FALSE;
+       io_object_t     hciController;
+       io_iterator_t   iter            = MACH_PORT_NULL;
+       kern_return_t   kr;
+
+       kr = IOServiceGetMatchingServices(masterPort,
+                                         IOServiceMatching("IOBluetoothHCIController"),
+                                         &iter);
+       if ((kr != kIOReturnSuccess) || (iter == MACH_PORT_NULL)) {
+               if (kr != kIOReturnSuccess) {
+                       SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
+               }
+               *haveController = FALSE;
+               return FALSE;
+       }
+       *haveController = TRUE;
 
+       hciController = IOIteratorNext(iter);
+       IOObjectRelease(iter);
+       if(hciController != MACH_PORT_NULL) {
+#if    !TARGET_OS_SIMULATOR
+               CFNumberRef     idVendor;
 
-typedef Boolean (*processInterface)(SCNetworkInterfacePrivateRef       interfacePrivate,
-                                   io_registry_entry_t                 interface,
-                                   CFDictionaryRef                     interface_dict,
-                                   io_registry_entry_t                 controller,
-                                   CFDictionaryRef                     controller_dict,
-                                   io_registry_entry_t                 bus,
-                                   CFDictionaryRef                     bus_dict);
+               idVendor = IORegistryEntryCreateCFProperty(hciController, CFSTR(kUSBVendorID), NULL, 0);
+               if (idVendor != NULL) {
+                       int     idVendorVal;
+
+                       if (isA_CFNumber(idVendor) &&
+                           CFNumberGetValue(idVendor, kCFNumberIntType, &idVendorVal) &&
+                           (idVendorVal == kIOUSBVendorIDAppleComputer)) {
+                               builtin = TRUE;
+                       }
+
+                       CFRelease(idVendor);
+               }
+#endif // !TARGET_OS_SIMULATOR
+
+               IOObjectRelease(hciController);
+       }
+
+       return builtin;
+}
 
 
 static Boolean
-processNetworkInterface(SCNetworkInterfacePrivateRef   interfacePrivate,
-                       io_registry_entry_t             interface,
-                       CFDictionaryRef                 interface_dict,
-                       io_registry_entry_t             controller,
-                       CFDictionaryRef                 controller_dict,
-                       io_registry_entry_t             bus,
-                       CFDictionaryRef                 bus_dict)
+isThunderbolt(io_registry_entry_t interface)
 {
-       CFBooleanRef    bVal;
-       CFDataRef       data;
-       int             ift     = -1;
-       int             iVal;
-       CFNumberRef     num;
-       CFStringRef     str;
+       CFTypeRef       val;
 
-       // interface type
-       num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType));
-       if (isA_CFNumber(num) &&
-           CFNumberGetValue(num, kCFNumberIntType, &ift)) {
-               interfacePrivate->type = CFRetain(num);
-       } else {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("processNetworkInterface() failed, no interface type"));
-               return FALSE;
+       val = IORegistryEntrySearchCFProperty(interface,
+                                             kIOServicePlane,
+                                             CFSTR(kPCIThunderboltString),
+                                             NULL,
+                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+       if (val != NULL) {
+               CFRelease(val);
+               return TRUE;
        }
 
-       switch (ift) {
-               case IFT_ETHER :
-                       // Type, Hardware
+       return FALSE;
+}
 
-                       if ((IOObjectConformsTo(controller, "IO80211Controller")) ||
-                           (IOObjectConformsTo(controller, "AirPortPCI"       )) ||
-                           (IOObjectConformsTo(controller, "AirPortDriver"    ))) {
-                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeIEEE80211;
-                               interfacePrivate->entity_type           = kSCEntNetEthernet;
-                               interfacePrivate->sort_order            = kSortAirPort;
-                       } else if (IOObjectConformsTo(controller, "IOBluetoothBNEPDriver")) {
-                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
-                               interfacePrivate->entity_type           = kSCEntNetEthernet;
-                               interfacePrivate->sort_order            = kSortBluetoothPAN;
-                       } else {
-                               str = IODictionaryCopyCFStringValue(bus_dict, CFSTR("name"));
-                               if ((str != NULL) && CFEqual(str, CFSTR("radio"))) {
-                                       interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;      // ??
-                                       interfacePrivate->entity_type           = kSCEntNetEthernet;
-                                       interfacePrivate->sort_order            = kSortOtherWireless;
-                               } else {
-                                       interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
-                                       interfacePrivate->entity_type           = kSCEntNetEthernet;
-                                       interfacePrivate->sort_order            = kSortEthernet;
 
-                                       // BOND support only enabled for ethernet devices
-                                       interfacePrivate->supportsBond = TRUE;
-                               }
+static void
+processUSBInterface(SCNetworkInterfacePrivateRef       interfacePrivate,
+                   io_registry_entry_t                 interface,
+                   CFDictionaryRef                     interface_dict,
+                   io_registry_entry_t                 controller,
+                   CFDictionaryRef                     controller_dict,
+                   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
+       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
 
-                               if (str != NULL) CFRelease(str);
-                       }
+       return;
+}
 
-                       // built-in
-                       bVal = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOBuiltin)));
-                       if (bVal == NULL) {
-                               bVal = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOPrimaryInterface)));
-                       }
-                       if (bVal != NULL) {
-                               interfacePrivate->builtin = CFBooleanGetValue(bVal);
-                       } else {
-                               interfacePrivate->builtin = isBuiltin(interface);
-                       }
 
-                       // location
-                       interfacePrivate->location = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOLocation));
+static Boolean
+update_interface_name(SCNetworkInterfacePrivateRef     interfacePrivate,
+                     io_registry_entry_t               interface,
+                     Boolean                           useUSBInfo)
+{
+       Boolean         updated = FALSE;
+       CFTypeRef       val;
 
-                       // VLAN support
-                       num = CFDictionaryGetValue(controller_dict, CFSTR(kIOFeatures));
-                       if (isA_CFNumber(num) &&
-                           CFNumberGetValue(num, kCFNumberIntType, & iVal)) {
+       // check if a "Product Name" has been provided
+       val = IORegistryEntrySearchCFProperty(interface,
+                                             kIOServicePlane,
+                                             CFSTR(kIOPropertyProductNameKey),
+                                             NULL,
+                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+       if ((val == NULL) && useUSBInfo && (interfacePrivate->usb.name != NULL)) {
+               // else, use "USB Product Name" if available
+               val = CFRetain(interfacePrivate->usb.name);
+       }
+       if (val != NULL) {
+               CFStringRef     productName;
+
+               productName = IOCopyCFStringValue(val);
+               CFRelease(val);
+
+               if (productName != NULL) {
+                       if (CFStringGetLength(productName) > 0) {
+                               // if we have a [somewhat reasonable?] product name
+                               if (interfacePrivate->name != NULL) {
+                                       CFRelease(interfacePrivate->name);
+                               }
+                               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);
+                               }
+
+                               updated = TRUE;
+                       }
+
+                       CFRelease(productName);
+               }
+       }
+
+       return updated;
+}
+
+
+#pragma mark -
+#pragma mark Interface enumeration
+
+
+typedef Boolean (*processInterface)(SCNetworkInterfacePrivateRef       interfacePrivate,
+                                   io_registry_entry_t                 interface,
+                                   CFDictionaryRef                     interface_dict,
+                                   io_registry_entry_t                 controller,
+                                   CFDictionaryRef                     controller_dict,
+                                   io_registry_entry_t                 bus,
+                                   CFDictionaryRef                     bus_dict);
+
+
+static void
+merge_override(SCNetworkInterfacePrivateRef    interfacePrivate,
+              io_registry_entry_t              interface,
+              CFStringRef                      override)
+{
+       CFStringRef     key;
+       CFTypeRef       val;
+
+       key = CFStringCreateWithFormat(NULL, NULL, CFSTR("Device%@Overrides"), override);
+       val = IORegistryEntrySearchCFProperty(interface,
+                                             kIOServicePlane,
+                                             key,
+                                             NULL,
+                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+       CFRelease(key);
+       if (val != NULL) {
+               if (isA_CFDictionary(val)) {
+                       if (interfacePrivate->overrides == NULL) {
+                               interfacePrivate->overrides = CFDictionaryCreateMutable(NULL,
+                                                                                       0,
+                                                                                       &kCFTypeDictionaryKeyCallBacks,
+                                                                                       &kCFTypeDictionaryValueCallBacks);
+                       }
+                       CFDictionarySetValue(interfacePrivate->overrides, override, val);
+               }
+               CFRelease(val);
+       }
+
+       return;
+}
+
+
+static Boolean
+processNetworkInterface(SCNetworkInterfacePrivateRef   interfacePrivate,
+                       io_registry_entry_t             interface,
+                       CFDictionaryRef                 interface_dict,
+                       io_registry_entry_t             controller,
+                       CFDictionaryRef                 controller_dict,
+                       io_registry_entry_t             bus,
+                       CFDictionaryRef                 bus_dict)
+{
+       CFDataRef       data;
+       int             ift     = -1;
+       int             iVal;
+       CFNumberRef     num;
+       CFStringRef     str;
+       CFBooleanRef    val;
+
+       // interface type
+       num = CFDictionaryGetValue(interface_dict, CFSTR(kIOInterfaceType));
+       if (isA_CFNumber(num) &&
+           CFNumberGetValue(num, kCFNumberIntType, &ift)) {
+               interfacePrivate->type = CFRetain(num);
+       } else {
+               SC_log(LOG_INFO, "no interface type: %@", interface_dict);
+               return FALSE;
+       }
+
+       switch (ift) {
+               case IFT_ETHER :
+                       // Type, Hardware
+
+                       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;
+                               interfacePrivate->sort_order            = kSortBluetoothPAN_GN;
+                       } else if (IOObjectConformsTo(controller, "AppleUSBEthernetHost")) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortTethered;
+                       } else if (IOObjectConformsTo(controller, "AppleUSBCDCECMData")) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortWWANEthernet;
+                       }
+
+                       if (interfacePrivate->interface_type == NULL) {
+                               val = IORegistryEntrySearchCFProperty(interface,
+                                                                     kIOServicePlane,
+                                                                     CFSTR(kIOUserEthernetInterfaceRoleKey),
+                                                                     NULL,
+                                                                     kIORegistryIterateRecursively | kIORegistryIterateParents);
+                               if (val != NULL) {
+                                       if (isA_CFString(val)) {
+                                               if (CFEqual(val, CFSTR(BT_PAN_NAME))) {
+                                                       interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                                                       interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                                                       interfacePrivate->sort_order            = kSortBluetoothPAN_GN;
+                                               } else if (CFEqual(val, CFSTR("Bluetooth PAN-NAP"))) {
+                                                       interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                                                       interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                                                       interfacePrivate->sort_order            = kSortBluetoothPAN_NAP;
+                                               } else if (CFEqual(val, CFSTR("Bluetooth P2P"))) {
+                                                       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;
+                                               }
+                                       }
+
+                                       CFRelease(val);
+                               }
+                       }
+
+#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) {
+                                       if (CFEqual(str, CFSTR("radio"))) {
+                                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;      // ??
+                                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                                               interfacePrivate->sort_order            = kSortOtherWireless;
+                                       }
+
+                                       CFRelease(str);
+                               }
+                       }
+
+                       if (interfacePrivate->interface_type == NULL) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortEthernet;
+
+                               // BOND support only enabled for ethernet devices
+                               interfacePrivate->supportsBond = TRUE;
+                       }
+
+                       // enable Bridge support
+                       interfacePrivate->supportsBridge = TRUE;
+
+                       // built-in
+                       val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOBuiltin)));
+                       if (val == NULL) {
+                               val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOPrimaryInterface)));
+                       }
+                       if (val != NULL) {
+                               interfacePrivate->builtin = CFBooleanGetValue(val);
+                       } else {
+                               interfacePrivate->builtin = isBuiltin(interface);
+                       }
+
+                       if (!interfacePrivate->builtin &&
+                           CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
+                               // always treat AirPort interfaces as built-in
+                               interfacePrivate->builtin = TRUE;
+                       }
+
+                       // 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));
+                       if (isA_CFNumber(num) &&
+                           CFNumberGetValue(num, kCFNumberIntType, & iVal)) {
                                if (iVal & (kIONetworkFeatureHardwareVlan | kIONetworkFeatureSoftwareVlan)) {
                                        interfacePrivate->supportsVLAN = TRUE;
                                }
@@ -1305,8 +1946,20 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                        // localized name
                        if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211)) {
                                interfacePrivate->localized_key = CFSTR("airport");
-                       } else if (interfacePrivate->sort_order == kSortBluetoothPAN) {
-                               interfacePrivate->localized_key  = CFSTR("bluetooth-pan");
+                       } 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) {
+                               interfacePrivate->localized_key  = CFSTR("bluetooth-pan-nap");
+                       } else if (interfacePrivate->sort_order == kSortBluetoothPAN_U) {
+                               interfacePrivate->localized_key  = CFSTR("bluetooth-pan-u");
                        } else if (interfacePrivate->sort_order == kSortOtherWireless) {
                                interfacePrivate->localized_key  = CFSTR("wireless");
                                interfacePrivate->localized_arg1 = CFRetain(CFSTR(""));         // ??
@@ -1332,24 +1985,84 @@ processNetworkInterface(SCNetworkInterfacePrivateRef    interfacePrivate,
                                                CFStringRef             port_name;
                                                CFStringRef             slot_name;
 
-                                               if (pci_slot_info(interface, &slot_name, &port_name)) {
-                                                       if (port_name == NULL) {
-                                                               interfacePrivate->localized_key  = CFSTR("pci-ether");
-                                                               interfacePrivate->localized_arg1 = slot_name;
+                                               // set interface "name"
+                                               if (!update_interface_name(interfacePrivate, interface, FALSE) &&
+                                                   pci_slot_info(interface, ift, &slot_name, &port_name)) {
+                                                       if (isThunderbolt(interface)) {
+                                                               if (port_name == NULL) {
+                                                                       interfacePrivate->localized_key  = CFSTR("thunderbolt-ether");
+                                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                               } else {
+                                                                       interfacePrivate->localized_key  = CFSTR("thunderbolt-multiether");
+                                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                                       interfacePrivate->localized_arg2 = port_name;
+                                                               }
+
+                                                       } else {
+                                                               if (port_name == NULL) {
+                                                                       interfacePrivate->localized_key  = CFSTR("pci-ether");
+                                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                               } else {
+                                                                       interfacePrivate->localized_key  = CFSTR("pci-multiether");
+                                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                                       interfacePrivate->localized_arg2 = port_name;
+                                                               }
+                                                       }
+                                               }
+                                       } 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 {
-                                                               interfacePrivate->localized_key  = CFSTR("pci-multiether");
-                                                               interfacePrivate->localized_arg1 = slot_name;
-                                                               interfacePrivate->localized_arg2 = port_name;
+                                                               break;
                                                        }
+
+                                                       CFRelease(provider);
+                                                       provider = IORegistryEntrySearchCFProperty(node,
+                                                                                                  kIOServicePlane,
+                                                                                                  CFSTR(kIOProviderClassKey),
+                                                                                                  NULL,
+                                                                                                  kIORegistryIterateRecursively | kIORegistryIterateParents);
+                                               }
+
+                                               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);
                                }
                        }
 
@@ -1359,7 +2072,7 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                        interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
 
                        // Entity
-                       interfacePrivate->entity_type     = kSCEntNetFireWire;
+                       interfacePrivate->entity_type = kSCValNetInterfaceTypeFireWire;
 
                        // built-in
                        interfacePrivate->builtin = isBuiltin(interface);
@@ -1371,23 +2084,42 @@ processNetworkInterface(SCNetworkInterfacePrivateRef    interfacePrivate,
                        if (interfacePrivate->builtin) {
                                interfacePrivate->localized_key = CFSTR("firewire");
                        } else {
+                               CFStringRef     port_name;
                                CFStringRef     slot_name;
 
-                               slot_name = pci_slot(interface, NULL);
-                               if (slot_name != NULL) {
-                                       interfacePrivate->localized_key  = CFSTR("pci-firewire");
-                                       interfacePrivate->localized_arg1 = slot_name;
+                               // set interface "name"
+                               if (!update_interface_name(interfacePrivate, interface, FALSE) &&
+                                   pci_slot_info(interface, ift, &slot_name, &port_name)) {
+                                       if (isThunderbolt(interface)) {
+                                               if (port_name == NULL) {
+                                                       interfacePrivate->localized_key  = CFSTR("thunderbolt-firewire");
+                                                       interfacePrivate->localized_arg1 = slot_name;
+                                               } else {
+                                                       interfacePrivate->localized_key  = CFSTR("thunderbolt-multifirewire");
+                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                       interfacePrivate->localized_arg2 = port_name;
+                                               }
+                                       } else {
+                                               if (port_name == NULL) {
+                                                       interfacePrivate->localized_key  = CFSTR("pci-firewire");
+                                                       interfacePrivate->localized_arg1 = slot_name;
+                                               } else {
+                                                       interfacePrivate->localized_key  = CFSTR("pci-multifirewire");
+                                                       interfacePrivate->localized_arg1 = slot_name;
+                                                       interfacePrivate->localized_arg2 = port_name;
+                                               }
+                                       }
                                }
                        }
 
                        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));
@@ -1395,6 +2127,12 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                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) &&
@@ -1402,6 +2140,9 @@ processNetworkInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                interfacePrivate->unit = CFRetain(num);
        }
 
+       // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
+       merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypePPP);
+
        return TRUE;
 }
 
@@ -1451,18 +2192,18 @@ set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate, CFStringRef
 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;
 
@@ -1478,9 +2219,7 @@ is_valid_connection_script(CFStringRef script)
                                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)) {
@@ -1502,9 +2241,7 @@ is_valid_connection_script(CFStringRef script)
                                        continue;
                                }
 
-                               SCLog(TRUE, LOG_DEBUG,
-                                     CFSTR("processSerialInterface stat() failed: %s"),
-                                     strerror(errno));
+                               SC_log(LOG_INFO, "stat() failed: %s", strerror(errno));
                                continue;
                        }
                }
@@ -1527,29 +2264,52 @@ processSerialInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                       io_registry_entry_t              bus,
                       CFDictionaryRef                  bus_dict)
 {
+       CFStringRef             base            = NULL;
        CFStringRef             ift;
        Boolean                 isModem         = FALSE;
+       Boolean                 isWWAN          = FALSE;
        CFStringRef             modemCCL        = NULL;
-       CFStringRef             str;
+       Boolean                 ok              = FALSE;
        CFTypeRef               val;
 
-       // check if hidden
+       // check if initializing
+       val = IORegistryEntrySearchCFProperty(interface,
+                                             kIOServicePlane,
+                                             kSCNetworkInterfaceInitializingKey,
+                                             NULL,
+                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+       if (val != NULL) {
+               Boolean initializing;
+
+               initializing = isA_CFBoolean(val) && CFBooleanGetValue(val);
+               CFRelease(val);
+               if (initializing) {
+                       return FALSE;   // if this interface is still initializing
+               }
+       }
+
+       // check if WWAN
        val = IORegistryEntrySearchCFProperty(interface,
                                              kIOServicePlane,
-                                             CFSTR("HiddenPort"),
+                                             CFSTR("WWAN"),
                                              NULL,
                                              kIORegistryIterateRecursively | kIORegistryIterateParents);
        if (val != NULL) {
+               isWWAN = isA_CFBoolean(val) && CFBooleanGetValue(val);
                CFRelease(val);
-               return FALSE;   // if this interface should not be exposed
        }
 
-       // Type
-       str = CFDictionaryGetValue(interface_dict, CFSTR(kIOTTYBaseNameKey));
-       if (str == NULL) {
+       // Entity (Device)
+       interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYDeviceKey));
+       if (interfacePrivate->entity_device == NULL) {
                return FALSE;
        }
 
+       base = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYBaseNameKey));
+       if (base == NULL) {
+               base = CFRetain(interfacePrivate->entity_device);
+       }
+
        /*
         * From MoreSCF:
         *
@@ -1558,21 +2318,28 @@ processSerialInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
         * that only the rev A actually had an IrDA port, and Mac OS X doesn't
         * even support it, these ports definitely shouldn't be listed.
         */
-       if (CFStringCompare(str,
+       if (CFStringCompare(base,
                            CFSTR("irda"),
                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
-               return FALSE;
+               goto done;
        }
 
-       if (IOStringValueHasPrefix(str, CFSTR("bluetooth"))) {
+       if (IOStringValueHasPrefix(base, CFSTR("bluetooth"))) {
+               Boolean haveController  = FALSE;
+
                // Bluetooth
                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeBluetooth;
                interfacePrivate->sort_order            = kSortBluetooth;
-       } else if (IOStringValueHasPrefix(str, CFSTR("irda-ircomm"))) {
+               interfacePrivate->builtin               = isBluetoothBuiltin(&haveController);
+               if (!haveController) {
+                       // if device with no controller present
+                       goto done;
+               }
+       } else if (IOStringValueHasPrefix(base, CFSTR("irda-ircomm"))) {
                // IrDA
                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeIrDA;
                interfacePrivate->sort_order            = kSortIrDA;
-       } else if (IOStringValueHasPrefix(str, CFSTR("wwan"))) {
+       } else if (isWWAN) {
                // WWAN
                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeWWAN;
                interfacePrivate->sort_order            = kSortWWAN;
@@ -1580,22 +2347,6 @@ processSerialInterface(SCNetworkInterfacePrivateRef      interfacePrivate,
                // 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)
@@ -1604,70 +2355,54 @@ processSerialInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
        // Entity (Hardware)
        ift = CFDictionaryGetValue(interface_dict, CFSTR(kIOSerialBSDTypeKey));
        if (!isA_CFString(ift)) {
-               return FALSE;
+               goto done;
        }
 
        if (CFEqual(ift, CFSTR(kIOSerialBSDModemType))) {
                // if modem
                isModem = TRUE;
 
-               if (CFEqual(str, CFSTR("modem"))) {
+               if (CFEqual(base, CFSTR("modem"))) {
                        interfacePrivate->builtin = TRUE;
                        interfacePrivate->sort_order = kSortInternalModem;
-               } else if (CFEqual(str, CFSTR("usbmodem"))) {
+               } else if (CFEqual(base, CFSTR("usbmodem"))) {
                        interfacePrivate->sort_order = kSortUSBModem;
                }
        } else if (CFEqual(ift, CFSTR(kIOSerialBSDRS232Type))) {
                // if serial port
                interfacePrivate->sort_order = kSortSerialPort;
        } else {
-               return FALSE;
+               goto done;
        }
 
-       // Entity (Device)
-       interfacePrivate->entity_device = IODictionaryCopyCFStringValue(interface_dict, CFSTR(kIOTTYDeviceKey));
+       // configuration [PPP] template override   (now deprecated, use NetworkConfigurationOverrides)
+       merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypePPP);
 
-       // configuration template overrides
-       val = IORegistryEntrySearchCFProperty(interface,
-                                             kIOServicePlane,
-                                             CFSTR("DevicePPPOverrides"),
-                                             NULL,
-                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
-       if (val != NULL) {
-               if (isA_CFDictionary(val)) {
-                       if (interfacePrivate->overrides == NULL) {
-                               interfacePrivate->overrides = CFDictionaryCreateMutable(NULL,
-                                                                                       0,
-                                                                                       &kCFTypeDictionaryKeyCallBacks,
-                                                                                       &kCFTypeDictionaryValueCallBacks);
-                       }
-                       CFDictionarySetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypePPP, val);
-               }
-               CFRelease(val);
-       }
+       // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
+       merge_override(interfacePrivate, interface, kSCNetworkInterfaceTypeModem);
 
-       val = IORegistryEntrySearchCFProperty(interface,
-                                             kIOServicePlane,
-                                             CFSTR("DeviceModemOverrides"),
-                                             NULL,
-                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
-       if (val != NULL) {
-               if (isA_CFDictionary(val)) {
-                       if (interfacePrivate->overrides == NULL) {
-                               interfacePrivate->overrides = CFDictionaryCreateMutable(NULL,
-                                                                                       0,
-                                                                                       &kCFTypeDictionaryKeyCallBacks,
-                                                                                       &kCFTypeDictionaryValueCallBacks);
-                       }
-                       CFDictionarySetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem, val);
+       // look for modem CCL, unique identifier
+       if (interfacePrivate->overrides != NULL) {
+               val = CFDictionaryGetValue(interfacePrivate->overrides, kSCNetworkInterfaceTypeModem);
+               if (val != NULL) {
+                       CFStringRef     uniqueID;
 
                        modemCCL = CFDictionaryGetValue(val, kSCPropNetModemConnectionScript);
                        modemCCL = isA_CFString(modemCCL);
+
+                       uniqueID = CFDictionaryGetValue(val, CFSTR("UniqueIdentifier"));
+                       uniqueID = isA_CFString(uniqueID);
+                       if (uniqueID != NULL) {
+                               // retain the device's base name and the unique id
+                               CFRelease(interfacePrivate->entity_device);
+                               interfacePrivate->entity_device = CFRetain(base);
+                               interfacePrivate->entity_device_unique = CFStringCreateCopy(NULL, uniqueID);
+                       }
                }
-               CFRelease(val);
        }
 
-       // modem CCL
+       // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
+       // a bit harder for the modem CCL
        if (modemCCL == NULL) {
                val = IORegistryEntrySearchCFProperty(interface,
                                                      kIOServicePlane,
@@ -1695,7 +2430,7 @@ processSerialInterface(SCNetworkInterfacePrivateRef       interfacePrivate,
                CFStringRef             name            = NULL;
                CFMutableStringRef      port;
 
-               port = CFStringCreateMutableCopy(NULL, 0, str);
+               port = CFStringCreateMutableCopy(NULL, 0, base);
                CFStringLowercase(port, NULL);
 
                if (!isModem) {
@@ -1713,10 +2448,10 @@ processSerialInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                        } else {
                                // if no [English] localization available, use TTY base name
                                CFRelease(name);
-                               interfacePrivate->name = CFStringCreateCopy(NULL, str);
+                               interfacePrivate->name = CFStringCreateCopy(NULL, base);
                        }
                } else {
-                       interfacePrivate->name = CFStringCreateCopy(NULL, str);
+                       interfacePrivate->name = CFStringCreateCopy(NULL, base);
                }
 
                // set localized name
@@ -1730,47 +2465,29 @@ processSerialInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                        } else {
                                // if no localization available, use TTY base name
                                CFRelease(localized);
-                               interfacePrivate->localized_name = CFStringCreateCopy(NULL, str);
+                               interfacePrivate->localized_name = CFStringCreateCopy(NULL, base);
                        }
                } else {
-                       interfacePrivate->localized_name = CFStringCreateCopy(NULL, str);
+                       interfacePrivate->localized_name = CFStringCreateCopy(NULL, base);
                }
 
-               if (!isModem || !CFEqual(str, CFSTR("modem"))) {
-                       CFStringRef     productName;
-
-                       // check if a "Product Name" has been provided
-                       val = IORegistryEntrySearchCFProperty(interface,
-                                                             kIOServicePlane,
-                                                             CFSTR(kIOPropertyProductNameKey),
-                                                             NULL,
-                                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
-                       if (val != NULL) {
-                               productName = IOCopyCFStringValue(val);
-                               CFRelease(val);
-
-                               if (productName != NULL) {
-                                       if (CFStringGetLength(productName) > 0) {
-                                               // if we have a [somewhat reasonable?] product name
-                                               if (interfacePrivate->name != NULL) {
-                                                       CFRelease(interfacePrivate->name);
-                                               }
-                                               interfacePrivate->name = CFRetain(productName);
-                                               if (interfacePrivate->localized_name != NULL) {
-                                                       CFRelease(interfacePrivate->localized_name);
-                                               }
-                                               interfacePrivate->localized_name = CFRetain(productName);
-
-                                               // if not provided, also check if the product name
-                                               // matches a CCL script
-                                               if ((modemCCL == NULL) &&
-                                                   is_valid_connection_script(productName)) {
-                                                       set_connection_script(interfacePrivate, productName);
-                                                       modemCCL = productName;
-                                               }
-                                       }
-
-                                       CFRelease(productName);
+               if (!isModem || !CFEqual(base, CFSTR("modem"))) {
+                       // 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)) {
+                               // if "ModemCCL" not provided, also check if the product/interface
+                               // name matches a CCL script
+                               if ((modemCCL == NULL) &&
+                                   is_valid_connection_script(interfacePrivate->name)) {
+                                       set_connection_script(interfacePrivate, interfacePrivate->name);
                                }
                        }
                }
@@ -1778,65 +2495,239 @@ processSerialInterface(SCNetworkInterfacePrivateRef    interfacePrivate,
                CFRelease(port);
        }
 
-       return TRUE;
-}
-
+       ok = TRUE;
 
-static SCNetworkInterfaceRef
-createInterface(io_registry_entry_t interface, processInterface func)
-{
-       io_registry_entry_t             bus                     = MACH_PORT_NULL;
-       CFMutableDictionaryRef          bus_dict                = NULL;
-       io_registry_entry_t             controller              = MACH_PORT_NULL;
-       CFMutableDictionaryRef          controller_dict         = NULL;
-       SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
-       CFMutableDictionaryRef          interface_dict          = NULL;
-       kern_return_t                   kr;
-       io_string_t                     path;
+    done :
 
-       kr = IORegistryEntryGetPath(interface, kIOServicePlane, path);
-       if (kr != kIOReturnSuccess) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryGetPath() failed, kr = 0x%x"), kr);
-               goto done;
+       if (!ok && (interfacePrivate->entity_device != NULL)) {
+               CFRelease(interfacePrivate->entity_device);
+               interfacePrivate->entity_device = NULL;
        }
+       if (base != NULL) CFRelease(base);
 
-       kr = IORegistryEntryCreateCFProperties(interface, &interface_dict, NULL, kNilOptions);
-       if (kr != kIOReturnSuccess) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("createInterface IORegistryEntryCreateCFProperties() failed, kr = 0x%x"), kr);
-               goto done;
-       }
+       return ok;
+}
 
-       /* 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);
-               goto done;
+
+static CFStringRef
+__SC_IORegistryEntryCopyPath(io_registry_entry_t entry, const io_name_t plane)
+{
+       /*
+        * Create a path for a registry entry.
+        */
+       io_string_t     path;
+       IOReturn        status;
+       CFStringRef     str     = NULL;
+
+       status = IORegistryEntryGetPath(entry, plane, path);
+       if (status == kIOReturnSuccess) {
+               str = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
+       } else if (status == kIOReturnBadArgument) {
+               io_registry_entry_t     parent;
+
+               status = IORegistryEntryGetParentEntry(entry, plane, &parent);
+               if (status == kIOReturnSuccess) {
+                       CFStringRef     str_parent;
+
+                       str_parent = __SC_IORegistryEntryCopyPath(parent, plane);
+                       if (str_parent != NULL) {
+                               io_name_t       name;
+
+                               status = IORegistryEntryGetNameInPlane(entry, plane, name);
+                               if (status == kIOReturnSuccess) {
+                                       io_name_t       location;
+
+                                       status = IORegistryEntryGetLocationInPlane(entry, plane, location);
+                                       if (status == kIOReturnSuccess) {
+                                               str = CFStringCreateWithFormat(NULL,
+                                                                              NULL,
+                                                                              CFSTR("%@/%s@%s"),
+                                                                              str_parent,
+                                                                              name,
+                                                                              location);
+                                       } else {
+                                               str = CFStringCreateWithFormat(NULL,
+                                                                              NULL,
+                                                                              CFSTR("%@/%s"),
+                                                                              str_parent,
+                                                                              name);
+                                       }
+                               }
+
+                               CFRelease(str_parent);
+                       }
+
+                       IOObjectRelease(parent);
+               }
+       }
+
+       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,
+               CFStringRef hidden_key)
+{
+       io_registry_entry_t             bus                     = MACH_PORT_NULL;
+       CFMutableDictionaryRef          bus_dict                = NULL;
+       io_registry_entry_t             controller              = MACH_PORT_NULL;
+       CFMutableDictionaryRef          controller_dict         = NULL;
+       uint64_t                        entryID                 = 0;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
+       CFMutableDictionaryRef          interface_dict          = NULL;
+       kern_return_t                   kr;
+       CFTypeRef                       val;
+
+       // 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 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);
+        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 != kIOReturnSuccess) {
+               SC_log(LOG_INFO, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr);
                goto done;
        }
 
-       /* get the bus node */
+       controller_dict = copyIORegistryProperties(controller,
+                                                  controller_dict_keys,
+                                                  sizeof(controller_dict_keys)/sizeof(controller_dict_keys[0]));
+
+       // 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);
+       bus_dict = copyIORegistryProperties(bus,
+                                           bus_dict_keys,
+                                           sizeof(bus_dict_keys)/sizeof(bus_dict_keys[0]));
+
+       // get the registry entry ID
+       kr = IORegistryEntryGetRegistryEntryID(interface, &entryID);
+       if (kr != kIOReturnSuccess) {
+               SC_log(LOG_INFO, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr);
                goto done;
        }
 
-       interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL, path);
+       interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL);
+       assert(interfacePrivate != NULL);
+       interfacePrivate->path = __SC_IORegistryEntryCopyPath(interface, kIOServicePlane);
+       interfacePrivate->entryID = entryID;
+
+       // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
+       val = IORegistryEntrySearchCFProperty(interface,
+                                             kIOServicePlane,
+                                             kSCNetworkInterfaceNetworkConfigurationOverridesKey,
+                                             NULL,
+                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+       if (val != NULL) {
+               if (isA_CFDictionary(val)) {
+                       interfacePrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, val);
+               }
+               CFRelease(val);
+       }
+
+       if ((*func)(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict)) {
+               // get user-notification / auto-configuration preference
+               val = IORegistryEntrySearchCFProperty(interface,
+                                                     kIOServicePlane,
+                                                     kSCNetworkInterfaceConfigurationActionKey,
+                                                     NULL,
+                                                     kIORegistryIterateRecursively | kIORegistryIterateParents);
+               if (val != NULL) {
+                       if (isA_CFString(val)) {
+                               interfacePrivate->configurationAction = CFRetain(val);
+                       }
+                       CFRelease(val);
+               }
+
+               // get HiddenConfiguration preference
+               val = IORegistryEntrySearchCFProperty(interface,
+                                                     kIOServicePlane,
+                                                     kSCNetworkInterfaceHiddenConfigurationKey,
+                                                     NULL,
+                                                     kIORegistryIterateRecursively | kIORegistryIterateParents);
+               if (val != NULL) {
+                       interfacePrivate->hidden = TRUE;
+                       CFRelease(val);
+               }
 
-       if (!(*func)(interfacePrivate, interface, interface_dict, controller, controller_dict, bus, bus_dict)) {
+#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;
        }
@@ -1855,17 +2746,27 @@ createInterface(io_registry_entry_t interface, processInterface func)
 }
 
 
-static CFArrayRef
-findMatchingInterfaces(CFDictionaryRef matching, processInterface func)
+static CF_RETURNS_RETAINED CFArrayRef
+findMatchingInterfaces(CFDictionaryRef matching,
+                      processInterface func,
+                      CFStringRef      hidden_key,
+                      Boolean          keep_pre_configured)
 {
        CFMutableArrayRef       interfaces;
        io_registry_entry_t     interface;
        kern_return_t           kr;
        io_iterator_t           iterator        = MACH_PORT_NULL;
 
+       /*
+        * A reference to the "matching" dictionary will be consumed by the
+        * the call to IOServiceGetMatchingServices so we bump up the retain
+        * count.
+        */
+       CFRetain(matching);
+
        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;
        }
 
@@ -1874,9 +2775,11 @@ findMatchingInterfaces(CFDictionaryRef matching, processInterface func)
        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);
                }
 
@@ -1896,9 +2799,7 @@ findMatchingInterfaces(CFDictionaryRef matching, processInterface func)
 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;
                }
@@ -1947,6 +2848,7 @@ __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef        inter
        CFIndex                         extendedIndex;
        CFIndex                         interfaceIndex;
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       Boolean                         isL2TP                  = FALSE;
        Boolean                         ok                      = FALSE;
 
        defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
@@ -1967,26 +2869,48 @@ __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef      inter
                goto done;
        }
 
-//     It turns out that, for PPP interfaces, we want to be able to store
-//     some extended interface configuration (e.g. IPSec [for L2TP]).  For
-//     now, I'm commenting out the following test.
-//
-//     if (requirePerInterface && !configurations[interfaceIndex].per_interface_config) {
-//             // we don't allow per-service extended configurations
-//             goto done;
-//     }
+       if (CFEqual(extendedType, kSCEntNetIPSec)) {
+               CFStringRef     interfaceType;
+
+               interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+               if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
+                       SCNetworkInterfaceRef   child;
+
+                       child = SCNetworkInterfaceGetInterface(interface);
+                       if (child != NULL) {
+                               interfaceType = SCNetworkInterfaceGetInterfaceType(child);
+                               if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
+                                       isL2TP = TRUE;
+                               }
+                       }
+               }
+       }
+
+       if (requirePerInterface &&
+           !configurations[interfaceIndex].per_interface_config &&
+           !isL2TP) {
+               // we don't allow per-service extended configurations (except
+               // that we do allow IPSec as an extended type for PPP->L2TP)
+               goto done;
+       }
 
        extendedIndex = findConfiguration(extendedType);
-       if (extendedIndex != kCFNotFound) {
-               // extended type cannot match a known interface type
+       if ((extendedIndex != kCFNotFound) && !isL2TP) {
+               // extended type cannot match a known interface type (except
+               // that we do allow IPSec as an extended type for PPP->L2TP)
                goto done;
        }
 
        /*
         * ???
-        * 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?
         * ???
         */
 
@@ -2010,6 +2934,7 @@ typedef struct {
 static void
 __addExtendedConfigurationType(const void *key, const void *value, void *context)
 {
+#pragma unused(value)
        CFStringRef                     extendedType    = (CFStringRef)key;
        extendedConfigurationRef        myContextRef    = (extendedConfigurationRef)context;
 
@@ -2031,7 +2956,28 @@ __addExtendedConfigurationType(const void *key, const void *value, void *context
 }
 
 
-static CFArrayRef
+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)
 {
        CFIndex                         i;
@@ -2055,15 +3001,9 @@ 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;
        }
 
@@ -2124,42 +3064,23 @@ extendedConfigurationTypes(SCNetworkInterfaceRef interface)
        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
@@ -2187,20 +3108,53 @@ copyConfigurationPaths(SCNetworkInterfacePrivateRef     interfacePrivate,
                                                                                   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);
 }
 
 
@@ -2235,6 +3189,23 @@ __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface)
                                     kSCPropNetInterfaceDeviceName,
                                     interfacePrivate->entity_device);
        }
+       if (interfacePrivate->entity_device_unique != NULL) {
+               CFDictionarySetValue(entity,
+                                    CFSTR("DeviceUniqueIdentifier"),
+                                    interfacePrivate->entity_device_unique);
+       }
+       if (interfacePrivate->hidden) {
+               CFDictionarySetValue(entity,
+                                    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) {
@@ -2249,6 +3220,10 @@ __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface)
        }
        interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
+       if (CFEqual(interface, kSCNetworkInterfaceIPv4)) {
+               return entity;
+       }
+
        interfaceIndex = findConfiguration(interfacePrivate->interface_type);
        if (interfaceIndex != kCFNotFound) {
                if (configurations[interfaceIndex].entity_hardware != NULL) {
@@ -2268,19 +3243,6 @@ __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface)
                             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;
 }
 
@@ -2306,7 +3268,7 @@ findInterface(CFArrayRef interfaces, CFStringRef match_if)
        return NULL;
 }
 
-
+#if    !TARGET_OS_IPHONE
 static SCNetworkInterfaceRef
 findBondInterface(SCPreferencesRef prefs, CFStringRef ifDevice)
 {
@@ -2325,6 +3287,26 @@ findBondInterface(SCPreferencesRef prefs, CFStringRef ifDevice)
        }
        return interface;
 }
+#endif // !TARGET_OS_IPHONE
+
+static SCNetworkInterfaceRef
+findBridgeInterface(SCPreferencesRef prefs, CFStringRef ifDevice)
+{
+       CFArrayRef              bridges;
+       SCNetworkInterfaceRef   interface       = NULL;
+
+       if (prefs == NULL) {
+               return (NULL);
+       }
+
+       // check if the interface is an bridge
+       bridges = SCBridgeInterfaceCopyAll(prefs);
+       if (bridges != NULL) {
+               interface = findInterface(bridges, ifDevice);
+               CFRelease(bridges);
+       }
+       return interface;
+}
 
 static SCNetworkInterfaceRef
 findVLANInterface(SCPreferencesRef prefs, CFStringRef ifDevice)
@@ -2346,25 +3328,129 @@ findVLANInterface(SCPreferencesRef prefs, CFStringRef ifDevice)
 }
 
 
+#define        N_QUICK 32
+
+
+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)
+_SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef    allocator,
+                                    CFStringRef        bsdName,
+                                    UInt32             flags)
 {
-       CFMutableDictionaryRef  entity;
+#pragma unused(allocator)
+       CFMutableDictionaryRef  entity  = NULL;
+       struct ifreq            ifr;
        SCNetworkInterfaceRef   interface;
 
-       entity = CFDictionaryCreateMutable(NULL,
-                                          0,
-                                          &kCFTypeDictionaryKeyCallBacks,
-                                          &kCFTypeDictionaryValueCallBacks);
-       CFDictionarySetValue(entity, kSCPropNetInterfaceDeviceName, bsdName);
-       if ((flags & kIncludeVLANInterfaces) == 0) {
-               CFDictionarySetValue(entity, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue);
+       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) {
                CFDictionarySetValue(entity, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue);
        }
+#endif // !TARGET_OS_IPHONE
+
+       if ((flags & kIncludeBridgeInterfaces) == 0) {
+               CFDictionarySetValue(entity, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue);
+       }
+
+       if ((flags & kIncludeVLANInterfaces) == 0) {
+               CFDictionarySetValue(entity, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue);
+       }
+
        interface = _SCNetworkInterfaceCreateWithEntity(NULL, entity, NULL);
        CFRelease(entity);
 
@@ -2372,1945 +3458,4286 @@ _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef         allocator,
 }
 
 
-SCNetworkInterfaceRef
-_SCNetworkInterfaceCreateWithEntity(CFAllocatorRef             allocator,
-                                   CFDictionaryRef             interface_entity,
-                                   SCNetworkServiceRef         service)
+static CFStringRef
+_SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName)
 {
-       SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
-       CFStringRef                     ifDevice;
-       CFStringRef                     ifSubType;
-       CFStringRef                     ifType;
-       CFArrayRef                      matching_interfaces     = NULL;
-
-       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
-       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+       CFMutableStringRef interfacePrefix = NULL;
+       UniChar lastChar;
+       CFIndex length = 0;
 
-       ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
-       if (ifType == NULL) {
-               /*
-                * The interface "Type" was not specified.  We'll make an
-                * 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
-                * will keep the rest of the configuration APIs happy.
-                */
-               ifType = kSCValNetInterfaceTypeEthernet;
+       if (isA_CFString(bsdName) == NULL) {
+               SC_log(LOG_DEBUG, "no BSD name");
+               goto done;
        }
 
-       if (!isA_CFString(ifType)) {
-               return NULL;
-       }
+       interfacePrefix = CFStringCreateMutableCopy(NULL, 0, bsdName);
+       length = CFStringGetLength(interfacePrefix);
 
-       ifSubType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceSubType);
-       if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
-               if (!isA_CFString(ifSubType)) {
-                       return NULL;
+       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;
+}
 
-       ifDevice = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceDeviceName);
-
-       if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet) ||
-           CFEqual(ifType, kSCValNetInterfaceTypeFireWire) ||
-           (CFEqual(ifType, kSCValNetInterfaceTypePPP) && CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE))) {
-               char                    bsdName[IFNAMSIZ + 1];
-               CFMutableDictionaryRef  matching;
 
-               if (!isA_CFString(ifDevice)) {
-                       return NULL;
-               }
+static void
+__SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface,
+                                        CFStringRef prefix);
 
-               if (_SC_cfstring_to_cstring(ifDevice, bsdName, sizeof(bsdName), kCFStringEncodingASCII) == NULL) {
-                       goto done;
-               }
 
-               matching = IOBSDNameMatching(masterPort, 0, bsdName);
-               if (matching == NULL) {
-                       goto done;
-               }
+static Boolean
+__SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface, CFStringRef currentBSDName, CFStringRef newBSDName)
+{
+       Boolean success = FALSE;
+       SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
-               // note: the "matching" dictionary will be consumed by the following
-               matching_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
+       if (isA_SCNetworkInterface(interface) == NULL) {
+               SC_log(LOG_INFO, "No interface");
+               goto done;
+       }
 
-       } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
-               if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) {
-                       CFDictionaryRef matching;
-                       CFStringRef     match_keys[2];
-                       CFStringRef     match_vals[2];
+       if (CFEqual(currentBSDName, newBSDName)) {
+               // if no change
+               goto done;
+       }
 
-                       if (!isA_CFString(ifDevice)) {
-                               return NULL;
-                       }
+       if (interfacePrivate->entity_device != NULL) {
+               CFRelease(interfacePrivate->entity_device);
+       }
+       interfacePrivate->entity_device = CFRetain(newBSDName);
+       success = TRUE;
+done:
+       return success;
+}
 
-                       match_keys[0] = CFSTR(kIOProviderClassKey);
-                       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
 
-                       match_keys[1] = CFSTR(kIOTTYDeviceKey);
-                       match_vals[1] = ifDevice;
+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;
 
-                       matching = CFDictionaryCreate(NULL,
-                                                     (const void **)match_keys,
-                                                     (const void **)match_vals,
-                                                     sizeof(match_keys)/sizeof(match_keys[0]),
-                                                     &kCFTypeDictionaryKeyCallBacks,
-                                                     &kCFTypeDictionaryValueCallBacks);
+done:
+       if (newPath != NULL) {
+               CFRelease(newPath);
+       }
+       return success;
+}
 
-                       // note: the "matching" dictionary will be consumed by the following
-                       matching_interfaces = findMatchingInterfaces(matching, processSerialInterface);
 
-               } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypeL2TP)) {
-                       interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
-                                                                                                              kSCNetworkInterfaceTypeL2TP);
-               } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPTP)) {
-                       interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
-                                                                                                              kSCNetworkInterfaceTypePPTP);
-               } else {
-                       // XXX do we allow non-Apple variants of PPP??? XXX
-                       interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
-                                                                                                              ifSubType);
-               }
-       } else if (CFEqual(ifType, kSCValNetInterfaceType6to4)) {
-               if (!isA_CFString(ifDevice)) {
-                       return NULL;
-               }
+static void
+__SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface,
+                                         CFStringRef prefix)
+{
+       SCNetworkInterfacePrivateRef interfacePrivate;
 
-               interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
-                                                                                                      kSCNetworkInterfaceType6to4);
-       } else if ((CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) && (ifDevice == NULL)) {
-               interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
-                                                                                                      ifType);
+       if (isA_CFString(prefix) == NULL) {
+               return;
        }
 
-       if (matching_interfaces != NULL) {
-               CFIndex                 n;
-               SCPreferencesRef        prefs;
+       interfacePrivate = (SCNetworkInterfacePrivateRef) interface;
 
-               n = CFArrayGetCount(matching_interfaces);
-               switch (n) {
-                       case 0 :
-                               if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
-                                       break;
-                               }
-                               prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterface"), NULL);
-                               if (prefs == NULL) {
-                                       break;
-                               }
-                               if (!CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
-                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
-                               }
-                               if ((interfacePrivate == NULL)
-                                   && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BOND_INTERFACES_"))) {
-                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBondInterface(prefs, ifDevice);
-                               }
-                               CFRelease(prefs);
-                               break;
-                       case 1 :
-                               interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0);
-                               CFRetain(interfacePrivate);
-                               break;
-                       default :
-                               SCLog(TRUE, LOG_DEBUG, CFSTR("_SCNetworkInterfaceCreateWithEntity() failed, more than one interface matches %@"), ifDevice);
-                               CFRelease(matching_interfaces);
-                               _SCErrorSet(kSCStatusFailed);
-                               return NULL;
-               }
-               CFRelease(matching_interfaces);
+       CFRetain(prefix);
+
+       if (interfacePrivate->prefix != NULL) {
+               CFRelease(interfacePrivate->prefix);
        }
 
-    done :
+       interfacePrivate->prefix = prefix;
+       return;
+}
 
-       if (interfacePrivate == NULL) {
-               /*
-                * if device not present on this system
-                */
-               interfacePrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, NULL, NULL, NULL);
-               interfacePrivate->entity_type     = ifType;
-               interfacePrivate->entity_subtype  = ifSubType;
-               interfacePrivate->entity_device   = (ifDevice != NULL) ? CFStringCreateCopy(NULL, ifDevice) : NULL;
 
-               if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
-                       CFStringRef     entity_hardware;
+__private_extern__
+void
+__SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface,
+                                      CFNumberRef unit)
+{
+       SCNetworkInterfacePrivateRef interfacePrivate;
+       CFStringRef newBSDName = NULL;
+       CFStringRef oldBSDName = NULL;
 
-                       entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware);
-                       if ((entity_hardware != NULL) &&
-                           CFEqual(entity_hardware, kSCEntNetAirPort)) {
-                               interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
-                       } else {
-                               interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+       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 if (CFEqual(ifType, kSCValNetInterfaceTypeFireWire)) {
-                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeFireWire;
-               } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
-                       if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) {
-                               interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
-                       } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) {
-                               if (CFStringHasPrefix(ifDevice, CFSTR("Bluetooth"))) {
-                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeBluetooth;
-                               } else if (CFStringHasPrefix(ifDevice, CFSTR("irda"))) {
-                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeIrDA;
-                               } else if (CFStringHasPrefix(ifDevice, CFSTR("wwan"))) {
-                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeWWAN;
-                               } else {
-                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem;
-                               }
-                       } else {
-                               // PPTP, L2TP, ...
-                               CFRelease(interfacePrivate);
-                               interfacePrivate = (SCNetworkInterfacePrivateRef)kSCNetworkInterfaceIPv4;
-                               CFRetain(interfacePrivate);
+                       else {
+                               __SCNetworkInterfaceSetIOInterfacePrefix(interface, interfaceNamePrefix);
+                               CFRelease(interfaceNamePrefix);
                        }
-               } else if (CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) {
-                       // if vendor interface
-                       interfacePrivate->interface_type = ifType;
-               } else {
-                       // if unknown interface
-                       CFRelease(interfacePrivate);
-                       interfacePrivate = NULL;
                }
        }
 
-       if ((interfacePrivate != NULL) && (service != NULL)) {
-               SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)service;
-
-               if (interfacePrivate->prefs != NULL)
-                       CFRelease(interfacePrivate->prefs);
-               if (interfacePrivate->serviceID != NULL)
-                       CFRelease(interfacePrivate->serviceID);
-
-               interfacePrivate->prefs     = CFRetain(servicePrivate->prefs);
-               interfacePrivate->serviceID = CFRetain(servicePrivate->serviceID);
+       if (interfacePrivate->prefix != NULL) {
+               newBSDName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), interfacePrivate->prefix, unit);
        }
 
-       if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
-               SCNetworkInterfaceRef   parent;
-
-               parent = SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef)interfacePrivate,
-                                                              kSCNetworkInterfaceTypePPP);
-               CFRelease(interfacePrivate);
-               interfacePrivate = (SCNetworkInterfacePrivateRef)parent;
+       // Update the BSD Name
+       if ((newBSDName == NULL) ||
+           (!__SCNetworkInterfaceUpdateBSDName(interface, oldBSDName, newBSDName))) {
+               SC_log(LOG_INFO, "BSD name update failed");
        }
 
-       return (SCNetworkInterfaceRef)interfacePrivate;
-}
-
-
-#pragma mark -
-#pragma mark SCNetworkInterface APIs
-
-
-__private_extern__
-CFArrayRef
-__SCNetworkInterfaceCopyAll_IONetworkInterface(void)
-{
-       CFDictionaryRef         matching;
-       CFArrayRef              new_interfaces;
+       // Update the path
+       if (!__SCNetworkInterfaceUpdateIOPath(interface)) {
+               SC_log(LOG_INFO, "IOPath update failed");
+       }
 
-       // get Ethernet, Firewire, and AirPort interfaces
+       CFRetain(unit);
+       if (interfacePrivate->unit != NULL) {
+               CFRelease(interfacePrivate->unit);
+       }
+       interfacePrivate->unit = unit;
 
-       matching = IOServiceMatching(kIONetworkInterfaceClass);
-       new_interfaces = findMatchingInterfaces(matching, processNetworkInterface);
 
-       return new_interfaces;
+       if (newBSDName != NULL) {
+               CFRelease(newBSDName);
+       }
+       return;
 }
 
 
-static
-CFArrayRef
-__SCNetworkInterfaceCopyAll_Modem()
+__private_extern__
+CFDictionaryRef
+__SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface)
 {
-       CFDictionaryRef         matching;
-       CFStringRef             match_keys[2];
-       CFStringRef             match_vals[2];
-       CFArrayRef              new_interfaces;
+       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;
+       }
 
-       match_keys[0] = CFSTR(kIOProviderClassKey);
-       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+       builtin = interfacePrivate->builtin ? kCFBooleanTrue : kCFBooleanFalse;
+       interfaceNamePrefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface);
+       if (!isA_CFString(interfaceNamePrefix)) {
+               goto done;
+       }
 
-       match_keys[1] = CFSTR(kIOSerialBSDTypeKey);
-       match_vals[1] = CFSTR(kIOSerialBSDModemType);
+       interfaceType = _SCNetworkInterfaceGetIOInterfaceType(interface);
+       if (!isA_CFNumber(interfaceType)) {
+               goto done;
+       }
 
-       matching = CFDictionaryCreate(NULL,
-                                     (const void **)match_keys,
-                                     (const void **)match_vals,
-                                     sizeof(match_keys)/sizeof(match_keys[0]),
-                                     &kCFTypeDictionaryKeyCallBacks,
-                                     &kCFTypeDictionaryValueCallBacks);
-       new_interfaces = findMatchingInterfaces(matching, processSerialInterface);
+       interfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
+       if (!isA_CFNumber(interfaceUnit)) {
+               goto done;
+       }
 
-       return new_interfaces;
-}
+       macAddress = _SCNetworkInterfaceGetHardwareAddress(interface);
+       if (!isA_CFData(macAddress)) {
+               goto done;
+       }
 
+       pathMatch = _SCNetworkInterfaceGetIOPath(interface);
+       if (!isA_CFString(pathMatch)) {
+               goto done;
+       }
 
-static
-CFArrayRef
-__SCNetworkInterfaceCopyAll_RS232()
-{
-       CFDictionaryRef         matching;
-       CFStringRef             match_keys[2];
-       CFStringRef             match_vals[2];
-       CFArrayRef              new_interfaces;
+       info = _SCNetworkInterfaceCopyInterfaceInfo(interface);
+       if (!isA_CFDictionary(info)) {
+               goto done;
+       }
 
-       match_keys[0] = CFSTR(kIOProviderClassKey);
-       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+       type = SCNetworkInterfaceGetInterfaceType(interface);
+       if (!isA_CFString(type)) {
+               goto done;
+       }
 
-       match_keys[1] = CFSTR(kIOSerialBSDTypeKey);
-       match_vals[1] = CFSTR(kIOSerialBSDRS232Type);
+       interface_entity = CFDictionaryCreateMutable(NULL, 0,
+                                                    &kCFTypeDictionaryKeyCallBacks,
+                                                    &kCFTypeDictionaryValueCallBacks);
 
-       matching = CFDictionaryCreate(NULL,
-                                     (const void **)match_keys,
-                                     (const void **)match_vals,
-                                     sizeof(match_keys)/sizeof(match_keys[0]),
-                                     &kCFTypeDictionaryKeyCallBacks,
-                                     &kCFTypeDictionaryValueCallBacks);
-       new_interfaces = findMatchingInterfaces(matching, processSerialInterface);
+       if (isA_CFBoolean(active) != NULL) {
+               CFDictionaryAddValue(interface_entity, CFSTR(kSCNetworkInterfaceActive), active);
+       }
 
-       return new_interfaces;
+       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
-add_interfaces(CFMutableArrayRef all_interfaces, CFArrayRef new_interfaces)
+__SCNetworkInterfaceSetService(SCNetworkInterfaceRef   interface,
+                              SCNetworkServiceRef      service)
 {
-       CFIndex i;
-       CFIndex n;
+       SCNetworkInterfacePrivateRef    interfacePrivate;
+       SCNetworkServicePrivateRef      servicePrivate;
 
-       n = CFArrayGetCount(new_interfaces);
-       for (i = 0; i < n; i++) {
-               CFStringRef             bsdName;
-               SCNetworkInterfaceRef   interface;
+       interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+       if (interfacePrivate->prefs != NULL) {
+               CFRelease(interfacePrivate->prefs);
+               interfacePrivate->prefs = NULL;
+       }
+       if (interfacePrivate->serviceID != NULL) {
+               CFRelease(interfacePrivate->serviceID);
+               interfacePrivate->serviceID = NULL;
+       }
 
-               interface = CFArrayGetValueAtIndex(new_interfaces, i);
-               bsdName = SCNetworkInterfaceGetBSDName(interface);
-               if (bsdName != NULL) {
-                       CFArrayAppendValue(all_interfaces, interface);
-               }
+       servicePrivate = (SCNetworkServicePrivateRef)service;
+       if (servicePrivate->prefs != NULL) {
+               interfacePrivate->prefs = CFRetain(servicePrivate->prefs);
+       }
+       if (servicePrivate->serviceID != NULL) {
+               interfacePrivate->serviceID = CFRetain(servicePrivate->serviceID);
        }
 
        return;
 }
 
 
-static void
-__waitForInterfaces()
+__private_extern__
+Boolean
+__SCNetworkInterfaceMatchesName(CFStringRef name, CFStringRef key)
 {
-       CFStringRef             key;
-       CFArrayRef              keys;
-       Boolean                 ok;
-       SCDynamicStoreRef       store;
+       Boolean         match;
+       CFStringRef     str;
 
-       store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL, NULL);
-       if (store == NULL) {
-               return;
+       if (bundle == NULL) {
+               SC_log(LOG_NOTICE, "no bundle information to compare interface names");
+               return FALSE;
        }
 
-       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
-       keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
-       ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
-       CFRelease(keys);
-       if (!ok) {
-               SCLog(TRUE, LOG_ERR,
-                     CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError()));
-               goto done;
+       if (!isA_CFString(name)) {
+               // if no interface "name"
+               return FALSE;
        }
 
-       while (TRUE) {
-               CFDictionaryRef dict;
-               Boolean         quiet   = FALSE;
-
-               // check if quiet
-               dict = SCDynamicStoreCopyValue(store, key);
-               if (dict != NULL) {
-                       if (isA_CFDictionary(dict) &&
-                           (CFDictionaryContainsKey(dict, CFSTR("*QUIET*")) ||
-                            CFDictionaryContainsKey(dict, CFSTR("*TIMEOUT*")))) {
-                               quiet = TRUE;
-                       }
-                       CFRelease(dict);
-               }
-               if (quiet) {
-                       break;
+       // check non-localized name for a match
+       str = copy_interface_string(bundle, key, FALSE);
+       if (str != NULL) {
+               match = CFEqual(name, str);
+               CFRelease(str);
+               if (match) {
+                       return TRUE;
                }
+       }
 
-               ok = SCDynamicStoreNotifyWait(store);
-               if (!ok) {
-                       SCLog(TRUE, LOG_ERR,
-                             CFSTR("SCDynamicStoreNotifyWait() failed: %s"), SCErrorString(SCError()));
-                       goto done;
+       // check localized name for a match
+       str = copy_interface_string(bundle, key, TRUE);
+       if (str != NULL) {
+               match = CFEqual(name, str);
+               CFRelease(str);
+               if (match) {
+                       return TRUE;
                }
        }
 
-    done :
-
-       CFRelease(key);
-       CFRelease(store);
-       return;
+       return FALSE;
 }
 
 
-CFArrayRef /* of SCNetworkInterfaceRef's */
-SCNetworkInterfaceCopyAll()
+#define kInterfaceTypeEthernetValue 6
+#define kInterfaceTypeFirewireValue 144
+
+
+static SCNetworkInterfaceRef
+__SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef     allocator,
+                                           CFDictionaryRef     interface_entity)
 {
-       CFMutableArrayRef       all_interfaces;
-       CFArrayRef              new_interfaces;
-       SCPreferencesRef        prefs;
+#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);
 
-       /* wait for IOKit to quiesce */
-       pthread_once(&iokit_quiet, __waitForInterfaces);
-
-       all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-       // get Ethernet, Firewire, and AirPort interfaces
-       new_interfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
-       if (new_interfaces != NULL) {
-               add_interfaces(all_interfaces, new_interfaces);
-               CFRelease(new_interfaces);
+       if (isA_CFDictionary(interface_entity) == NULL) {
+               SC_log(LOG_INFO, "No interface entity");
+               goto done;
        }
-
-       // get Modem interfaces
-       new_interfaces = __SCNetworkInterfaceCopyAll_Modem();
-       if (new_interfaces != NULL) {
-               add_interfaces(all_interfaces, new_interfaces);
-               CFRelease(new_interfaces);
+       active = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceActive));
+       if (isA_CFBoolean(active) == NULL) {
+               active = kCFBooleanFalse;
        }
-
-       // get serial (RS232) interfaces
-       new_interfaces = __SCNetworkInterfaceCopyAll_RS232();
-       if (new_interfaces != NULL) {
-               add_interfaces(all_interfaces, new_interfaces);
-               CFRelease(new_interfaces);
+       bsdName = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceBSDName));
+       if (isA_CFString(bsdName) == NULL) {
+               SC_log(LOG_INFO, "No BSD name");
+               goto done;
        }
-
-       // get virtual network interfaces (Bond, VLAN)
-       prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL);
-       if (prefs != NULL) {
-               new_interfaces = SCBondInterfaceCopyAll(prefs);
-               if (new_interfaces != NULL) {
-                       add_interfaces(all_interfaces, new_interfaces);
-                       CFRelease(new_interfaces);
+       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");
 
-               new_interfaces = SCVLANInterfaceCopyAll(prefs);
-               if (new_interfaces != NULL) {
-                       add_interfaces(all_interfaces, new_interfaces);
-                       CFRelease(new_interfaces);
-               }
+               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
 
-               CFRelease(prefs);
+       type = CFDictionaryGetValue(interface_entity, CFSTR(kSCNetworkInterfaceType));
+       if (isA_CFString(type) == NULL) {
+               SC_log(LOG_INFO, "No SCNetworkInterfaceType");
+               goto done;
        }
 
-       // all interfaces have been identified, order and return
-       sort_interfaces(all_interfaces);
+       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;
+       }
 
-       return all_interfaces;
+       // 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;
 }
 
 
-CFArrayRef /* of kSCNetworkInterfaceTypeXXX CFStringRef's */
-SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface)
+__private_extern__
+void
+_SCNetworkInterfaceCacheOpen(void)
 {
-       CFIndex                         i;
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
+       if (!__SCNetworkInterfaceCacheIsOpen()) {
+               S_interface_cache = CFDictionaryCreateMutable(NULL,
+                                                             0,
+                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                             &kCFTypeDictionaryValueCallBacks);
+               SC_log(LOG_DEBUG, "SCNetworkInterface cache (%p): open", S_interface_cache);
        }
+}
 
-       if (interfacePrivate->supported_interface_types != NULL) {
-               goto done;
-       }
 
-       i = findConfiguration(interfacePrivate->interface_type);
-       if (i != kCFNotFound) {
-               if (configurations[i].supported_interfaces != doNone) {
-                       interfacePrivate->supported_interface_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-                       if (configurations[i].supported_interfaces & do6to4) {
-                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceType6to4);
-                       }
-                       if (configurations[i].supported_interfaces & doL2TP) {
-                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeL2TP);
-                       }
-                       if (configurations[i].supported_interfaces & doPPP) {
-                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPP);
-                       }
-                       if (configurations[i].supported_interfaces & doPPTP) {
-                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPTP);
-                       }
-               }
+__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;
        }
+}
 
-    done :
 
-       return interfacePrivate->supported_interface_types;
+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);
+       }
 }
 
 
-CFArrayRef /* of kSCNetworkProtocolTypeXXX CFStringRef's */
-SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface)
+static inline Boolean
+__SCNetworkInterfaceCacheIsOpen(void)
 {
-       CFIndex                         i;
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+       return (S_interface_cache != NULL);
+}
 
-       if (interfacePrivate->supported_protocol_types != NULL) {
-               goto done;
-       }
 
-       i = findConfiguration(interfacePrivate->interface_type);
-       if (i != kCFNotFound) {
-               if (configurations[i].supported_protocols != doNone) {
-                       interfacePrivate->supported_protocol_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-                       if (configurations[i].supported_protocols & doAppleTalk) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeAppleTalk);
-                       }
-                       if (configurations[i].supported_protocols & doDNS) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeDNS);
-                       }
-                       if (configurations[i].supported_protocols & doIPv4) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv4);
-                       }
-                       if (configurations[i].supported_protocols & doIPv6) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv6);
-                       }
-                       if (configurations[i].supported_protocols & doProxies) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeProxies);
-                       }
-                       if (configurations[i].supported_protocols & doSMB) {
-                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeSMB);
-                       }
+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);
                }
-       }
 
-    done :
+               return matchingInterfaces;
+       }
 
-       return interfacePrivate->supported_protocol_types;
+       return NULL;
 }
 
 
 SCNetworkInterfaceRef
-SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef interfaceType)
+_SCNetworkInterfaceCreateWithEntity(CFAllocatorRef     allocator,
+                                   CFDictionaryRef     interface_entity,
+                                   SCNetworkServiceRef service)
 {
-       SCNetworkInterfacePrivateRef    childPrivate    = (SCNetworkInterfacePrivateRef)child;
-       CFIndex                         childIndex;
-       SCNetworkInterfacePrivateRef    parentPrivate;
+#pragma unused(allocator)
+       SCNetworkInterfacePrivateRef    interfacePrivate        = NULL;
+       CFStringRef                     ifDevice;
+       CFStringRef                     ifName                  = NULL;
+       CFStringRef                     ifSubType;
+       CFStringRef                     ifType;
+       CFStringRef                     ifUnique;
+       CFArrayRef                      matching_interfaces     = NULL;
+       SCPreferencesRef                servicePref             = NULL;
+       Boolean                         useSystemInterfaces     = TRUE;
 
-       if (!isA_SCNetworkInterface(child)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       if (!isA_CFString(interfaceType)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
+       if (service != NULL) {
+               servicePref = ((SCNetworkServicePrivateRef)service)->prefs;
+               useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePref)) &&
+                                      (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref)));
        }
 
-       childIndex = findConfiguration(childPrivate->interface_type);
+       ifType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceType);
+       if (ifType == NULL) {
+               /*
+                * The interface "Type" was not specified.  We'll make an
+                * 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 that
+                * will keep the rest of the configuration APIs happy.
+                */
+               ifType = kSCValNetInterfaceTypeEthernet;
+       }
 
-       parentPrivate = __SCNetworkInterfaceCreatePrivate(NULL,
-                                                         child,
-                                                         childPrivate->prefs,
-                                                         childPrivate->serviceID,
-                                                         NULL);
-       if (parentPrivate == NULL) {
-               _SCErrorSet(kSCStatusFailed);
+       if (!isA_CFString(ifType)) {
                return NULL;
        }
 
-       if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
-               parentPrivate->interface_type = kSCNetworkInterfaceTypePPP;
-               parentPrivate->entity_type    = kSCEntNetPPP;
+       ifSubType = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceSubType);
+       if (CFEqual(ifType, kSCValNetInterfaceTypePPP) ||
+           CFEqual(ifType, kSCValNetInterfaceTypeVPN)) {
+               if (!isA_CFString(ifSubType)) {
+                       return NULL;
+               }
+       }
 
-               // entity subtype
-               if (childIndex != kCFNotFound) {
-                       if (configurations[childIndex].ppp_subtype != NULL) {
-                               parentPrivate->entity_subtype = *configurations[childIndex].ppp_subtype;
-                       } else {
+       ifDevice = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceDeviceName);
+       ifUnique = CFDictionaryGetValue(interface_entity, CFSTR("DeviceUniqueIdentifier"));
+
+       if (CFEqual(ifType, kSCValNetInterfaceTypeEthernet) ||
+           CFEqual(ifType, kSCValNetInterfaceTypeFireWire) ||
+           (CFEqual(ifType, kSCValNetInterfaceTypePPP) && CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE))) {
+               char                    bsdName[IFNAMSIZ];
+               CFMutableDictionaryRef  matching;
+
+               if (!isA_CFString(ifDevice)) {
+                       return NULL;
+               }
+
+               if (CFEqual(ifDevice, CFSTR("lo0"))) {  // for _SCNetworkInterfaceCreateWithBSDName
+                       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;
+                               }
+
+                               matching = IOBSDNameMatching(masterPort, 0, bsdName);
+                               if (matching == NULL) {
+                                       goto done;
+                               }
+                               matching_interfaces = findMatchingInterfaces(matching,
+                                                                            processNetworkInterface,
+                                                                            kSCNetworkInterfaceHiddenInterfaceKey,
+                                                                            TRUE);
+
+                               __SCNetworkInterfaceCacheAdd(ifDevice, matching_interfaces);
+                               CFRelease(matching);
+                       }
+               }
+       } else if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
+               if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) {
+                       CFDictionaryRef matching;
+                       CFStringRef     match_keys[2];
+                       CFStringRef     match_vals[2];
+
+                       if (!isA_CFString(ifDevice)) {
+                               return NULL;
+                       }
+
+                       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;
+
+                               n = (matching_interfaces != NULL) ? CFArrayGetCount(matching_interfaces) : 0;
+                               if (n > 0) {
+                                       CFIndex i;
+
+                                       for (i = 0; i < n; i++) {
+                                               SCNetworkInterfacePrivateRef    scanPrivate;
+
+                                               scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i);
+                                               if (scanPrivate->entity_device_unique != NULL) {
+                                                       useDeviceName = FALSE;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               if (useDeviceName && useSystemInterfaces) {
+                                       if (matching_interfaces != NULL) {
+                                               CFRelease(matching_interfaces);
+                                       }
+
+                                       match_keys[1] = CFSTR(kIOTTYDeviceKey);
+                                       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);
+                               }
+                       }
+               } 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,
+                                                                                                              ifSubType);
+               }
+       } else if (CFEqual(ifType, kSCValNetInterfaceType6to4)) {
+               if (!isA_CFString(ifDevice)) {
+                       return NULL;
+               }
+
+               interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+                                                                                                      kSCNetworkInterfaceType6to4);
+       } else if (CFEqual(ifType, kSCValNetInterfaceTypeIPSec)) {
+               interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+                                                                                                      kSCNetworkInterfaceTypeIPSec);
+       } else if (CFEqual(ifType, kSCValNetInterfaceTypeLoopback)) {
+               interfacePrivate = __SCNetworkInterfaceCreateCopy(NULL, kSCNetworkInterfaceLoopback, NULL, NULL);
+       } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) {
+               if (CFStringFind(ifSubType, CFSTR("."), 0).location != kCFNotFound) {
+                       interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+                                                                                                              ifSubType);
+               }
+       } else if ((CFStringFind(ifType, CFSTR("."), 0).location != kCFNotFound) && (ifDevice == NULL)) {
+               interfacePrivate = (SCNetworkInterfacePrivateRef)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4,
+                                                                                                      ifType);
+       }
+
+       if (matching_interfaces != NULL) {
+               CFIndex                 n;
+               SCPreferencesRef        prefs;
+               Boolean                 temp_preferences        = FALSE;
+
+               n = CFArrayGetCount(matching_interfaces);
+               switch (n) {
+                       case 1 :
+                               interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0);
+                               if (_SC_CFEqual(ifUnique, interfacePrivate->entity_device_unique)) {
+                                       // if the unique ID's  match
+                                       CFRetain(interfacePrivate);
+                                       break;
+                               }
+
+                               interfacePrivate = NULL;
+                               // fall through
+                       case 0 :
+                               if (!CFEqual(ifType, kSCValNetInterfaceTypeEthernet)) {
+                                       break;
+                               }
+
+                               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;
+                               }
+#if    !TARGET_OS_IPHONE
+                               if (!CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BOND_INTERFACES_"))) {
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBondInterface(prefs, ifDevice);
+                               }
+#endif // !TARGET_OS_IPHONE
+                               if ((interfacePrivate == NULL)
+                                   && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findBridgeInterface(prefs, ifDevice);
+                               }
+
+                               if ((interfacePrivate == NULL)
+                                   && !CFDictionaryContainsKey(interface_entity, CFSTR("_NO_VLAN_INTERFACES_"))) {
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)findVLANInterface(prefs, ifDevice);
+                               }
+                               if (temp_preferences) CFRelease(prefs);
+                               break;
+                       default :
+                               if (ifUnique != NULL) {
+                                       CFIndex i;
+
+                                       // we are looking for an interface with a unique ID
+                                       // so let's try to focus our choices
+                                       for (i = 0; i < n; i++) {
+                                               SCNetworkInterfacePrivateRef    scanPrivate;
+
+                                               scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i);
+                                               if (_SC_CFEqual(ifUnique, scanPrivate->entity_device_unique)) {
+                                                       if (interfacePrivate != NULL) {
+                                                               // if we've matched more than one interface
+                                                               interfacePrivate = NULL;
+                                                               break;
+                                                       }
+                                                       interfacePrivate = scanPrivate;
+                                               }
+                                       }
+                               } else if (CFDictionaryGetValueIfPresent(interface_entity,
+                                                                        kSCPropUserDefinedName,
+                                                                        (const void **)&ifName)) {
+                                       CFIndex i;
+
+                                       // we don't have a unique ID but do have an interface
+                                       // name.  If the matching interfaces do have IDs than
+                                       // we can try to focus our choices using the name
+                                       for (i = 0; i < n; i++) {
+                                               SCNetworkInterfacePrivateRef    scanPrivate;
+
+                                               scanPrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, i);
+                                               if (scanPrivate->entity_device_unique != NULL) {
+                                                       SCNetworkInterfaceRef   scan    = (SCNetworkInterfaceRef)scanPrivate;
+                                                       CFStringRef             scanName;
+
+                                                       scanName = __SCNetworkInterfaceGetNonLocalizedDisplayName(scan);
+                                                       if ((scanName != NULL) && !_SC_CFEqual(ifName, scanName)) {
+                                                               continue; // if not the same display name
+                                                       }
+                                               }
+
+                                               if (interfacePrivate != NULL) {
+                                                       // if we've matched more than one interface
+                                                       interfacePrivate = NULL;
+                                                       break;
+                                               }
+                                               interfacePrivate = scanPrivate;
+                                       }
+                               }
+                               if (interfacePrivate == NULL) {
+                                       SC_log(LOG_NOTICE, "more than one interface matches %@", ifDevice);
+                                       interfacePrivate = (SCNetworkInterfacePrivateRef)CFArrayGetValueAtIndex(matching_interfaces, 0);
+                               }
+                               CFRetain(interfacePrivate);
+                               break;
+               }
+               CFRelease(matching_interfaces);
+       }
+
+    done :
+
+       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 != 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;
+
+                       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 {
+                               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 {
+                                       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) && (ifSubType != NULL)) {
+                       if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPoE)) {
+                               CFStringRef     entity_hardware;
+
+                               entity_hardware = CFDictionaryGetValue(interface_entity, kSCPropNetInterfaceHardware);
+                               if (isA_CFString((entity_hardware)) &&
+                                   CFEqual(entity_hardware, kSCEntNetAirPort)) {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeIEEE80211;
+                                       interfacePrivate->sort_order     = kSortAirPort;
+                               } else {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeEthernet;
+                                       interfacePrivate->sort_order     = kSortEthernet;
+                               }
+                       } else if (CFEqual(ifSubType, kSCValNetInterfaceSubTypePPPSerial)) {
+                               if (CFStringHasPrefix(ifDevice, CFSTR("Bluetooth"))) {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeBluetooth;
+                                       interfacePrivate->sort_order     = kSortBluetooth;
+                               } else if (CFStringHasPrefix(ifDevice, CFSTR("irda"))) {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeIrDA;
+                                       interfacePrivate->sort_order     = kSortIrDA;
+                               } else if (CFStringHasPrefix(ifDevice, CFSTR("wwan"))) {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeWWAN;
+                                       interfacePrivate->sort_order     = kSortWWAN;
+                               } else {
+                                       interfacePrivate->interface_type = kSCNetworkInterfaceTypeModem;
+                                       interfacePrivate->sort_order     = kSortModem;
+                               }
+                       } else {
+                               SCNetworkInterfaceRef   child;
+                               // PPTP, L2TP, ...
+                               CFRelease(interfacePrivate);
+                               child = SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4, ifSubType);
+                               interfacePrivate = (SCNetworkInterfacePrivateRef)child;
+                               if (interfacePrivate == NULL) {
+                                       return NULL;
+                               }
+                       }
+               } 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);
+                       interfacePrivate = NULL;
+                       return NULL;
+               }
+
+               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((SCNetworkInterfaceRef)interfacePrivate,
+                                              service);
+
+#if    !TARGET_OS_IPHONE
+               // set prefs & serviceID to Bond member interfaces
+               if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBond)) {
+                       CFIndex         i;
+                       CFArrayRef      members;
+                       CFIndex         n;
+
+                       members = SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef)interfacePrivate);
+                       n = (members != NULL) ? CFArrayGetCount(members) : 0;
+                       for (i = 0; i < n; i++) {
+                               SCNetworkInterfaceRef   member;
+
+                               member = CFArrayGetValueAtIndex(members, i);
+                               __SCNetworkInterfaceSetService(member, service);
+                       }
+               }
+#endif // !TARGET_OS_IPHONE
+
+               // set prefs & serviceID to Bridge member interfaces
+               if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeBridge)) {
+                       CFIndex         i;
+                       CFArrayRef      members;
+                       CFIndex         n;
+
+                       members = SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef)interfacePrivate);
+                       n = (members != NULL) ? CFArrayGetCount(members) : 0;
+                       for (i = 0; i < n; i++) {
+                               SCNetworkInterfaceRef   member;
+
+                               member = CFArrayGetValueAtIndex(members, i);
+                               __SCNetworkInterfaceSetService(member, service);
+                       }
+               }
+               // set prefs & serviceID to VLAN pyhsical interface
+               if (CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeVLAN)) {
+                       SCNetworkInterfaceRef   vlan_physical;
+
+                       vlan_physical = SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef)interfacePrivate);
+                       if (vlan_physical != NULL) {
+                               __SCNetworkInterfaceSetService(vlan_physical, service);
+                       }
+               }
+       }
+
+       if (CFEqual(ifType, kSCValNetInterfaceTypePPP)) {
+               SCNetworkInterfaceRef   parent;
+
+               // create parent
+               parent = SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef)interfacePrivate,
+                                                              kSCNetworkInterfaceTypePPP);
+               CFRelease(interfacePrivate);
+               interfacePrivate = (SCNetworkInterfacePrivateRef)parent;
+       } else if (CFEqual(ifType, kSCValNetInterfaceTypeVPN)) {
+               SCNetworkInterfaceRef   parent;
+
+               // create parent
+               parent = SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef)interfacePrivate,
+                                                              kSCNetworkInterfaceTypeVPN);
+               CFRelease(interfacePrivate);
+               interfacePrivate = (SCNetworkInterfacePrivateRef)parent;
+       }
+
+       return (SCNetworkInterfaceRef)interfacePrivate;
+}
+
+
+#pragma mark -
+#pragma mark SCNetworkInterface APIs
+
+
+__private_extern__
+CFArrayRef
+__SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured)
+{
+       CFDictionaryRef         matching;
+       CFArrayRef              new_interfaces;
+
+       // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
+
+       matching = IOServiceMatching(kIONetworkInterfaceClass);
+       new_interfaces = findMatchingInterfaces(matching,
+                                               processNetworkInterface,
+                                               kSCNetworkInterfaceHiddenInterfaceKey,
+                                               keep_pre_configured);
+       CFRelease(matching);
+
+       return new_interfaces;
+}
+
+
+static
+CFArrayRef
+__SCNetworkInterfaceCopyAll_Modem()
+{
+       CFDictionaryRef         matching;
+       CFStringRef             match_keys[2];
+       CFStringRef             match_vals[2];
+       CFArrayRef              new_interfaces;
+
+       match_keys[0] = CFSTR(kIOProviderClassKey);
+       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+
+       match_keys[1] = CFSTR(kIOSerialBSDTypeKey);
+       match_vals[1] = CFSTR(kIOSerialBSDModemType);
+
+       matching = CFDictionaryCreate(NULL,
+                                     (const void **)match_keys,
+                                     (const void **)match_vals,
+                                     sizeof(match_keys)/sizeof(match_keys[0]),
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+       new_interfaces = findMatchingInterfaces(matching,
+                                               processSerialInterface,
+                                               kSCNetworkInterfaceHiddenPortKey,
+                                               FALSE);
+       CFRelease(matching);
+
+       return new_interfaces;
+}
+
+
+static
+CFArrayRef
+__SCNetworkInterfaceCopyAll_RS232()
+{
+       CFDictionaryRef         matching;
+       CFStringRef             match_keys[2];
+       CFStringRef             match_vals[2];
+       CFArrayRef              new_interfaces;
+
+       match_keys[0] = CFSTR(kIOProviderClassKey);
+       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+
+       match_keys[1] = CFSTR(kIOSerialBSDTypeKey);
+       match_vals[1] = CFSTR(kIOSerialBSDRS232Type);
+
+       matching = CFDictionaryCreate(NULL,
+                                     (const void **)match_keys,
+                                     (const void **)match_vals,
+                                     sizeof(match_keys)/sizeof(match_keys[0]),
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+       new_interfaces = findMatchingInterfaces(matching,
+                                               processSerialInterface,
+                                               kSCNetworkInterfaceHiddenPortKey,
+                                               FALSE);
+       CFRelease(matching);
+
+       return new_interfaces;
+}
+
+
+#if    !TARGET_OS_IPHONE
+static void
+addBTPANInterface(CFMutableArrayRef all_interfaces)
+{
+       CFIndex                 i;
+       SCNetworkInterfaceRef   interface;
+       CFIndex                 n;
+
+       n = CFArrayGetCount(all_interfaces);
+       for (i = 0; i < n; i++) {
+               SCNetworkInterfaceRef   interface;
+
+               interface = CFArrayGetValueAtIndex(all_interfaces, i);
+               if (_SCNetworkInterfaceIsBluetoothPAN(interface)) {
+                       // if we already have a BT-PAN interface
+                       return;
+               }
+       }
+
+       interface = _SCNetworkInterfaceCopyBTPANInterface();
+       if (interface != NULL) {
+               // include BT-PAN interface
+               CFArrayAppendValue(all_interfaces, interface);
+               CFRelease(interface);
+       }
+
+       return;
+}
+#endif // !TARGET_OS_IPHONE
+
+
+static void
+add_interfaces(CFMutableArrayRef all_interfaces, CFArrayRef new_interfaces)
+{
+       CFIndex i;
+       CFIndex n;
+
+       n = CFArrayGetCount(new_interfaces);
+       for (i = 0; i < n; i++) {
+               CFStringRef             bsdName;
+               SCNetworkInterfaceRef   interface;
+
+               interface = CFArrayGetValueAtIndex(new_interfaces, i);
+               bsdName = SCNetworkInterfaceGetBSDName(interface);
+               if (bsdName != NULL) {
+                       CFArrayAppendValue(all_interfaces, interface);
+               }
+       }
+
+       return;
+}
+
+
+static void
+__waitForInterfaces()
+{
+       CFStringRef             key     = NULL;
+       CFArrayRef              keys;
+       Boolean                 ok;
+       SCDynamicStoreRef       store   = NULL;
+
+       CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
+
+       store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL, NULL);
+       if (store == NULL) {
+               goto done;
+       }
+
+       key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin);
+       keys = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
+       ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
+       CFRelease(keys);
+       if (!ok) {
+               SC_log(LOG_NOTICE, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
+               goto done;
+       }
+
+       while (TRUE) {
+               CFArrayRef      changedKeys;
+               CFDictionaryRef dict;
+               Boolean         quiet   = FALSE;
+
+               // check if quiet
+               dict = SCDynamicStoreCopyValue(store, key);
+               if (dict != NULL) {
+                       if (isA_CFDictionary(dict) &&
+                           (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet) ||
+                            CFDictionaryContainsKey(dict, kInterfaceNamerKey_Timeout))) {
+                               quiet = TRUE;
+                       }
+                       CFRelease(dict);
+               }
+               if (quiet) {
+                       break;
+               }
+
+               ok = SCDynamicStoreNotifyWait(store);
+               if (!ok) {
+                       SC_log(LOG_NOTICE, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
+                       goto done;
+               }
+
+               changedKeys = SCDynamicStoreCopyNotifiedKeys(store);
+               if (changedKeys != NULL) {
+                       CFRelease(changedKeys);
+               }
+       }
+
+    done :
+
+       CRSetCrashLogMessage(NULL);
+
+       if (key != NULL) CFRelease(key);
+       if (store != NULL) CFRelease(store);
+       return;
+}
+
+
+CFArrayRef /* of SCNetworkInterfaceRef's */
+_SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs)
+{
+       CFMutableArrayRef       all_interfaces;
+       CFArrayRef              new_interfaces;
+       Boolean                 temp_preferences        = FALSE;
+
+       /* initialize runtime */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+       /* wait for IOKit to quiesce */
+       pthread_once(&iokit_quiet, __waitForInterfaces);
+
+       all_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       // 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);
+       }
+
+       // get Modem interfaces
+       new_interfaces = __SCNetworkInterfaceCopyAll_Modem();
+       if (new_interfaces != NULL) {
+               add_interfaces(all_interfaces, new_interfaces);
+               CFRelease(new_interfaces);
+       }
+
+       // get serial (RS232) interfaces
+       new_interfaces = __SCNetworkInterfaceCopyAll_RS232();
+       if (new_interfaces != NULL) {
+               add_interfaces(all_interfaces, new_interfaces);
+               CFRelease(new_interfaces);
+       }
+
+       // get virtual network interfaces (Bond, Bridge, VLAN)
+       if (prefs == NULL) {
+               prefs = SCPreferencesCreate(NULL, CFSTR("SCNetworkInterfaceCopyAll"), NULL);
+               if (prefs != NULL) {
+                       temp_preferences = TRUE;
+               }
+       }
+       if (prefs != NULL) {
+#if    !TARGET_OS_IPHONE
+               new_interfaces = SCBondInterfaceCopyAll(prefs);
+               if (new_interfaces != NULL) {
+                       add_interfaces(all_interfaces, new_interfaces);
+                       CFRelease(new_interfaces);
+               }
+#endif // !TARGET_OS_IPHONE
+
+               new_interfaces = SCBridgeInterfaceCopyAll(prefs);
+               if (new_interfaces != NULL) {
+                       add_interfaces(all_interfaces, new_interfaces);
+                       CFRelease(new_interfaces);
+               }
+
+               new_interfaces = SCVLANInterfaceCopyAll(prefs);
+               if (new_interfaces != NULL) {
+                       add_interfaces(all_interfaces, new_interfaces);
+                       CFRelease(new_interfaces);
+               }
+
+#if    !TARGET_OS_IPHONE
+               // add BT-PAN interface
+               addBTPANInterface(all_interfaces);
+#endif // !TARGET_OS_IPHONE
+
+               if (temp_preferences) CFRelease(prefs);
+       }
+
+       // all interfaces have been identified, order and return
+       sort_interfaces(all_interfaces);
+
+       return all_interfaces;
+}
+
+
+CFArrayRef /* of SCNetworkInterfaceRef's */
+SCNetworkInterfaceCopyAll()
+{
+       CFArrayRef      all_interfaces;
+
+       all_interfaces = _SCNetworkInterfaceCopyAllWithPreferences(NULL);
+       return all_interfaces;
+}
+
+
+CFArrayRef /* of kSCNetworkInterfaceTypeXXX CFStringRef's */
+SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface)
+{
+       CFIndex                         i;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (interfacePrivate->supported_interface_types != NULL) {
+               goto done;
+       }
+
+       i = findConfiguration(interfacePrivate->interface_type);
+       if (i != kCFNotFound) {
+               if (configurations[i].supported_interfaces != doNone) {
+                       interfacePrivate->supported_interface_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       if (configurations[i].supported_interfaces & do6to4) {
+                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceType6to4);
+                       }
+                       if (configurations[i].supported_interfaces & doL2TP) {
+                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeL2TP);
+                       }
+                       if (configurations[i].supported_interfaces & doPPP) {
+                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypePPP);
+                       }
+                       if (configurations[i].supported_interfaces & doIPSec) {
+                               CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeIPSec);
+                       }
+               }
+       } else {
+               SCNetworkInterfaceRef   child;
+
+               child = SCNetworkInterfaceGetInterface(interface);
+               if ((child != NULL) && CFEqual(child, kSCNetworkInterfaceIPv4)) {
+                       interfacePrivate->supported_interface_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       CFArrayAppendValue(interfacePrivate->supported_interface_types, kSCNetworkInterfaceTypeVPN);
+               }
+       }
+
+    done :
+
+       return interfacePrivate->supported_interface_types;
+}
+
+
+CFArrayRef /* of kSCNetworkProtocolTypeXXX CFStringRef's */
+SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface)
+{
+       CFIndex                         i;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (interfacePrivate->supported_protocol_types != NULL) {
+               goto done;
+       }
+
+       i = findConfiguration(interfacePrivate->interface_type);
+       if (i != kCFNotFound) {
+               if (configurations[i].supported_protocols != doNone) {
+                       interfacePrivate->supported_protocol_types = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       if (configurations[i].supported_protocols & doDNS) {
+                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeDNS);
+                       }
+                       if (configurations[i].supported_protocols & doIPv4) {
+                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv4);
+                       }
+                       if (configurations[i].supported_protocols & doIPv6) {
+                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeIPv6);
+                       }
+                       if (configurations[i].supported_protocols & doProxies) {
+                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeProxies);
+                       }
+#if    !TARGET_OS_IPHONE
+                       if (configurations[i].supported_protocols & doSMB) {
+                               CFArrayAppendValue(interfacePrivate->supported_protocol_types, kSCNetworkProtocolTypeSMB);
+                       }
+#endif // !TARGET_OS_IPHONE
+               }
+       }
+
+    done :
+
+       return interfacePrivate->supported_protocol_types;
+}
+
+
+SCNetworkInterfaceRef
+SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child, CFStringRef interfaceType)
+{
+       SCNetworkInterfacePrivateRef    childPrivate    = (SCNetworkInterfacePrivateRef)child;
+       CFIndex                         childIndex;
+       SCNetworkInterfacePrivateRef    parentPrivate;
+
+       if (!isA_SCNetworkInterface(child)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (!isA_CFString(interfaceType)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (CFEqual(child, kSCNetworkInterfaceLoopback)) {
+               // can't layer on top of loopback
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       childIndex = findConfiguration(childPrivate->interface_type);
+
+       parentPrivate = __SCNetworkInterfaceCreatePrivate(NULL,
+                                                         child,
+                                                         childPrivate->prefs,
+                                                         childPrivate->serviceID);
+       if (parentPrivate == NULL) {
+               _SCErrorSet(kSCStatusFailed);
+               return NULL;
+       }
+
+       if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
+               parentPrivate->interface_type = kSCNetworkInterfaceTypePPP;
+               parentPrivate->entity_type    = kSCValNetInterfaceTypePPP;
+
+               // entity subtype
+               if (childIndex != kCFNotFound) {
+                       if (configurations[childIndex].ppp_subtype != NULL) {
+                               parentPrivate->entity_subtype = *configurations[childIndex].ppp_subtype;
+                       } else {
                                // sorry, the child interface does not support PPP
                                goto fail;
                        }
-               } else {
-                       // if the child's interface type not known, use the child entities "Type"
-                       parentPrivate->entity_subtype = childPrivate->entity_type;
+               } else {
+                       // if the child's interface type not known, use the child entities "Type"
+                       parentPrivate->entity_subtype = childPrivate->entity_type;
+               }
+
+               if (childPrivate->entity_device != NULL) {
+                       parentPrivate->entity_device = CFStringCreateCopy(NULL, childPrivate->entity_device);
+               }
+
+               if (childPrivate->entity_device_unique != NULL) {
+                       parentPrivate->entity_device_unique = CFStringCreateCopy(NULL, childPrivate->entity_device_unique);
+               }
+       } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
+               if ((childIndex == kCFNotFound) ||
+                   ((configurations[childIndex].supported_interfaces & doL2TP) != doL2TP)) {
+                       // if the child interface does not support L2TP
+                       goto fail;
+               }
+               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)) {
+                       // if the child interface does not support PPTP
+                       goto fail;
+               }
+               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)) {
+                       // if the child interface does not support 6to4
+                       goto fail;
+               }
+
+               parentPrivate->interface_type = kSCNetworkInterfaceType6to4;
+               parentPrivate->localized_key  = CFSTR("6to4");
+               parentPrivate->entity_type    = kSCValNetInterfaceType6to4;
+               parentPrivate->entity_device  = CFRetain(CFSTR("stf0"));
+       } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
+               if ((childIndex == kCFNotFound) ||
+                   ((configurations[childIndex].supported_interfaces & doIPSec) != doIPSec)) {
+                       // if the child interface does not support IPSec
+                       goto fail;
+               }
+               parentPrivate->interface_type = kSCNetworkInterfaceTypeIPSec;
+               parentPrivate->localized_key  = CFSTR("ipsec");
+               parentPrivate->entity_type    = kSCValNetInterfaceTypeIPSec;
+       } else  if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) {
+               if (childIndex != kCFNotFound) {
+                       // if not a "vendor" child interface
+                       goto fail;
+               }
+
+               parentPrivate->interface_type = kSCNetworkInterfaceTypeVPN;
+               parentPrivate->localized_key  = CFSTR("vpn");
+               parentPrivate->localized_arg1 = CFRetain(childPrivate->entity_type);
+               parentPrivate->entity_type    = kSCValNetInterfaceTypeVPN;
+               parentPrivate->entity_subtype = childPrivate->entity_type;
+               if (childPrivate->entity_device != NULL) {
+                       parentPrivate->entity_device = CFStringCreateCopy(NULL, childPrivate->entity_device);
+               }
+               if (parentPrivate->entity_subtype != NULL) {
+                       CFArrayRef      components;
+                       CFIndex         n;
+                       CFStringRef     vpnType;
+
+                       //
+                       // the "default" interface name is derived from the VPN type
+                       //
+                       // e.g.
+                       //      com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
+                       //                ^^^^^^^^^
+                       //
+                       vpnType = parentPrivate->entity_subtype;
+                       components = CFStringCreateArrayBySeparatingStrings(NULL, vpnType, CFSTR("."));
+                       n = CFArrayGetCount(components);
+                       if ((n >= 4) &&
+                           CFEqual(CFArrayGetValueAtIndex(components, n - 1), CFSTR("vpnplugin"))) {
+                               CFMutableStringRef      str;
+
+                               str = CFStringCreateMutableCopy(NULL,
+                                                               0,
+                                                               CFArrayGetValueAtIndex(components, n - 2));
+                               (void) CFStringFindAndReplace(str,
+                                                             CFSTR("-"),
+                                                             CFSTR(" "),
+                                                             CFRangeMake(0, CFStringGetLength(str)),
+                                                             0);
+                               parentPrivate->localized_name = str;
+                       }
+                       CFRelease(components);
+               }
+       } 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
+       } else {
+               // unknown interface type
+               goto fail;
+       }
+
+       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);
+       }
+
+       // The following change handles the case where a user has both an Ethernet and
+       // PPPoE network service. Because a PPPoE service is typically associated with
+       // an ISP we want it to be sorted higher in the service order.
+       if ((parentPrivate->entity_subtype != NULL) &&
+           (CFEqual(parentPrivate->entity_subtype, kSCValNetInterfaceSubTypePPPoE))) {
+               if ((childPrivate->interface_type != NULL) &&
+                   (CFEqual(childPrivate->interface_type, kSCNetworkInterfaceTypeIEEE80211))) {
+                       parentPrivate->sort_order = kSortAirportPPP;
+               } else {
+                       parentPrivate->sort_order = kSortEthernetPPP;
+               }
+       } else {
+               // set sort order of the parent to match the child interface
+               parentPrivate->sort_order = childPrivate->sort_order;
+       }
+
+       return (SCNetworkInterfaceRef)parentPrivate;
+
+    fail :
+
+       CFRelease(parentPrivate);
+       _SCErrorSet(kSCStatusInvalidArgument);
+       return NULL;
+}
+
+
+__private_extern__
+CFDictionaryRef
+__SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface)
+{
+       CFDictionaryRef                 config                  = NULL;
+       CFStringRef                     defaultType;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+       defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
+       if (defaultType != NULL) {
+               if (set != NULL) {
+                       CFStringRef     path;
+
+                       path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL,                                // allocator
+                                                                                  SCNetworkSetGetSetID(set),           // set
+                                                                                  interfacePrivate->entity_device,     // interface
+                                                                                  defaultType);                        // entity
+                       if (path != NULL) {
+                               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+                               CFRelease(path);
+
+                               if (config == NULL) {
+                                       // if the "set" does not have a saved configuration, use
+                                       // the [template] "interface" configuration
+                                       if (interfacePrivate->unsaved != NULL) {
+                                               config = CFDictionaryGetValue(interfacePrivate->unsaved, defaultType);
+                                               if (config == (CFDictionaryRef)kCFNull) {
+                                                       config = NULL;
+                                               }
+                                       }
+                               }
+                               if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
+                                       config = NULL;
+                               }
+                       }
+               }
+       }
+
+       return config;
+}
+
+
+static CFDictionaryRef
+__SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef     interface,
+                                    CFStringRef                extendedType)
+{
+       CFDictionaryRef                 config                  = NULL;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFArrayRef                      paths;
+
+       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+       paths = copyConfigurationPaths(interfacePrivate, extendedType);
+       if (paths != NULL) {
+               CFStringRef                     path;
+
+               path = CFArrayGetValueAtIndex(paths, 0);
+               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+
+               CFRelease(paths);
+       } else {
+               if (interfacePrivate->unsaved != NULL) {
+                       config = CFDictionaryGetValue(interfacePrivate->unsaved, extendedType);
+                       if (config == (CFDictionaryRef)kCFNull) {
+                               config = NULL;
+                       }
+               }
+       }
+
+       if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
+               config = NULL;
+       }
+
+       return config;
+}
+
+
+CFDictionaryRef
+SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface)
+{
+       CFDictionaryRef config;
+       CFStringRef     defaultType;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
+       if (defaultType == NULL) {
+               return NULL;
+       }
+
+       config = __SCNetworkInterfaceGetConfiguration(interface, defaultType);
+       if (config == NULL) {
+               if (CFEqual(defaultType, kSCEntNetAirPort)) {
+                       SCNetworkInterfacePrivateRef    interfacePrivate;
+                       CFStringRef                     path;
+
+                       // if AirPort interface, check for a per-service config
+                       interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
+                       path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
+                                                                             interfacePrivate->serviceID,      // service
+                                                                             kSCEntNetAirPort);                // entity
+                       config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+                       CFRelease(path);
+               }
+       }
+       if (config == NULL) {
+               _SCErrorSet(kSCStatusOK);
+       }
+
+       return config;
+}
+
+
+CFDictionaryRef
+SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef       interface,
+                                          CFStringRef                  extendedType)
+{
+       CFDictionaryRef config;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       config = __SCNetworkInterfaceGetConfiguration(interface, extendedType);
+       if (config == NULL) {
+               _SCErrorSet(kSCStatusOK);
+       }
+
+       return config;
+}
+
+
+__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)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if ((interfacePrivate->interface != NULL) &&
+           (interfacePrivate->interface != kSCNetworkInterfaceIPv4)) {
+               _SCErrorSet(kSCStatusOK);
+               return NULL;
+       }
+
+       return interfacePrivate->entity_device;
+}
+
+
+CFStringRef
+SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if ((interfacePrivate->address != NULL) &&
+           (interfacePrivate->addressString == NULL)) {
+               uint8_t         *bp;
+               char            *cp;
+               size_t          n;
+               char            mac[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
+               char            *mac_p  = mac;
+
+               bp = (uint8_t *)CFDataGetBytePtr(interfacePrivate->address);
+               n  = CFDataGetLength(interfacePrivate->address) * 3;
+
+               if (n > sizeof(mac)) {
+                       mac_p = CFAllocatorAllocate(NULL, n, 0);
+               }
+
+               for (cp = mac_p; n > 0; n -= 3) {
+                       cp += snprintf(cp, n, "%2.2x:", *bp++);
+               }
+
+               interfacePrivate->addressString = CFStringCreateWithCString(NULL, mac_p, kCFStringEncodingUTF8);
+               if (mac_p != mac)       CFAllocatorDeallocate(NULL, mac_p);
+       }
+
+       return interfacePrivate->addressString;
+}
+
+
+SCNetworkInterfaceRef
+SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       return interfacePrivate->interface;
+}
+
+
+CFStringRef
+SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       return interfacePrivate->interface_type;
+}
+
+
+static CFStringRef
+copy_string_from_bundle(CFBundleRef bundle, CFStringRef key, Boolean localized)
+{
+       CFStringRef     str     = NULL;
+
+       if (localized) {
+               str = CFBundleCopyLocalizedString(bundle,
+                                                 key,
+                                                 key,
+                                                 NETWORKINTERFACE_LOCALIZATIONS);
+       } else {
+               str = _SC_CFBundleCopyNonLocalizedString(bundle,
+                                                        key,
+                                                        key,
+                                                        NETWORKINTERFACE_LOCALIZATIONS);
+       }
+
+       return str;
+}
+
+
+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)
+{
+       CFMutableStringRef      local;
+       CFStringRef             name;
+
+       local = CFStringCreateMutable(NULL, 0);
+
+       while (interface != NULL) {
+               Boolean                         added                   = FALSE;
+               SCNetworkInterfaceRef           child                   = NULL;
+               SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+               if ((interfacePrivate->interface != NULL) &&
+                   (interfacePrivate->interface != kSCNetworkInterfaceIPv4) &&
+                   !CFEqual(interfacePrivate->interface_type, kSCNetworkInterfaceTypeVPN)) {
+                       child = interfacePrivate->interface;
+               }
+
+               if ((bundle != NULL) && (interfacePrivate->localized_key != NULL)) {
+                       CFStringRef     fmt;
+                       CFStringRef     key     = interfacePrivate->localized_key;
+
+                       if (oldLocalization) {
+                               key = CFStringCreateWithFormat(NULL, NULL, CFSTR("X-%@"),
+                                                              interfacePrivate->localized_key);
+                       }
+                       fmt = copy_interface_string(bundle, key, localized);
+                       if (fmt != NULL) {
+                               CFStringAppendFormat(local,
+                                                    NULL,
+                                                    fmt,
+                                                    interfacePrivate->localized_arg1,
+                                                    interfacePrivate->localized_arg2);
+                               CFRelease(fmt);
+                               added = TRUE;
+                       }
+                       if (oldLocalization) {
+                               CFRelease(key);
+                       }
+               }
+
+               if (!added &&
+                   (interfacePrivate->prefs != NULL) &&
+                   (interfacePrivate->serviceID != NULL) &&
+                   (child == NULL)) {
+                       CFDictionaryRef entity;
+                       CFStringRef     path;
+
+                       // check for (and use) the name of the interface when it
+                       // was last available
+                       path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,
+                                                                             interfacePrivate->serviceID,
+                                                                             kSCEntNetInterface);
+                       entity = SCPreferencesPathGetValue(interfacePrivate->prefs, path);
+                       CFRelease(path);
+                       if (isA_CFDictionary(entity)) {
+                               CFStringRef     name;
+
+                               name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
+                               if (isA_CFString(name)) {
+                                       CFStringAppend(local, name);
+                                       added = TRUE;
+                               }
+                       }
+               }
+
+               if (!added) {
+                       // create (non-)localized name based on the interface type
+                       CFStringAppend(local, interfacePrivate->interface_type);
+
+                       // ... and, if this is a leaf node, the interface device
+                       if ((interfacePrivate->entity_device != NULL) && (child == NULL)) {
+                               CFStringAppendFormat(local, NULL, CFSTR(" (%@)"), interfacePrivate->entity_device);
+                       }
+               }
+
+               if (child != NULL) {
+                       // if this interface is layered over another
+                       CFStringAppend(local, CFSTR(" --> "));
+               }
+
+               interface = child;
+       }
+
+       name = CFStringCreateCopy(NULL, local);
+       CFRelease(local);
+
+       return name;
+}
+
+
+#if    !TARGET_OS_IPHONE
+__private_extern__
+CFStringRef
+__SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface)
+{
+       CFStringRef                     name;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       name = copy_display_name(interface, TRUE, TRUE);
+       return name;
+}
+
+
+__private_extern__
+CFStringRef
+__SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface)
+{
+       CFStringRef                     localized_name;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       localized_name = copy_display_name(interface, FALSE, TRUE);
+       return localized_name;
+}
+#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__
+CFStringRef
+__SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (interfacePrivate->name == NULL) {
+               interfacePrivate->name = copy_display_name(interface, FALSE, FALSE);
+       }
+
+       return interfacePrivate->name;
+}
+
+
+CFStringRef
+SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
+       if (interfacePrivate->localized_name == NULL) {
+               interfacePrivate->localized_name = copy_display_name(interface, TRUE, FALSE);
+       }
+
+       return interfacePrivate->localized_name;
+}
+
+
+__private_extern__
+CFPropertyListRef
+__SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface, CFStringRef overrideType)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFPropertyListRef               overrides               = NULL;
+
+       if (interfacePrivate->overrides != NULL) {
+               overrides = CFDictionaryGetValue(interfacePrivate->overrides, overrideType);
+       }
+
+       return overrides;
+}
+
+
+CFTypeID
+SCNetworkInterfaceGetTypeID(void)
+{
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);     /* initialize runtime */
+       return __kSCNetworkInterfaceTypeID;
+}
+
+
+__private_extern__
+Boolean
+__SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef            set,
+                                           SCNetworkInterfaceRef       interface,
+                                           CFStringRef                 defaultType,
+                                           CFDictionaryRef             config,
+                                           Boolean                     okToHold)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       Boolean                         ok                      = FALSE;
+
+       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+       if (defaultType == NULL) {
+               defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
+               if (defaultType == NULL) {
+                       return FALSE;
+               }
+       }
+
+       if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
+               config = NULL;
+       }
+
+       if (set != NULL) {
+               CFStringRef     path;
+
+               path = SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL,                                // allocator
+                                                                          SCNetworkSetGetSetID(set),           // set
+                                                                          interfacePrivate->entity_device,     // interface
+                                                                          defaultType);                        // entity
+               if (path != NULL) {
+                       ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE);
+                       CFRelease(path);
+                       if (ok) {
+                               // if configuration has been saved
+                               if (interfacePrivate->unsaved != NULL) {
+                                       CFDictionaryRemoveValue(interfacePrivate->unsaved, defaultType);
+                                       if (CFDictionaryGetCount(interfacePrivate->unsaved) == 0) {
+                                               CFRelease(interfacePrivate->unsaved);
+                                               interfacePrivate->unsaved = NULL;
+                                       }
+                               }
+                       }
+               } else {
+                       if (okToHold) {
+                               if (config == NULL) {
+                                       // remember that we are clearing the configuration
+                                       config = (CFDictionaryRef)kCFNull;
+                               }
+
+                               if (interfacePrivate->unsaved == NULL) {
+                                       interfacePrivate->unsaved = CFDictionaryCreateMutable(NULL,
+                                                                                             0,
+                                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(interfacePrivate->unsaved, defaultType, config);
+                               ok = TRUE;
+                       } else {
+                               _SCErrorSet(kSCStatusNoKey);
+                       }
+               }
+       }
+
+       return ok;
+}
+
+
+__private_extern__
+Boolean
+__SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef     interface,
+                                    CFStringRef                extendedType,
+                                    CFDictionaryRef            config,
+                                    Boolean                    okToHold)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       Boolean                         ok                      = FALSE;
+       CFArrayRef                      paths;
+
+       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+
+       if (extendedType == NULL) {
+               extendedType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
+               if (extendedType == NULL) {
+                       return FALSE;
+               }
+       }
+
+       if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
+               config = NULL;
+       }
+
+       paths = copyConfigurationPaths(interfacePrivate, extendedType);
+       if (paths != NULL) {
+               CFIndex                         i;
+               CFIndex                         n;
+
+               n = CFArrayGetCount(paths);
+               for (i = 0; i < n; i++) {
+                       CFStringRef     path;
+
+                       path = CFArrayGetValueAtIndex(paths, i);
+                       ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE);
+                       if (!ok) {
+                               break;
+                       }
+               }
+
+               if (ok) {
+                       // if configuration has been saved
+                       if (interfacePrivate->unsaved != NULL) {
+                               CFDictionaryRemoveValue(interfacePrivate->unsaved, extendedType);
+                               if (CFDictionaryGetCount(interfacePrivate->unsaved) == 0) {
+                                       CFRelease(interfacePrivate->unsaved);
+                                       interfacePrivate->unsaved = NULL;
+                               }
+                       }
+               }
+
+               CFRelease(paths);
+       } else {
+               if (okToHold) {
+                       if (config == NULL) {
+                               // remember that we are clearing the configuration
+                               config = (CFDictionaryRef)kCFNull;
+                       }
+
+                       if (interfacePrivate->unsaved == NULL) {
+                               interfacePrivate->unsaved = CFDictionaryCreateMutable(NULL,
+                                                                                     0,
+                                                                                     &kCFTypeDictionaryKeyCallBacks,
+                                                                                     &kCFTypeDictionaryValueCallBacks);
+                       }
+                       CFDictionarySetValue(interfacePrivate->unsaved, extendedType, config);
+                       ok = TRUE;
+               } else {
+                       _SCErrorSet(kSCStatusNoKey);
+               }
+       }
+
+       return ok;
+}
+
+
+Boolean
+SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionaryRef config)
+{
+       CFStringRef     defaultType;
+       Boolean         ok;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
+       if (defaultType == NULL) {
+               return FALSE;
+       }
+
+       ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
+                      interface,
+                      config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+       }
+
+       return ok;
+}
+
+
+Boolean
+SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef       interface,
+                                          CFStringRef                  extendedType,
+                                          CFDictionaryRef              config)
+{
+       Boolean         ok;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) {
+               return 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 -
+#pragma mark SCNetworkInterface [Refresh Configuration] API
+
+
+Boolean
+_SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName)
+{
+       CFStringRef             key;
+       Boolean                 ok     = FALSE;
+
+       if (!isA_CFString(ifName)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                           kSCDynamicStoreDomainState,
+                                                           ifName,
+                                                           kSCEntNetRefreshConfiguration);
+       ok = SCDynamicStoreNotifyValue(NULL, key);
+       CFRelease(key);
+       return ok;
+}
+
+
+static Boolean
+__SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs, CFStringRef ifName)
+{
+       CFDataRef               data            = NULL;
+       Boolean                 ok;
+       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+       uint32_t                status          = kSCStatusOK;
+       CFDataRef               reply           = NULL;
+
+       if (prefsPrivate->helper_port == MACH_PORT_NULL) {
+               ok = __SCPreferencesCreate_helper(prefs);
+               if (!ok) {
+                       return FALSE;
+               }
+       }
+
+       // serialize the interface name
+       ok = _SCSerializeString(ifName, &data, NULL, NULL);
+       if (!ok) {
+               goto fail;
+       }
+
+       // have the helper "refresh" the configuration
+       status = kSCStatusOK;
+       reply  = NULL;
+       ok = _SCHelperExec(prefsPrivate->helper_port,
+                          SCHELPER_MSG_INTERFACE_REFRESH,
+                          data,
+                          &status,
+                          NULL);
+       if (data != NULL) CFRelease(data);
+       if (!ok) {
+               goto fail;
+       }
+
+       if (status != kSCStatusOK) {
+               goto error;
+       }
+
+       return TRUE;
+
+    fail :
+
+       // close helper
+       if (prefsPrivate->helper_port != MACH_PORT_NULL) {
+               _SCHelperClose(&prefsPrivate->helper_port);
+       }
+
+       status = kSCStatusAccessError;
+
+    error :
+
+       // return error
+       _SCErrorSet(status);
+       return FALSE;
+}
+
+
+Boolean
+SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface)
+{
+       CFStringRef                     ifName;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       ifName = SCNetworkInterfaceGetBSDName(interface);
+       if (ifName == NULL) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (interfacePrivate->prefs != NULL) {
+               SCPreferencesRef                prefs           = interfacePrivate->prefs;
+               SCPreferencesPrivateRef         prefsPrivate    = (SCPreferencesPrivateRef)prefs;
+
+               if (prefsPrivate->authorizationData != NULL) {
+                       return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs, ifName);
+               }
+       }
+
+       return _SCNetworkInterfaceForceConfigurationRefresh(ifName);
+}
+
+
+#if    !TARGET_OS_IPHONE
+Boolean
+SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName)
+{
+       return _SCNetworkInterfaceForceConfigurationRefresh(ifName);
+}
+#endif // !TARGET_OS_IPHONE
+
+
+#pragma mark -
+#pragma mark SCNetworkInterface Password APIs
+
+
+static CFStringRef
+getPasswordID(CFDictionaryRef config, CFStringRef serviceID)
+{
+       CFStringRef     unique_id       = NULL;
+
+       if (config != NULL) {
+               CFStringRef     encryption;
+
+               encryption = CFDictionaryGetValue(config, kSCPropNetPPPAuthPasswordEncryption);
+               if (isA_CFString(encryption) &&
+                   CFEqual(encryption, kSCValNetPPPAuthPasswordEncryptionKeychain)) {
+                       unique_id = CFDictionaryGetValue(config, kSCPropNetPPPAuthPassword);
+               }
+       }
+       if (unique_id == NULL) {
+               unique_id = serviceID;
+       }
+
+       return unique_id;
+}
+
+
+static CFStringRef
+copySharedSecretID(CFDictionaryRef config, CFStringRef serviceID)
+{
+       CFMutableStringRef      shared_id       = NULL;
+
+       if (config != NULL) {
+               CFStringRef     encryption;
+
+               encryption = CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecretEncryption);
+               if (isA_CFString(encryption) &&
+                   CFEqual(encryption, kSCValNetIPSecSharedSecretEncryptionKeychain)) {
+                       shared_id = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecret);
+                       if (shared_id != NULL) {
+                               CFRetain(shared_id);
+                       }
+               }
+       }
+
+       if (shared_id == NULL) {
+               CFStringRef     unique_id;
+
+               unique_id = getPasswordID(config, serviceID);
+               shared_id = CFStringCreateMutableCopy(NULL, 0, unique_id);
+               CFStringAppend(shared_id, CFSTR(".SS"));
+       }
+
+       return shared_id;
+}
+
+
+static CFStringRef
+copyXAuthID(CFDictionaryRef config, CFStringRef serviceID)
+{
+       CFMutableStringRef      xauth_id        = NULL;
+
+       if (config != NULL) {
+               CFStringRef     encryption;
+
+               encryption = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPasswordEncryption);
+               if (isA_CFString(encryption) &&
+                   CFEqual(encryption, kSCValNetIPSecXAuthPasswordEncryptionKeychain)) {
+                       xauth_id = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecXAuthPassword);
+                       if (xauth_id != NULL) {
+                               CFRetain(xauth_id);
+                       }
                }
+       }
 
-               if (childPrivate->entity_device != NULL) {
-                       parentPrivate->entity_device = CFStringCreateCopy(NULL, childPrivate->entity_device);
+       if (xauth_id == NULL) {
+               CFStringRef     unique_id;
+
+               unique_id = getPasswordID(config, serviceID);
+               xauth_id = CFStringCreateMutableCopy(NULL, 0, unique_id);
+               CFStringAppend(xauth_id, CFSTR(".XAUTH"));
+       }
+
+       return xauth_id;
+}
+
+
+static Boolean
+checkInterfacePassword(SCNetworkInterfaceRef           interface,
+                      SCNetworkInterfacePasswordType   passwordType,
+                      SCPreferencesRef                 *prefs,
+                      CFStringRef                      *serviceID)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       if (!isA_SCNetworkInterface(interface)) {
+               goto error;
+       }
+
+       *serviceID = interfacePrivate->serviceID;
+       if (*serviceID == NULL) {
+               goto error;
+       }
+
+       *prefs = interfacePrivate->prefs;
+       if (*prefs == NULL) {
+               goto error;
+       }
+
+       switch (passwordType) {
+               case kSCNetworkInterfacePasswordTypePPP : {
+                       CFStringRef     interfaceType;
+
+                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
+                               // if PPP
+                               break;
+                       }
+
+                       goto error;
                }
-       } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
-               if ((childIndex == kCFNotFound) ||
-                   ((configurations[childIndex].supported_interfaces & doL2TP) != doL2TP)) {
-                       // if the child interface does not support L2TP
-                       goto fail;
+
+               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+                       CFStringRef     interfaceType;
+
+                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
+                               interface = SCNetworkInterfaceGetInterface(interface);
+                               if (interface != NULL) {
+                                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
+                                               // if PPP->L2TP interface
+                                               break;
+                                       }
+                               }
+                       } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
+                               // if IPSec interface
+                               break;
+                       }
+
+                       goto error;
                }
-               parentPrivate->interface_type = kSCNetworkInterfaceTypeL2TP;
-               parentPrivate->localized_key  = CFSTR("l2tp");
-               parentPrivate->entity_type    = kSCValNetInterfaceSubTypeL2TP;  // interface config goes into "L2TP"
-       } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) {
-               if ((childIndex == kCFNotFound) ||
-                   ((configurations[childIndex].supported_interfaces & doPPTP) != doPPTP)) {
-                       // if the child interface does not support PPTP
-                       goto fail;
+
+               case kSCNetworkInterfacePasswordTypeEAPOL : {
+                       break;
                }
-               parentPrivate->interface_type = kSCNetworkInterfaceTypePPTP;
-               parentPrivate->localized_key  = CFSTR("pptp");
-               parentPrivate->entity_type    = kSCValNetInterfaceSubTypePPTP;  // interface config goes into "PPTP"
-       } else if (CFEqual(interfaceType, kSCNetworkInterfaceType6to4)) {
-               if ((childIndex == kCFNotFound) ||
-                   ((configurations[childIndex].supported_interfaces & do6to4) != do6to4)) {
-                       // if the child interface does not support 6to4
-                       goto fail;
+
+               case kSCNetworkInterfacePasswordTypeIPSecXAuth : {
+                       CFStringRef     interfaceType;
+
+                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
+                               // if IPSec interface
+                               break;
+                       }
+
+                       goto error;
                }
 
-               parentPrivate->interface_type = kSCNetworkInterfaceType6to4;
-               parentPrivate->localized_key  = CFSTR("6to4");
-               parentPrivate->entity_type    = kSCEntNet6to4;
-               parentPrivate->entity_device  = CFRetain(CFSTR("stf0"));
-       } else if (CFStringFind(interfaceType, CFSTR("."), 0).location != kCFNotFound) {
-               // if custom interface type
-               parentPrivate->interface_type = interfaceType;
-               parentPrivate->entity_type    = interfaceType;                  // interface config goes into a
-                                                                               // a dictionary with the same
-                                                                               // name as the interfaceType
-       } else {
-               // unknown interface type
-               goto fail;
-       }
+               case kSCNetworkInterfacePasswordTypeVPN : {
+                       CFStringRef     interfaceType;
 
-       if (childPrivate->overrides != NULL) {
-               parentPrivate->overrides = CFDictionaryCreateMutableCopy(NULL, 0, childPrivate->overrides);
-       };
-       parentPrivate->sort_order = childPrivate->sort_order;
+                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
+                       if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) {
+                               // if VPN interface
+                               break;
+                       }
 
-       return (SCNetworkInterfaceRef)parentPrivate;
+                       goto error;
+               }
 
-    fail :
+               default :
+                       break;
+       }
+
+       return TRUE;
+
+    error :
 
-       CFRelease(parentPrivate);
        _SCErrorSet(kSCStatusInvalidArgument);
-       return NULL;
+       return FALSE;
 }
 
 
-static CFDictionaryRef
-__SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef     interface,
-                                    CFStringRef                extendedType)
+Boolean
+SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef          interface,
+                               SCNetworkInterfacePasswordType  passwordType)
 {
-       CFDictionaryRef                 config                  = NULL;
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-       CFArrayRef                      paths;
+       Boolean                 exists          = FALSE;
+       SCPreferencesRef        prefs           = NULL;
+       CFStringRef             serviceID       = NULL;
 
-       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
-       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
+               return FALSE;
+       }
 
-       paths = copyConfigurationPaths(interfacePrivate, extendedType);
-       if (paths != NULL) {
-               CFStringRef                     path;
+       switch (passwordType) {
+               case kSCNetworkInterfacePasswordTypePPP : {
+                       CFDictionaryRef config;
+                       CFStringRef     unique_id;
 
-               path = CFArrayGetValueAtIndex(paths, 0);
-               config = __getPrefsConfiguration(interfacePrivate->prefs, path);
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-               CFRelease(paths);
-       } else {
-               if (interfacePrivate->unsaved != NULL) {
-                       config = CFDictionaryGetValue(interfacePrivate->unsaved, extendedType);
-                       if (config == (CFDictionaryRef)kCFNull) {
-                               config = NULL;
+                       // get serviceID
+                       unique_id = getPasswordID(config, serviceID);
+
+                       // check
+                       exists = __extract_password(prefs,
+                                                   config,
+                                                   kSCPropNetPPPAuthPassword,
+                                                   kSCPropNetPPPAuthPasswordEncryption,
+                                                   kSCValNetPPPAuthPasswordEncryptionKeychain,
+                                                   unique_id,
+                                                   NULL);
+                       break;
+               }
+
+               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+                       CFDictionaryRef config;
+                       Boolean         extended;
+                       CFStringRef     shared_id;
+
+                       // get configuration
+                       extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP);
+                       if (extended) {
+                               config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+                       } else {
+                               config = SCNetworkInterfaceGetConfiguration(interface);
                        }
+
+                       // get sharedSecret ID
+                       shared_id = copySharedSecretID(config, serviceID);
+
+                       // check
+                       exists = __extract_password(prefs,
+                                                   config,
+                                                   kSCPropNetIPSecSharedSecret,
+                                                   kSCPropNetIPSecSharedSecretEncryption,
+                                                   kSCValNetIPSecSharedSecretEncryptionKeychain,
+                                                   shared_id,
+                                                   NULL);
+                       CFRelease(shared_id);
+                       break;
                }
-       }
 
-       if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
-               config = NULL;
-       }
+               case kSCNetworkInterfacePasswordTypeEAPOL : {
+                       CFDictionaryRef config;
+                       CFStringRef     unique_id       = NULL;
 
-       return config;
-}
+                       // get configuration
+                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
 
+                       // get 802.1X identifier
+                       if (config != NULL) {
+                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+                       }
+                       if (!isA_CFString(unique_id)) {
+                               return FALSE;
+                       }
 
-CFDictionaryRef
-SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface)
-{
-       CFDictionaryRef config;
-       CFStringRef     defaultType;
+                       // check password
+                       exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id);
+                       break;
+               }
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+               case kSCNetworkInterfacePasswordTypeIPSecXAuth : {
+                       CFDictionaryRef config;
+                       CFStringRef     xauth_id;
 
-       defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
-       if (defaultType == NULL) {
-               return NULL;
-       }
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-       config = __SCNetworkInterfaceGetConfiguration(interface, defaultType);
-       if (config == NULL) {
-               if (CFEqual(defaultType, kSCEntNetAirPort)) {
-                       SCNetworkInterfacePrivateRef    interfacePrivate;
-                       CFStringRef                     path;
+                       // get XAuth ID
+                       xauth_id = copyXAuthID(config, serviceID);
 
-                       // if AirPort interface, check for a per-service config
-                       interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
-                       path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
-                                                                             interfacePrivate->serviceID,      // service
-                                                                             kSCEntNetAirPort);                // entity
-                       config = __getPrefsConfiguration(interfacePrivate->prefs, path);
-                       CFRelease(path);
+                       // check
+                       exists = __extract_password(prefs,
+                                                   config,
+                                                   kSCPropNetIPSecXAuthPassword,
+                                                   kSCPropNetIPSecXAuthPasswordEncryption,
+                                                   kSCValNetIPSecXAuthPasswordEncryptionKeychain,
+                                                   xauth_id,
+                                                   NULL);
+                       CFRelease(xauth_id);
+                       break;
                }
-       }
-       if (config == NULL) {
-               _SCErrorSet(kSCStatusOK);
+
+               case kSCNetworkInterfacePasswordTypeVPN : {
+                       CFDictionaryRef config;
+                       CFStringRef     vpn_id;
+
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
+
+                       // get serviceID
+                       vpn_id = getPasswordID(config, serviceID);
+
+                       // check
+                       exists = __extract_password(prefs,
+                                                   config,
+                                                   kSCPropNetVPNAuthPassword,
+                                                   kSCPropNetVPNAuthPasswordEncryption,
+                                                   kSCValNetVPNAuthPasswordEncryptionKeychain,
+                                                   vpn_id,
+                                                   NULL);
+                       break;
+               }
+
+               default :
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return FALSE;
        }
 
-       return config;
+       return exists;
 }
 
 
-CFDictionaryRef
-SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef       interface,
-                                          CFStringRef                  extendedType)
+CFDataRef
+SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef           interface,
+                              SCNetworkInterfacePasswordType   passwordType)
 {
-       CFDictionaryRef config;
-
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+       CFDataRef               password        = NULL;
+       SCPreferencesRef        prefs           = NULL;
+       CFStringRef             serviceID       = NULL;
 
-       if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
+       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
                return NULL;
        }
 
-       config = __SCNetworkInterfaceGetConfiguration(interface, extendedType);
-       if (config == NULL) {
-               _SCErrorSet(kSCStatusOK);
-       }
+       switch (passwordType) {
+               case kSCNetworkInterfacePasswordTypePPP : {
+                       CFDictionaryRef config;
+                       CFStringRef     unique_id;
 
-       return config;
-}
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
+                       // get serviceID
+                       unique_id = getPasswordID(config, serviceID);
 
-CFStringRef
-SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+                       // extract
+                       (void) __extract_password(prefs,
+                                                 config,
+                                                 kSCPropNetPPPAuthPassword,
+                                                 kSCPropNetPPPAuthPasswordEncryption,
+                                                 kSCValNetPPPAuthPasswordEncryptionKeychain,
+                                                 unique_id,
+                                                 &password);
+                       break;
+               }
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+                       CFDictionaryRef config;
+                       Boolean         extended;
+                       CFStringRef     shared_id;
 
-       if ((interfacePrivate->interface != NULL) &&
-           (interfacePrivate->interface != kSCNetworkInterfaceIPv4)) {
-               _SCErrorSet(kSCStatusOK);
-               return NULL;
-       }
+                       // get configuration
+                       extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP);
+                       if (extended) {
+                               config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+                       } else {
+                               config = SCNetworkInterfaceGetConfiguration(interface);
+                       }
 
-       return interfacePrivate->entity_device;
-}
+                       // get sharedSecret ID
+                       shared_id = copySharedSecretID(config, serviceID);
 
+                       // extract
+                       (void) __extract_password(prefs,
+                                                 config,
+                                                 kSCPropNetIPSecSharedSecret,
+                                                 kSCPropNetIPSecSharedSecretEncryption,
+                                                 kSCValNetIPSecSharedSecretEncryptionKeychain,
+                                                 shared_id,
+                                                 &password);
 
-CFStringRef
-SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+                       CFRelease(shared_id);
+                       break;
+               }
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+               case kSCNetworkInterfacePasswordTypeEAPOL : {
+                       CFDictionaryRef config;
+                       CFStringRef     unique_id       = NULL;
 
-       if ((interfacePrivate->address != NULL) &&
-           (interfacePrivate->addressString == NULL)) {
-               uint8_t         *bp;
-               char            *cp;
-               CFIndex         n;
-               char            mac[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
-               char            *mac_p  = mac;
+                       // get configuration
+                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
 
-               bp = (uint8_t *)CFDataGetBytePtr(interfacePrivate->address);
-               n  = CFDataGetLength(interfacePrivate->address) * 3;
+                       // get 802.1X identifier
+                       if (config != NULL) {
+                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+                       }
+                       if (!isA_CFString(unique_id)) {
+                               _SCErrorSet(kSCStatusFailed);
+                               return NULL;
+                       }
 
-               if (n > sizeof(mac)) {
-                       mac_p = CFAllocatorAllocate(NULL, 0, n);
+                       // copy password
+                       password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id);
+                       break;
                }
 
-               for (cp = mac_p; n > 0; n -= 3) {
-                       cp += snprintf(cp, n, "%2.2x:", *bp++);
+               case kSCNetworkInterfacePasswordTypeIPSecXAuth : {
+                       CFDictionaryRef config;
+                       CFStringRef     xauth_id;
+
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
+
+                       // get XAuth ID
+                       xauth_id = copyXAuthID(config, serviceID);
+
+                       // extract
+                       (void) __extract_password(prefs,
+                                                 config,
+                                                 kSCPropNetIPSecXAuthPassword,
+                                                 kSCPropNetIPSecXAuthPasswordEncryption,
+                                                 kSCValNetIPSecXAuthPasswordEncryptionKeychain,
+                                                 xauth_id,
+                                                 &password);
+                       CFRelease(xauth_id);
+                       break;
                }
 
-               interfacePrivate->addressString = CFStringCreateWithCString(NULL, mac_p, kCFStringEncodingUTF8);
-               if (mac_p != mac)       CFAllocatorDeallocate(NULL, mac_p);
-       }
+               case kSCNetworkInterfacePasswordTypeVPN : {
+                       CFDictionaryRef config;
+                       CFStringRef     vpn_id;
 
-       return interfacePrivate->addressString;
-}
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
+                       // get serviceID
+                       vpn_id = getPasswordID(config, serviceID);
 
-SCNetworkInterfaceRef
-SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+                       // extract
+                       (void) __extract_password(prefs,
+                                                 config,
+                                                 kSCPropNetVPNAuthPassword,
+                                                 kSCPropNetVPNAuthPasswordEncryption,
+                                                 kSCValNetVPNAuthPasswordEncryptionKeychain,
+                                                 vpn_id,
+                                                 &password);
+                       break;
+               }
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
+               default :
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return NULL;
        }
 
-       return interfacePrivate->interface;
+       return password;
 }
 
 
-CFStringRef
-SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface)
+Boolean
+SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef         interface,
+                                SCNetworkInterfacePasswordType passwordType)
 {
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       Boolean                 ok              = FALSE;
+       SCPreferencesRef        prefs           = NULL;
+       CFStringRef             serviceID       = NULL;
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
+       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
+               return FALSE;
        }
 
-       return interfacePrivate->interface_type;
-}
+       switch (passwordType) {
+               case kSCNetworkInterfacePasswordTypePPP : {
+                       CFDictionaryRef config;
+                       CFDictionaryRef newConfig       = NULL;
+                       CFStringRef     unique_id;
 
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-static CFStringRef
-copy_interface_string(CFBundleRef bundle, CFStringRef key, Boolean localized)
-{
-       CFStringRef     str     = NULL;
+                       // get serviceID
+                       unique_id = getPasswordID(config, serviceID);
 
-       if (localized) {
-               str = CFBundleCopyLocalizedString(bundle,
-                                                 key,
-                                                 key,
-                                                 NETWORKINTERFACE_LOCALIZATIONS);
-       } else {
-               str = _SC_CFBundleCopyNonLocalizedString(bundle,
-                                                        key,
-                                                        key,
-                                                        NETWORKINTERFACE_LOCALIZATIONS);
-       }
+                       // remove password
+                       ok = __remove_password(prefs,
+                                              config,
+                                              kSCPropNetPPPAuthPassword,
+                                              kSCPropNetPPPAuthPasswordEncryption,
+                                              kSCValNetPPPAuthPasswordEncryptionKeychain,
+                                              unique_id,
+                                              &newConfig);
+                       if (ok) {
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               if (newConfig != NULL) CFRelease(newConfig);
+                       }
 
-       return str;
-}
+                       break;
+               }
 
+               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+                       CFDictionaryRef config;
+                       Boolean         extended;
+                       CFDictionaryRef newConfig       = NULL;
+                       CFStringRef     shared_id;
 
-static CFStringRef
-copy_display_name(SCNetworkInterfaceRef interface, Boolean localized)
-{
-       CFMutableStringRef      local;
-       CFStringRef             name;
+                       // get configuration
+                       extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP);
+                       if (extended) {
+                               config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+                       } else {
+                               config = SCNetworkInterfaceGetConfiguration(interface);
+                       }
 
-       local = CFStringCreateMutable(NULL, 0);
+                       // get sharedSecret ID
+                       shared_id = copySharedSecretID(config, serviceID);
 
-       while (interface != NULL) {
-               Boolean                         added                   = FALSE;
-               SCNetworkInterfaceRef           child                   = NULL;
-               SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+                       // remove password
+                       ok = __remove_password(prefs,
+                                              config,
+                                              kSCPropNetIPSecSharedSecret,
+                                              kSCPropNetIPSecSharedSecretEncryption,
+                                              kSCValNetIPSecSharedSecretEncryptionKeychain,
+                                              shared_id,
+                                              &newConfig);
+                       if (ok) {
+                               if (extended) {
+                                       ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+                                                                                       kSCEntNetIPSec,
+                                                                                       newConfig);
+                               } else {
+                                       ok = SCNetworkInterfaceSetConfiguration(interface,
+                                                                               newConfig);
+                               }
+                               if (newConfig != NULL) CFRelease(newConfig);
+                       }
 
-               if ((interfacePrivate->interface != NULL) &&
-                   (interfacePrivate->interface != kSCNetworkInterfaceIPv4)) {
-                       child = interfacePrivate->interface;
+                       CFRelease(shared_id);
+                       break;
                }
 
-               if ((bundle != NULL) && (interfacePrivate->localized_key != NULL)) {
-                       CFStringRef     fmt;
+               case kSCNetworkInterfacePasswordTypeEAPOL : {
+                       CFDictionaryRef config;
+                       CFStringRef     unique_id       = NULL;
 
-                       fmt = copy_interface_string(bundle, interfacePrivate->localized_key, localized);
-                       if (fmt != NULL) {
-                               CFStringAppendFormat(local,
-                                                    NULL,
-                                                    fmt,
-                                                    interfacePrivate->localized_arg1,
-                                                    interfacePrivate->localized_arg2);
-                               CFRelease(fmt);
-                               added = TRUE;
+                       // get configuration
+                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+
+                       // get 802.1X identifier
+                       if (config != NULL) {
+                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+                       }
+                       if (!isA_CFString(unique_id)) {
+                               _SCErrorSet(kSCStatusFailed);
+                               return FALSE;
                        }
+
+                       // remove password
+                       ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
+                       break;
                }
 
-               if (!added &&
-                   (interfacePrivate->prefs != NULL) &&
-                   (interfacePrivate->serviceID != NULL) &&
-                   (child == NULL)) {
-                       CFDictionaryRef entity;
-                       CFStringRef     path;
+               case kSCNetworkInterfacePasswordTypeIPSecXAuth : {
+                       CFDictionaryRef config;
+                       CFDictionaryRef newConfig       = NULL;
+                       CFStringRef     xauth_id;
 
-                       // check for (and use) the name of the interface when it
-                       // was last available
-                       path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,
-                                                                             interfacePrivate->serviceID,
-                                                                             kSCEntNetInterface);
-                       entity = SCPreferencesPathGetValue(interfacePrivate->prefs, path);
-                       CFRelease(path);
-                       if (isA_CFDictionary(entity)) {
-                               CFStringRef     name;
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-                               name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
-                               if (isA_CFString(name)) {
-                                       CFStringAppend(local, name);
-                                       added = TRUE;
-                               }
+                       // get XAuth ID
+                       xauth_id = copyXAuthID(config, serviceID);
+
+                       // remove password
+                       ok = __remove_password(prefs,
+                                              config,
+                                              kSCPropNetIPSecXAuthPassword,
+                                              kSCPropNetIPSecXAuthPasswordEncryption,
+                                              kSCValNetIPSecXAuthPasswordEncryptionKeychain,
+                                              xauth_id,
+                                              &newConfig);
+                       if (ok) {
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               if (newConfig != NULL) CFRelease(newConfig);
                        }
+
+                       CFRelease(xauth_id);
+                       break;
                }
 
-               if (!added) {
-                       // create (non-)localized name based on the interface type
-                       CFStringAppend(local, interfacePrivate->interface_type);
+               case kSCNetworkInterfacePasswordTypeVPN : {
+                       CFDictionaryRef config;
+                       CFDictionaryRef newConfig       = NULL;
+                       CFStringRef     vpn_id;
 
-                       // ... and, if this is a leaf node, the interface device
-                       if ((interfacePrivate->entity_device != NULL) && (child == NULL)) {
-                               CFStringAppendFormat(local, NULL, CFSTR(" (%@)"), interfacePrivate->entity_device);
-                       }
-               }
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-               if (child != NULL) {
-                       // if this interface is layered over another
-                       CFStringAppend(local, CFSTR(" --> "));
+                       // get serviceID
+                       vpn_id = getPasswordID(config, serviceID);
+
+                       // remove password
+                       ok = __remove_password(prefs,
+                                              config,
+                                              kSCPropNetVPNAuthPassword,
+                                              kSCPropNetVPNAuthPasswordEncryption,
+                                              kSCValNetVPNAuthPasswordEncryptionKeychain,
+                                              vpn_id,
+                                              &newConfig);
+                       if (ok) {
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               if (newConfig != NULL) CFRelease(newConfig);
+                       }
+                       break;
                }
 
-               interface = child;
+               default :
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       return FALSE;
        }
 
-       name = CFStringCreateCopy(NULL, local);
-       CFRelease(local);
-
-       return name;
+       return ok;
 }
 
 
-__private_extern__
-CFStringRef
-__SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface)
+Boolean
+SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef            interface,
+                             SCNetworkInterfacePasswordType    passwordType,
+                             CFDataRef                         password,
+                             CFDictionaryRef                   options)
 {
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef             account         = NULL;
+       CFDictionaryRef         config;
+       CFStringRef             description     = NULL;
+       CFStringRef             label           = NULL;
+       Boolean                 ok              = FALSE;
+       SCPreferencesRef        prefs           = NULL;
+       CFStringRef             serviceID       = NULL;
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
+       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
+               return FALSE;
        }
 
-       if (interfacePrivate->name == NULL) {
-               interfacePrivate->name = copy_display_name(interface, FALSE);
-       }
+       switch (passwordType) {
+               case kSCNetworkInterfacePasswordTypePPP : {
+                       SCNetworkServiceRef     service = NULL;
+                       CFStringRef             unique_id;
 
-       return interfacePrivate->name;
-}
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
+                       // get serviceID
+                       unique_id = getPasswordID(config, serviceID);
 
-CFStringRef
-SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+                       // get "Account", "Name", "Kind"
+                       if (config != NULL) {
+                               // auth name --> keychain "Account"
+                               account = CFDictionaryGetValue(config, kSCPropNetPPPAuthName);
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return NULL;
-       }
+                               // PPP [user defined] "name" --> keychain "Name"
+                               label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+                       }
 
-       if (interfacePrivate->localized_name == NULL) {
-               interfacePrivate->localized_name = copy_display_name(interface, TRUE);
-       }
+                       if (label == NULL) {
+                               // service name --> keychain "Name"
+                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+                                                                                              prefs,
+                                                                                              serviceID,
+                                                                                              interface);
 
-       return interfacePrivate->localized_name;
-}
+                               label = SCNetworkServiceGetName(service);
+                               if (label == NULL) {
+                                       // interface name --> keychain "Name"
+                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+                               }
+                       }
 
+                       if (bundle != NULL) {
+                               // "PPP Password" --> keychain "Kind"
+                               description = CFBundleCopyLocalizedString(bundle,
+                                                                         CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
+                                                                         CFSTR("PPP Password"),
+                                                                         NULL);
+                       }
 
-__private_extern__
-CFDictionaryRef
-__SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface, CFStringRef interfaceType)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-       CFDictionaryRef                 overrides               = NULL;
+                       // store password
+                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+                                                                        unique_id,
+                                                                        (label != NULL)       ? label       : CFSTR("Network Connection"),
+                                                                        (description != NULL) ? description : CFSTR("PPP Password"),
+                                                                        account,
+                                                                        password,
+                                                                        options);
+                       if (ok) {
+                               CFMutableDictionaryRef  newConfig;
 
-       if (interfacePrivate->overrides != NULL) {
-               overrides = CFDictionaryGetValue(interfacePrivate->overrides, interfaceType);
-       }
+                               if (config != NULL) {
+                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                               } else {
+                                       newConfig = CFDictionaryCreateMutable(NULL,
+                                                                             0,
+                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetPPPAuthPassword,
+                                                    unique_id);
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetPPPAuthPasswordEncryption,
+                                                    kSCValNetPPPAuthPasswordEncryptionKeychain);
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               CFRelease(newConfig);
+                       }
 
-       return overrides;
-}
+                       if (description != NULL) CFRelease(description);
+                       if (service     != NULL) CFRelease(service);
+                       break;
+               }
 
+               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
+                       CFDictionaryRef         baseConfig      = NULL;
+                       Boolean                 extended;
+                       SCNetworkServiceRef     service         = NULL;
+                       CFStringRef             shared_id;
 
-CFTypeID
-SCNetworkInterfaceGetTypeID(void)
-{
-       pthread_once(&initialized, __SCNetworkInterfaceInitialize);     /* initialize runtime */
-       return __kSCNetworkInterfaceTypeID;
-}
+                       // get configuration
+                       extended = CFEqual(SCNetworkInterfaceGetInterfaceType(interface), kSCNetworkInterfaceTypePPP);
+                       config = SCNetworkInterfaceGetConfiguration(interface);
+                       if (extended) {
+                               baseConfig = config;
+                               config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+                       }
 
+                       // get sharedSecret ID
+                       shared_id = copySharedSecretID(config, serviceID);
 
-__private_extern__
-Boolean
-__SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef     interface,
-                                    CFStringRef                extendedType,
-                                    CFDictionaryRef            config,
-                                    Boolean                    okToHold)
-{
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-       Boolean                         ok                      = FALSE;
-       CFArrayRef                      paths;
+                       // get "Account", "Name", "Kind"
+                       if (config != NULL) {
+                               CFStringRef     localIdentifier;
+                               CFStringRef     localIdentifierType;
+
+                               if (CFDictionaryGetValueIfPresent(config,
+                                                                 kSCPropNetIPSecLocalIdentifierType,
+                                                                 (const void **)&localIdentifierType)
+                                   && CFEqual(localIdentifierType, kSCValNetIPSecLocalIdentifierTypeKeyID)
+                                   && CFDictionaryGetValueIfPresent(config,
+                                                                    kSCPropNetIPSecLocalIdentifier,
+                                                                    (const void **)&localIdentifier)
+                                   && isA_CFString(localIdentifier)) {
+                                       // local identifier --> keychain "Account"
+                                       account = localIdentifier;
+                               }
 
-       /* initialize runtime (and kSCNetworkInterfaceIPv4) */
-       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+                               // PPP [user defined] "name" --> keychain "Name"
+                               if (!extended) {
+                                       label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+                               } else {
+                                       if (baseConfig != NULL) {
+                                               label = CFDictionaryGetValue(baseConfig, kSCPropUserDefinedName);
+                                       }
+                               }
+                       }
+
+                       if (label == NULL) {
+                               // service name --> keychain "Name"
+                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+                                                                                              prefs,
+                                                                                              serviceID,
+                                                                                              interface);
+
+                               label = SCNetworkServiceGetName(service);
+                               if (label == NULL) {
+                                       // interface name --> keychain "Name"
+                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+                               }
+                       }
+
+                       if (bundle != NULL) {
+                               // "IPSec Shared Secret" --> keychain "Kind"
+                               description = CFBundleCopyLocalizedString(bundle,
+                                                                         CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
+                                                                         CFSTR("IPSec Shared Secret"),
+                                                                         NULL);
+                       }
+
+                       // set password
+                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+                                                                        shared_id,
+                                                                        (label != NULL)       ? label       : CFSTR("Network Connection"),
+                                                                        (description != NULL) ? description : CFSTR("IPSec Shared Secret"),
+                                                                        account,
+                                                                        password,
+                                                                        options);
+                       if (ok) {
+                               CFMutableDictionaryRef  newConfig       = NULL;
+
+                               if (config != NULL) {
+                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                               } else {
+                                       newConfig = CFDictionaryCreateMutable(NULL,
+                                                                             0,
+                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetIPSecSharedSecret,
+                                                    shared_id);
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetIPSecSharedSecretEncryption,
+                                                    kSCValNetIPSecSharedSecretEncryptionKeychain);
+                               if (extended) {
+                                       ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+                                                                                       kSCEntNetIPSec,
+                                                                                       newConfig);
+                               } else {
+                                       ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               }
+                               CFRelease(newConfig);
+                       }
 
-       if (extendedType == NULL) {
-               extendedType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
-               if (extendedType == NULL) {
-                       return FALSE;
+                       if (description != NULL) CFRelease(description);
+                       if (service     != NULL) CFRelease(service);
+                       CFRelease(shared_id);
+                       break;
                }
-       }
-
-       if (isA_CFDictionary(config) && (CFDictionaryGetCount(config) == 0)) {
-               config = NULL;
-       }
 
-       paths = copyConfigurationPaths(interfacePrivate, extendedType);
-       if (paths != NULL) {
-               CFIndex                         i;
-               CFIndex                         n;
+               case kSCNetworkInterfacePasswordTypeEAPOL : {
+                       CFStringRef     account         = NULL;
+                       CFStringRef     unique_id       = NULL;
 
-               n = CFArrayGetCount(paths);
-               for (i = 0; i < n; i++) {
-                       CFStringRef     path;
+                       // get configuration
+                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
 
-                       path = CFArrayGetValueAtIndex(paths, i);
-                       ok = __setPrefsConfiguration(interfacePrivate->prefs, path, config, FALSE);
-                       if (!ok) {
-                               break;
+                       // get 802.1X identifier
+                       if (config != NULL) {
+                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
+                               unique_id = isA_CFString(unique_id);
                        }
-               }
+                       if (unique_id != NULL) {
+                               CFRetain(unique_id);
+                       } else {
+                               CFUUIDRef       uuid;
 
-               if (ok) {
-                       // if configuration has been saved
-                       if (interfacePrivate->unsaved != NULL) {
-                               CFDictionaryRemoveValue(interfacePrivate->unsaved, extendedType);
-                               if (CFDictionaryGetCount(interfacePrivate->unsaved) == 0) {
-                                       CFRelease(interfacePrivate->unsaved);
-                                       interfacePrivate->unsaved = NULL;
-                               }
+                               uuid      = CFUUIDCreate(NULL);
+                               unique_id = CFUUIDCreateString(NULL, uuid);
+                               CFRelease(uuid);
                        }
-               }
 
-               CFRelease(paths);
-       } else {
-               if (okToHold) {
-                       if (config == NULL) {
-                               // remember that we are clearing the configuration
-                               config = (CFDictionaryRef)kCFNull;
+                       // 802.1x UserName --> keychain "Account"
+                       if (config != NULL) {
+                               account = CFDictionaryGetValue(config, kEAPClientPropUserName);
                        }
 
-                       if (interfacePrivate->unsaved == NULL) {
-                               interfacePrivate->unsaved = CFDictionaryCreateMutable(NULL,
-                                                                                     0,
-                                                                                     &kCFTypeDictionaryKeyCallBacks,
-                                                                                     &kCFTypeDictionaryValueCallBacks);
-                       }
-                       CFDictionarySetValue(interfacePrivate->unsaved, extendedType, config);
-                       ok = TRUE;
-               } else {
-                       _SCErrorSet(kSCStatusNoKey);
-               }
-       }
+                       // get "Name", "Kind"
+                       if (bundle != NULL) {
+                               CFStringRef     interface_name;
+
+                               // "Network Connection (%@)" --> keychain "Name"
+                               interface_name = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+                               if (interface_name != NULL) {
+                                       CFStringRef     label_fmt;
+
+                                       label_fmt = CFBundleCopyLocalizedString(bundle,
+                                                                               CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
+                                                                               CFSTR("Network Connection (%@)"),
+                                                                               NULL);
+                                       label = CFStringCreateWithFormat(NULL, NULL, label_fmt, interface_name);
+                                       CFRelease(label_fmt);
+                               } else {
+                                       label = CFBundleCopyLocalizedString(bundle,
+                                                                           CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
+                                                                           CFSTR("Network Connection"),
+                                                                           NULL);
+                               }
 
-       return ok;
-}
+                               // "802.1X Password" --> keychain "Kind"
+                               description = CFBundleCopyLocalizedString(bundle,
+                                                                         CFSTR("KEYCHAIN_KIND_EAPOL"),
+                                                                         CFSTR("802.1X Password"),
+                                                                         NULL);
+                       }
 
+                       // set password
+                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+                                                                        unique_id,
+                                                                        (label != NULL)       ? label       : CFSTR("Network Connection"),
+                                                                        (description != NULL) ? description : CFSTR("802.1X Password"),
+                                                                        account,
+                                                                        password,
+                                                                        options);
+                       if (ok) {
+                               CFMutableDictionaryRef  newConfig       = NULL;
 
-Boolean
-SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface, CFDictionaryRef config)
-{
-       CFStringRef     defaultType;
+                               if (config != NULL) {
+                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                               } else {
+                                       newConfig = CFDictionaryCreateMutable(NULL,
+                                                                             0,
+                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(newConfig,
+                                                    kEAPClientPropUserPasswordKeychainItemID,
+                                                    unique_id);
+                               ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
+                                                                               kSCEntNetEAPOL,
+                                                                               newConfig);
+                               CFRelease(newConfig);
+                       }
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
+                       CFRelease(unique_id);
+                       if (label       != NULL) CFRelease(label);
+                       if (description != NULL) CFRelease(description);
+                       break;
+               }
 
-       defaultType = __SCNetworkInterfaceGetDefaultConfigurationType(interface);
-       if (defaultType == NULL) {
-               return FALSE;
-       }
+               case kSCNetworkInterfacePasswordTypeIPSecXAuth : {
+                       SCNetworkServiceRef     service = NULL;
+                       CFStringRef             xauth_id;
 
-       return __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, FALSE);
-}
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
+                       // get XAuth ID
+                       xauth_id = copyXAuthID(config, serviceID);
 
-Boolean
-SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef       interface,
-                                          CFStringRef                  extendedType,
-                                          CFDictionaryRef              config)
-{
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
+                       // get "Account", "Name", "Kind"
+                       if (config != NULL) {
+                               // auth name --> keychain "Account"
+                               account = CFDictionaryGetValue(config, kSCPropNetIPSecXAuthName);
 
-       if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface, extendedType, TRUE)) {
-               return FALSE;
-       }
+                               // IPSec [user defined] "name" --> keychain "Name"
+                               label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+                       }
 
-       return __SCNetworkInterfaceSetConfiguration(interface, extendedType, config, FALSE);
-}
+                       if (label == NULL) {
+                               // service name --> keychain "Name"
+                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+                                                                                              prefs,
+                                                                                              serviceID,
+                                                                                              interface);
 
+                               label = SCNetworkServiceGetName(service);
+                               if (label == NULL) {
+                                       // interface name --> keychain "Name"
+                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+                               }
+                       }
 
-#pragma mark -
-#pragma mark SCNetworkInterface [Refresh Configuration] API
+                       if (bundle != NULL) {
+                               // "IPSec XAuth Password" --> keychain "Kind"
+                               description = CFBundleCopyLocalizedString(bundle,
+                                                                         CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
+                                                                         CFSTR("IPSec XAuth Password"),
+                                                                         NULL);
+                       }
 
+                       // store password
+                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+                                                                        xauth_id,
+                                                                        (label != NULL)       ? label       : CFSTR("Network Connection"),
+                                                                        (description != NULL) ? description : CFSTR("IPSec XAuth Password"),
+                                                                        account,
+                                                                        password,
+                                                                        options);
+                       if (ok) {
+                               CFMutableDictionaryRef  newConfig;
 
-#ifndef kSCEntNetRefreshConfiguration
-#define kSCEntNetRefreshConfiguration  CFSTR("RefreshConfiguration")
-#endif // kSCEntNetRefreshConfiguration
+                               if (config != NULL) {
+                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                               } else {
+                                       newConfig = CFDictionaryCreateMutable(NULL,
+                                                                             0,
+                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetIPSecXAuthPassword,
+                                                    xauth_id);
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetIPSecXAuthPasswordEncryption,
+                                                    kSCValNetIPSecXAuthPasswordEncryptionKeychain);
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               CFRelease(newConfig);
+                       }
 
-Boolean
-_SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName)
-{
-       CFStringRef             key;
-       Boolean                 ok     = FALSE;
-       SCDynamicStoreRef       store;
+                       CFRelease(xauth_id);
+                       if (description != NULL) CFRelease(description);
+                       if (service     != NULL) CFRelease(service);
+                       break;
+               }
 
-       if (!isA_CFString(ifName)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
+               case kSCNetworkInterfacePasswordTypeVPN : {
+                       SCNetworkServiceRef     service = NULL;
+                       CFStringRef             vpn_id;
 
-       store = SCDynamicStoreCreate(NULL, CFSTR("_SCNetworkInterfaceForceConfigurationRefresh"), NULL, NULL);
-       if (store == NULL) {
-               return FALSE;
-       }
+                       // get configuration
+                       config = SCNetworkInterfaceGetConfiguration(interface);
 
-       key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
-                                                           kSCDynamicStoreDomainState,
-                                                           ifName,
-                                                           kSCEntNetRefreshConfiguration);
-       ok = SCDynamicStoreNotifyValue(store, key);
-       CFRelease(key);
-       CFRelease(store);
-       return ok;
-}
+                       // get serviceID
+                       vpn_id = getPasswordID(config, serviceID);
 
+                       // get "Account", "Name", "Kind"
+                       if (config != NULL) {
+                               // auth name --> keychain "Account"
+                               account = CFDictionaryGetValue(config, kSCPropNetVPNAuthName);
 
-static Boolean
-__SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs, CFStringRef ifName)
-{
-       CFDataRef               data            = NULL;
-       Boolean                 ok;
-       SCPreferencesPrivateRef prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-       uint32_t                status          = kSCStatusOK;
-       CFDataRef               reply           = NULL;
+                               // VPN [user defined] "name" --> keychain "Name"
+                               label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
+                       }
 
-       if (prefsPrivate->helper == -1) {
-               ok = __SCPreferencesCreate_helper(prefs);
-               if (!ok) {
-                       return FALSE;
-               }
-       }
+                       if (label == NULL) {
+                               // service name --> keychain "Name"
+                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
+                                                                                              prefs,
+                                                                                              serviceID,
+                                                                                              interface);
 
-       // serialize the interface name
-       ok = _SCSerializeString(ifName, &data, NULL, NULL);
-       if (!ok) {
-               goto fail;
-       }
+                               label = SCNetworkServiceGetName(service);
+                               if (label == NULL) {
+                                       // interface name --> keychain "Name"
+                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+                               }
+                       }
 
-       // have the helper "refresh" the configuration
-       status = kSCStatusOK;
-       reply  = NULL;
-       ok = _SCHelperExec(prefsPrivate->helper,
-                          SCHELPER_MSG_INTERFACE_REFRESH,
-                          data,
-                          &status,
-                          NULL);
-       if (data != NULL) CFRelease(data);
-       if (!ok) {
-               goto fail;
-       }
+                       if (bundle != NULL) {
+                               // "VPN Password" --> keychain "Kind"
+                               description = CFBundleCopyLocalizedString(bundle,
+                                                                         CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
+                                                                         CFSTR("VPN Password"),
+                                                                         NULL);
+                       }
 
-       if (status != kSCStatusOK) {
-               goto error;
-       }
+                       // store password
+                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
+                                                                        vpn_id,
+                                                                        (label != NULL)       ? label       : CFSTR("Network Connection"),
+                                                                        (description != NULL) ? description : CFSTR("VPN Password"),
+                                                                        account,
+                                                                        password,
+                                                                        options);
+                       if (ok) {
+                               CFMutableDictionaryRef  newConfig;
 
-       return TRUE;
+                               if (config != NULL) {
+                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
+                               } else {
+                                       newConfig = CFDictionaryCreateMutable(NULL,
+                                                                             0,
+                                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                                             &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetVPNAuthPassword,
+                                                    vpn_id);
+                               CFDictionarySetValue(newConfig,
+                                                    kSCPropNetVPNAuthPasswordEncryption,
+                                                    kSCValNetVPNAuthPasswordEncryptionKeychain);
+                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
+                               CFRelease(newConfig);
+                       }
 
-    fail :
+                       if (description != NULL) CFRelease(description);
+                       if (service     != NULL) CFRelease(service);
+                       break;
+               }
 
-       // close helper
-       if (prefsPrivate->helper != -1) {
-               _SCHelperClose(prefsPrivate->helper);
-               prefsPrivate->helper = -1;
+               default :
+                       _SCErrorSet(kSCStatusInvalidArgument);
+                       break;
        }
 
-       status = kSCStatusAccessError;
+       return ok;
+}
 
-    error :
+#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);
+}
 
-       // return error
-       _SCErrorSet(status);
-       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
-SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface)
+SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface,
+                             SCNetworkInterfaceAdvisory advisory,
+                             CFStringRef reason)
 {
+       IPMonitorControlRef             control;
+       SCNetworkInterfacePrivateRef    interfacePrivate =
+                                       (SCNetworkInterfacePrivateRef)interface;
        CFStringRef                     ifName;
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
-
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
 
        ifName = SCNetworkInterfaceGetBSDName(interface);
        if (ifName == NULL) {
                _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
-
-       if (interfacePrivate->prefs != NULL) {
-               SCPreferencesRef                prefs           = interfacePrivate->prefs;
-               SCPreferencesPrivateRef         prefsPrivate    = (SCPreferencesPrivateRef)prefs;
-
-               if (prefsPrivate->authorizationData != NULL) {
-                       return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs, ifName);
+               return (FALSE);
+       }
+       control = interfacePrivate->IPMonitorControl;
+       if (control == NULL) {
+               control = IPMonitorControlCreate();
+               if (control == NULL) {
+                       _SCErrorSet(kSCStatusFailed);
+                       return (FALSE);
                }
+               interfacePrivate->IPMonitorControl = control;
        }
-
-       return _SCNetworkInterfaceForceConfigurationRefresh(ifName);
+       return IPMonitorControlSetInterfaceAdvisory(control,
+                                                   ifName,
+                                                   advisory,
+                                                   reason);
 }
 
-
 Boolean
-SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName)
-{
-       return _SCNetworkInterfaceForceConfigurationRefresh(ifName);
-}
-
-
-#pragma mark -
-#pragma mark SCNetworkInterface Password APIs
-
-
-static CFStringRef
-getPasswordID(CFDictionaryRef config, CFStringRef serviceID)
+SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface)
 {
-       CFStringRef     unique_id       = NULL;
-
-       if (config != NULL) {
-               CFStringRef     encryption;
+       IPMonitorControlRef             control;
+       SCNetworkInterfacePrivateRef    interfacePrivate =
+                                       (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     ifName;
 
-               encryption = CFDictionaryGetValue(config, kSCPropNetPPPAuthPasswordEncryption);
-               if (isA_CFString(encryption) &&
-                   CFEqual(encryption, kSCValNetPPPAuthPasswordEncryptionKeychain)) {
-                       unique_id = CFDictionaryGetValue(config, kSCPropNetPPPAuthPassword);
+       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;
        }
-       if (unique_id == NULL) {
-               unique_id = serviceID;
-       }
-
-       return unique_id;
+       return IPMonitorControlInterfaceAdvisoryIsSet(control, ifName);
 }
 
-
-static CFStringRef
-copySharedSecretID(CFDictionaryRef config, CFStringRef serviceID)
+CFStringRef
+SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface)
 {
-       CFMutableStringRef      sharedSecret    = NULL;
-
-       if (config != NULL) {
-               CFStringRef     encryption;
-
-               encryption = CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecretEncryption);
-               if (isA_CFString(encryption) &&
-                   CFEqual(encryption, kSCValNetIPSecSharedSecretEncryptionKeychain)) {
-                       sharedSecret = (CFMutableStringRef)CFDictionaryGetValue(config, kSCPropNetIPSecSharedSecret);
-                       if (sharedSecret != NULL) {
-                               CFRetain(sharedSecret);
-                       }
-               }
-       }
-
-       if (sharedSecret == NULL) {
-               CFStringRef     unique_id;
+       CFStringRef                     ifName;
 
-               unique_id = getPasswordID(config, serviceID);
-               sharedSecret = CFStringCreateMutableCopy(NULL, 0, unique_id);
-               CFStringAppend(sharedSecret, CFSTR(".SS"));
+       ifName = SCNetworkInterfaceGetBSDName(interface);
+       if (ifName == NULL) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return (NULL);
        }
-
-       return sharedSecret;
+       return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName);
 }
+#endif /* TARGET_OS_SIMULATOR */
 
+#pragma mark -
+#pragma mark SCNetworkInterface [InterfaceNamer] SPIs
 
-static Boolean
-checkInterfacePassword(SCNetworkInterfaceRef           interface,
-                      SCNetworkInterfacePasswordType   passwordType,
-                      SCPreferencesRef                 *prefs,
-                      CFStringRef                      *serviceID)
+
+CFDictionaryRef
+_SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
 {
+       CFMutableDictionaryRef          info;
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     name;
 
-       if (!isA_SCNetworkInterface(interface)) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
+       if (interface == NULL) {
+               return NULL;
        }
 
-       *serviceID = interfacePrivate->serviceID;
-       if (*serviceID == NULL) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
-       }
+       info = CFDictionaryCreateMutable(NULL,
+                                        0,
+                                        &kCFTypeDictionaryKeyCallBacks,
+                                        &kCFTypeDictionaryValueCallBacks);
 
-       *prefs = interfacePrivate->prefs;
-       if (*prefs == NULL) {
-               _SCErrorSet(kSCStatusInvalidArgument);
-               return FALSE;
+       // add non-localized interface name
+       name = __SCNetworkInterfaceGetNonLocalizedDisplayName(interface);
+       if (name != NULL) {
+               CFDictionaryAddValue(info, kSCPropUserDefinedName, name);
        }
 
-       switch (passwordType) {
-               case kSCNetworkInterfacePasswordTypePPP : {
-                       CFStringRef     interfaceType;
-
-                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
-                       if (!CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
-                               _SCErrorSet(kSCStatusInvalidArgument);
-                               return FALSE;
-                       }
-                       break;
+       // 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);
                }
-
-               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
-                       CFStringRef             interfaceType;
-
-                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
-                       if (!CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
-                               _SCErrorSet(kSCStatusInvalidArgument);
-                               return FALSE;
-                       }
-
-                       interface = SCNetworkInterfaceGetInterface(interface);
-                       if (interface == NULL) {
-                               _SCErrorSet(kSCStatusInvalidArgument);
-                               return FALSE;
-                       }
-
-                       interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
-                       if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
-                               _SCErrorSet(kSCStatusInvalidArgument);
-                               return FALSE;
-                       }
-                       break;
+               if (interfacePrivate->usb.vid != NULL) {
+                       CFDictionaryAddValue(info, CFSTR(kUSBVendorID), interfacePrivate->usb.vid);
                }
-
-               case kSCNetworkInterfacePasswordTypeEAPOL : {
-                       break;
+               if (interfacePrivate->usb.pid != NULL) {
+                       CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
                }
+#endif // !TARGET_OS_SIMULATOR
+       }
 
-               default :
-                       break;
+       if (CFDictionaryGetCount(info) == 0) {
+               // do not return an empty dictionary
+               CFRelease(info);
+               info = NULL;
        }
 
-       return TRUE;
+       return info;
 }
 
 
-Boolean
-SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef          interface,
-                               SCNetworkInterfacePasswordType  passwordType)
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj)
 {
-       Boolean                 exists          = FALSE;
-       SCPreferencesRef        prefs           = NULL;
-       CFStringRef             serviceID       = NULL;
-
-       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
-               return FALSE;
-       }
-
-       switch (passwordType) {
-               case kSCNetworkInterfacePasswordTypePPP : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id;
-
-                       // get configuration
-                       config = SCNetworkInterfaceGetConfiguration(interface);
-
-                       // get serviceID
-                       unique_id = getPasswordID(config, serviceID);
-
-                       // check
-                       exists = __extract_password(prefs,
-                                                   config,
-                                                   kSCPropNetPPPAuthPassword,
-                                                   kSCPropNetPPPAuthPasswordEncryption,
-                                                   kSCValNetPPPAuthPasswordEncryptionKeychain,
-                                                   unique_id,
-                                                   NULL);
-                       break;
-               }
-
-               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
-                       CFDictionaryRef config;
-                       CFStringRef     shared_id;
+       SCNetworkInterfaceRef   interface       = NULL;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+       /* initialize runtime */
+       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-                       // get sharedSecret ID
-                       shared_id = copySharedSecretID(config, serviceID);
+       if (IOObjectConformsTo(if_obj, kIONetworkInterfaceClass)) {
+               interface = createInterface(if_obj, processNetworkInterface, NULL);
+       } else if (IOObjectConformsTo(if_obj, kIOSerialBSDServiceValue)) {
+               interface = createInterface(if_obj, processSerialInterface, kSCNetworkInterfaceHiddenPortKey);
+       }
 
-                       // check
-                       exists = __extract_password(prefs,
-                                                   config,
-                                                   kSCPropNetIPSecSharedSecret,
-                                                   kSCPropNetIPSecSharedSecretEncryption,
-                                                   kSCValNetIPSecSharedSecretEncryptionKeychain,
-                                                   shared_id,
-                                                   NULL);
-                       CFRelease(shared_id);
-                       break;
-               }
+       return interface;
+}
 
-               case kSCNetworkInterfacePasswordTypeEAPOL : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id       = NULL;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+CFStringRef
+_SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // get 802.1X identifier
-                       if (config != NULL) {
-                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
-                       }
-                       if (!isA_CFString(unique_id)) {
-                               return FALSE;
-                       }
+       return interfacePrivate->configurationAction;
+}
 
-                       // check password
-                       exists = _SCPreferencesSystemKeychainPasswordItemExists(prefs, unique_id);
-                       break;
-               }
 
-               default :
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       return FALSE;
-       }
+CFDataRef
+_SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return exists;
+       return interfacePrivate->address;
 }
 
 
-CFDataRef
-SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef           interface,
-                              SCNetworkInterfacePasswordType   passwordType)
+CFStringRef
+_SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface)
 {
-       CFDataRef               password        = NULL;
-       SCPreferencesRef        prefs           = NULL;
-       CFStringRef             serviceID       = NULL;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
-               return NULL;
-       }
+       return interfacePrivate->prefix;
+}
 
-       switch (passwordType) {
-               case kSCNetworkInterfacePasswordTypePPP : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetConfiguration(interface);
+CFNumberRef
+_SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // get serviceID
-                       unique_id = getPasswordID(config, serviceID);
+       return interfacePrivate->type;
+}
 
-                       // extract
-                       (void) __extract_password(prefs,
-                                                 config,
-                                                 kSCPropNetPPPAuthPassword,
-                                                 kSCPropNetPPPAuthPasswordEncryption,
-                                                 kSCValNetPPPAuthPasswordEncryptionKeychain,
-                                                 unique_id,
-                                                 &password);
-                       break;
-               }
 
-               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
-                       CFDictionaryRef config;
-                       CFStringRef     shared_id;
+CFNumberRef
+_SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+       return interfacePrivate->unit;
+}
 
-                       // get sharedSecret ID
-                       shared_id = copySharedSecretID(config, serviceID);
 
-                       // extract
-                       (void) __extract_password(prefs,
-                                                 config,
-                                                 kSCPropNetIPSecSharedSecret,
-                                                 kSCPropNetIPSecSharedSecretEncryption,
-                                                 kSCValNetIPSecSharedSecretEncryptionKeychain,
-                                                 shared_id,
-                                                 &password);
+static void
+update_ift_family(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       CFRelease(shared_id);
-                       break;
-               }
+       // note: family/subfamily are not in IORegistry, fetch with ioctl()
 
-               case kSCNetworkInterfacePasswordTypeEAPOL : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id       = NULL;
+       if ((interfacePrivate->family == NULL) && (interfacePrivate->subfamily == NULL)) {
+               CFStringRef     bsdName = SCNetworkInterfaceGetBSDName(interface);
+               struct ifreq    ifr;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+               memset(&ifr, 0, sizeof(ifr));
+               if ((bsdName != NULL) &&
+                   _SC_cfstring_to_cstring(bsdName, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) != NULL) {
+                       int     s;
 
-                       // get 802.1X identifier
-                       if (config != NULL) {
-                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
-                       }
-                       if (!isA_CFString(unique_id)) {
-                               _SCErrorSet(kSCStatusFailed);
-                               return NULL;
+                       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);
                        }
-
-                       // copy password
-                       password = _SCPreferencesSystemKeychainPasswordItemCopy(prefs, unique_id);
-                       break;
                }
 
-               default :
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       return NULL;
+               interfacePrivate->family = CFNumberCreate(NULL,
+                                                         kCFNumberSInt32Type,
+                                                         &ifr.ifr_type.ift_family);
+               interfacePrivate->subfamily = CFNumberCreate(NULL,
+                                                            kCFNumberSInt32Type,
+                                                            &ifr.ifr_type.ift_subfamily);
        }
-
-       return password;
 }
 
 
-Boolean
-SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef         interface,
-                                SCNetworkInterfacePasswordType passwordType)
+CFNumberRef
+_SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface)
 {
-       Boolean                 ok              = FALSE;
-       SCPreferencesRef        prefs           = NULL;
-       CFStringRef             serviceID       = NULL;
-
-       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
-               return FALSE;
-       }
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       switch (passwordType) {
-               case kSCNetworkInterfacePasswordTypePPP : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id;
+       // note: family not in IORegistry, fetch with ioctl()
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetConfiguration(interface);
+       if (interfacePrivate->family == NULL) {
+               update_ift_family(interface);
+       }
 
-                       // get serviceID
-                       unique_id = getPasswordID(config, serviceID);
+       return interfacePrivate->family;
+}
 
-                       // remove password
-                       ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
-                       if (ok) {
-                               CFMutableDictionaryRef  newConfig;
 
-                               if (config != NULL) {
-                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                                       CFDictionaryRemoveValue(newConfig, kSCPropNetPPPAuthPassword);
-                                       CFDictionaryRemoveValue(newConfig, kSCPropNetPPPAuthPasswordEncryption);
-                                       ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
-                                       CFRelease(newConfig);
-                               }
-                       }
-                       break;
-               }
+CFNumberRef
+_SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
-                       CFDictionaryRef config;
-                       CFStringRef     shared_id;
+       // note: subfamily not in IORegistry, fetch with ioctl()
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+       if (interfacePrivate->subfamily == NULL) {
+               update_ift_family(interface);
+       }
 
-                       // get sharedSecret ID
-                       shared_id = copySharedSecretID(config, serviceID);
+       return interfacePrivate->subfamily;
+}
 
-                       // remove password
-                       ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, shared_id);
-                       if (ok) {
-                               CFMutableDictionaryRef  newConfig;
 
-                               if (config != NULL) {
-                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                                       CFDictionaryRemoveValue(newConfig, kSCPropNetIPSecSharedSecret);
-                                       CFDictionaryRemoveValue(newConfig, kSCPropNetIPSecSharedSecretEncryption);
-                                       ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
-                                                                                       kSCEntNetIPSec,
-                                                                                       newConfig);
-                                       CFRelease(newConfig);
-                               }
-                       }
+CFStringRef
+_SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       CFRelease(shared_id);
-                       break;
-               }
+       return interfacePrivate->path;
+}
 
-               case kSCNetworkInterfacePasswordTypeEAPOL : {
-                       CFDictionaryRef config;
-                       CFStringRef     unique_id       = NULL;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
+uint64_t
+_SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // get 802.1X identifier
-                       if (config != NULL) {
-                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
-                       }
-                       if (!isA_CFString(unique_id)) {
-                               _SCErrorSet(kSCStatusFailed);
-                               return FALSE;
-                       }
+       return interfacePrivate->entryID;
+}
 
-                       // remove password
-                       ok = _SCPreferencesSystemKeychainPasswordItemRemove(prefs, unique_id);
-                       break;
-               }
 
-               default :
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       return FALSE;
-       }
+__private_extern__
+Boolean
+__SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
-       return ok;
+       return interfacePrivate->active;
 }
 
 
 Boolean
-SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef            interface,
-                             SCNetworkInterfacePasswordType    passwordType,
-                             CFDataRef                         password,
-                             CFDictionaryRef                   options)
+_SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface)
 {
-       CFStringRef             account         = NULL;
-       CFDictionaryRef         config;
-       CFStringRef             description     = NULL;
-       CFStringRef             label           = NULL;
-       Boolean                 ok              = FALSE;
-       SCPreferencesRef        prefs           = NULL;
-       CFStringRef             serviceID       = NULL;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       if (!checkInterfacePassword(interface, passwordType, &prefs, &serviceID)) {
-               return FALSE;
-       }
+       return interfacePrivate->builtin;
+}
 
-       switch (passwordType) {
-               case kSCNetworkInterfacePasswordTypePPP : {
-                       SCNetworkServiceRef     service = NULL;
-                       CFStringRef             unique_id;
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetConfiguration(interface);
+Boolean
+_SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // get serviceID
-                       unique_id = getPasswordID(config, serviceID);
+       return interfacePrivate->trustRequired;
+}
 
-                       // get "Account", "Name", "Kind"
-                       if (config != NULL) {
-                               // auth name --> keychain "Account"
-                               account = CFDictionaryGetValue(config, kSCPropNetPPPAuthName);
 
-                               // PPP [user defined] "name" --> keychain "Name"
-                               label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
-                       }
+#pragma mark -
+#pragma mark SCNetworkInterface SPIs
 
-                       if (label == NULL) {
-                               // service name --> keychain "Name"
-                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
-                                                                                              prefs,
-                                                                                              serviceID,
-                                                                                              interface);
 
-                               label = SCNetworkServiceGetName(service);
-                               if (label == NULL) {
-                                       // interface name --> keychain "Name"
-                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
-                               }
-                       }
+#if    TARGET_OS_OSX
 
-                       if (bundle != NULL) {
-                               // "PPP Password" --> keychain "Kind"
-                               description = CFBundleCopyLocalizedString(bundle,
-                                                                         CFSTR("KEYCHAIN_PPP_PASSWORD"),
-                                                                         CFSTR("PPP Password"),
-                                                                         NULL);
-                       }
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCopyBTPANInterface(void)
+{
+       CFDictionaryRef         dict;
+       SCNetworkInterfaceRef   interface       = NULL;
+       CFStringRef             key;
 
-                       // store password
-                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
-                                                                        unique_id,
-                                                                        (label != NULL)       ? label       : CFSTR("PPP"),
-                                                                        (description != NULL) ? description : CFSTR("PPP Password"),
-                                                                        account,
-                                                                        password,
-                                                                        options);
-                       if (ok) {
-                               CFMutableDictionaryRef  newConfig;
+       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);
+               }
 
-                               if (config != NULL) {
-                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                               } else {
-                                       newConfig = CFDictionaryCreateMutable(NULL,
-                                                                             0,
-                                                                             &kCFTypeDictionaryKeyCallBacks,
-                                                                             &kCFTypeDictionaryValueCallBacks);
-                               }
-                               CFDictionarySetValue(newConfig,
-                                                    kSCPropNetPPPAuthPassword,
-                                                    unique_id);
-                               CFDictionarySetValue(newConfig,
-                                                    kSCPropNetPPPAuthPasswordEncryption,
-                                                    kSCValNetPPPAuthPasswordEncryptionKeychain);
-                               ok = SCNetworkInterfaceSetConfiguration(interface, newConfig);
-                               CFRelease(newConfig);
-                       }
+               interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
 
-                       if (description != NULL) CFRelease(description);
-                       if (service     != NULL) CFRelease(service);
-                       break;
+               if ((interfacePrivate != NULL) &&
+                   (interfacePrivate->address == NULL) &&
+                   CFDictionaryGetValueIfPresent(dict,
+                                                 kInterfaceNamerKey_BT_PAN_Mac,
+                                                 (const void **)&addr) &&
+                   isA_CFData(addr)) {
+                       interfacePrivate->address = CFRetain(addr);
                }
 
-               case kSCNetworkInterfacePasswordTypeIPSecSharedSecret : {
-                       SCNetworkServiceRef     service = NULL;
-                       CFStringRef             shared_id;
+               CFRelease(dict);
+       }
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+       return interface;
+}
+#endif // TARGET_OS_OSX
 
-                       // get sharedSecret ID
-                       shared_id = copySharedSecretID(config, serviceID);
 
-                       // get "Name", "Kind"
-                       if (config != NULL) {
-                               // PPP [user defined] "name" --> keychain "Name"
-                               label = CFDictionaryGetValue(config, kSCPropUserDefinedName);
-                       }
+CFStringRef
+_SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface)
+{
+       io_registry_entry_t             device;
+       io_iterator_t                   device_iterator         = MACH_PORT_NULL;
+       CFStringRef                     device_path             = NULL;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       kern_return_t                   kr;
+       CFStringRef                     match_keys[2];
+       CFTypeRef                       match_vals[2];
+       CFDictionaryRef                 match_dict;
+       CFDictionaryRef                 matching;
 
-                       if (label == NULL) {
-                               // service name --> keychain "Name"
-                               service = (SCNetworkServiceRef)__SCNetworkServiceCreatePrivate(NULL,
-                                                                                              prefs,
-                                                                                              serviceID,
-                                                                                              interface);
+       if (interfacePrivate->entity_device == NULL) {
+               return NULL;
+       }
 
-                               label = SCNetworkServiceGetName(service);
-                               if (label == NULL) {
-                                       // interface name --> keychain "Name"
-                                       label = SCNetworkInterfaceGetLocalizedDisplayName(interface);
-                               }
-                       }
+       if (interfacePrivate->entity_device_unique == NULL) {
+               goto done;
+       }
 
-                       if (bundle != NULL) {
-                               // "IPSec Shared Secret" --> keychain "Kind"
-                               description = CFBundleCopyLocalizedString(bundle,
-                                                                         CFSTR("KEYCHAIN_IPSEC_SHARED_SECRET"),
-                                                                         CFSTR("IPSec Shared Secret"),
-                                                                         NULL);
-                       }
+       match_keys[0] = CFSTR(kIOTTYBaseNameKey);
+       match_vals[0] = interfacePrivate->entity_device;
+       match_dict = CFDictionaryCreate(NULL,
+                                       (const void **)match_keys,
+                                       (const void **)match_vals,
+                                       1,
+                                       &kCFTypeDictionaryKeyCallBacks,
+                                       &kCFTypeDictionaryValueCallBacks);
 
-                       // set password
-                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
-                                                                        shared_id,
-                                                                        (label != NULL)       ? label       : CFSTR("PPP"),
-                                                                        (description != NULL) ? description : CFSTR("IPSec Shared Secret"),
-                                                                        NULL,
-                                                                        password,
-                                                                        options);
-                       if (ok) {
-                               CFMutableDictionaryRef  newConfig       = NULL;
+       match_keys[0] = CFSTR(kIOProviderClassKey);
+       match_vals[0] = CFSTR(kIOSerialBSDServiceValue);
+       match_keys[1] = CFSTR(kIOPropertyMatchKey);
+       match_vals[1] = match_dict;
+       matching = CFDictionaryCreate(NULL,
+                                     (const void **)match_keys,
+                                     (const void **)match_vals,
+                                     sizeof(match_keys)/sizeof(match_keys[0]),
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+       CFRelease(match_dict);
 
-                               if (config != NULL) {
-                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                               } else {
-                                       newConfig = CFDictionaryCreateMutable(NULL,
-                                                                             0,
-                                                                             &kCFTypeDictionaryKeyCallBacks,
-                                                                             &kCFTypeDictionaryValueCallBacks);
+       // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
+       kr = IOServiceGetMatchingServices(masterPort, matching, &device_iterator);
+       if (kr != kIOReturnSuccess) {
+               SC_log(LOG_INFO, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr);
+               goto done;
+       }
+
+       while ((device_path == NULL) &&
+              ((device = IOIteratorNext(device_iterator)) != MACH_PORT_NULL)) {
+               CFDictionaryRef overrides;
+
+               overrides = IORegistryEntrySearchCFProperty(device,
+                                                           kIOServicePlane,
+                                                           kSCNetworkInterfaceNetworkConfigurationOverridesKey,
+                                                           NULL,
+                                                           kIORegistryIterateRecursively | kIORegistryIterateParents);
+               if (overrides != NULL) {
+                       CFDictionaryRef modemOverrides;
+
+                       modemOverrides = CFDictionaryGetValue(overrides, kSCEntNetModem);
+                       if (modemOverrides != NULL) {
+                               CFRetain(modemOverrides);
+                       }
+                       CFRelease(overrides);
+                       overrides = modemOverrides;
+               }
+               if (overrides == NULL) {
+                       overrides = IORegistryEntrySearchCFProperty(device,
+                                                                   kIOServicePlane,
+                                                                   CFSTR("DeviceModemOverrides"),
+                                                                   NULL,
+                                                                   kIORegistryIterateRecursively | kIORegistryIterateParents);
+               }
+               if (overrides != NULL) {
+                       if (isA_CFDictionary(overrides)) {
+                               CFStringRef     matchIdentifier;
+
+                               matchIdentifier = CFDictionaryGetValue(overrides, CFSTR("UniqueIdentifier"));
+                               if (isA_CFString(matchIdentifier) &&
+                                   CFEqual(interfacePrivate->entity_device_unique, matchIdentifier)) {
+                                       device_path = IORegistryEntryCreateCFProperty(device,
+                                                                                     CFSTR(kIOTTYDeviceKey),
+                                                                                     NULL,
+                                                                                     0);
                                }
-                               CFDictionarySetValue(newConfig,
-                                                    kSCPropNetIPSecSharedSecret,
-                                                    shared_id);
-                               CFDictionarySetValue(newConfig,
-                                                    kSCPropNetIPSecSharedSecretEncryption,
-                                                    kSCValNetIPSecSharedSecretEncryptionKeychain);
-                               ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
-                                                                               kSCEntNetIPSec,
-                                                                               newConfig);
-                               CFRelease(newConfig);
                        }
+                       CFRelease(overrides);
+               }
+               IOObjectRelease(device);
+       }
 
-                       if (description != NULL) CFRelease(description);
-                       if (service     != NULL) CFRelease(service);
-                       CFRelease(shared_id);
-                       break;
+       IOObjectRelease(device_iterator);
+
+    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);
                }
+       }
 
-               case kSCNetworkInterfacePasswordTypeEAPOL : {
-                       CFStringRef     unique_id       = NULL;
+       return device_path;
+}
 
-                       // get configuration
-                       config = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetEAPOL);
 
-                       // get 802.1X identifier
-                       if (config != NULL) {
-                               unique_id = CFDictionaryGetValue(config, kEAPClientPropUserPasswordKeychainItemID);
-                       }
-                       if (isA_CFString(unique_id)) {
-                               CFRetain(unique_id);
-                       } else {
-                               CFUUIDRef       uuid;
+#pragma mark -
 
-                               uuid     = CFUUIDCreate(NULL);
-                               unique_id = CFUUIDCreateString(NULL, uuid);
-                               CFRelease(uuid);
-                       }
 
-                       // get "Name", "Kind"
-                       if (bundle != NULL) {
-                               // "802.1X Password" --> keychain "Name"
-                               label = CFBundleCopyLocalizedString(bundle,
-                                                                   CFSTR("KEYCHAIN_EAPOL_PASSWORD"),
-                                                                   CFSTR("802.1X Password"),
-                                                                   NULL);
-                               // "Internet Connect" --> keychain "Kind"
-                               description = CFBundleCopyLocalizedString(bundle,
-                                                                         CFSTR("KEYCHAIN_INTERNET_CONNECT"),
-                                                                         CFSTR("Internet Connect"),
-                                                                         NULL);
-                       }
+Boolean
+_SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface)
+{
+#if    TARGET_OS_SIMULATOR
+#pragma unused(interface)
+#else  // TARGET_OS_SIMULATOR
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-                       // set password
-                       ok = _SCPreferencesSystemKeychainPasswordItemSet(prefs,
-                                                                        unique_id,
-                                                                        (label != NULL)       ? label       : CFSTR("802.1X Password"),
-                                                                        (description != NULL) ? description : CFSTR("Internet Connect"),
-                                                                        NULL,
-                                                                        password,
-                                                                        options);
-                       if (ok) {
-                               CFMutableDictionaryRef  newConfig       = NULL;
+       if (!_SCNetworkInterfaceIsHiddenConfiguration(interface)) {
+               // if not HiddenConfiguration
+               return FALSE;
+       }
 
-                               if (config != NULL) {
-                                       newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
-                               } else {
-                                       newConfig = CFDictionaryCreateMutable(NULL,
-                                                                             0,
-                                                                             &kCFTypeDictionaryKeyCallBacks,
-                                                                             &kCFTypeDictionaryValueCallBacks);
-                               }
-                               CFDictionarySetValue(newConfig,
-                                                    kEAPClientPropUserPasswordKeychainItemID,
-                                                    unique_id);
-                               ok = SCNetworkInterfaceSetExtendedConfiguration(interface,
-                                                                               kSCEntNetEAPOL,
-                                                                               newConfig);
-                               CFRelease(newConfig);
-                       }
+       if ((interfacePrivate->overrides == NULL) ||
+           (!CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv4) &&
+            !CFDictionaryContainsKey(interfacePrivate->overrides, kSCNetworkProtocolTypeIPv6))) {
+               // if no [IPv4/IPv6] configuration overrides
+               return FALSE;
+       }
 
-                       CFRelease(unique_id);
-                       if (label       != NULL) CFRelease(label);
-                       if (description != NULL) CFRelease(description);
-                       break;
-               }
+       if (_SCNetworkInterfaceIsBuiltin(interface)) {
+               // if built-in (and overrides are present)
+               return TRUE;
+       }
 
-               default :
-                       _SCErrorSet(kSCStatusInvalidArgument);
-                       break;
+       if (_SCNetworkInterfaceIsCarPlay(interface)) {
+               // if CarPlay (and overrides are present)
+               return TRUE;
        }
 
-       return ok;
-}
+       if (isA_CFNumber(interfacePrivate->usb.vid)) {
+               int             vid;
 
+               if (CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid) &&
+                   (vid == kIOUSBVendorIDAppleComputer)) {
+                       // if Apple interface (and overrides are present)
+                       return TRUE;
+               }
+       }
+#endif // TARGET_OS_SIMULATOR
 
-#pragma mark -
-#pragma mark SCNetworkInterface [InterfaceNamer] SPIs
+       return FALSE;
+}
 
 
-SCNetworkInterfaceRef
-_SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj)
+Boolean
+_SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface)
 {
-       SCNetworkInterfaceRef   interface;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       /* initialize runtime */
-       pthread_once(&initialized, __SCNetworkInterfaceInitialize);
+       return (interfacePrivate->sort_order == kSortBluetoothPAN_GN);
+}
 
-       interface = createInterface(if_obj, processNetworkInterface);
-       return interface;
+
+Boolean
+_SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface)
+{
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+
+       return (interfacePrivate->sort_order == kSortBluetoothPAN_NAP);
 }
 
 
-CFDataRef
-_SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface)
+Boolean
+_SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return interfacePrivate->address;
+       return (interfacePrivate->sort_order == kSortBluetoothPAN_U);
 }
 
 
-CFNumberRef
-_SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface)
+Boolean
+_SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return interfacePrivate->type;
+       return (interfacePrivate->sort_order == kSortCarPlay);
 }
 
 
-CFNumberRef
-_SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface)
+Boolean
+_SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return interfacePrivate->unit;
+       return interfacePrivate->hidden;
 }
 
 
-CFStringRef
-_SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface)
+Boolean
+_SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
 
-       return interfacePrivate->path;
+       return (interfacePrivate->sort_order == kSortTethered);
 }
 
 
 Boolean
-_SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface)
+_SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface)
 {
        SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     interfaceType;
 
-       return interfacePrivate->builtin;
+       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 -
-#pragma mark SCNetworkInterface SPIs
+
+
+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
-_SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface)
+SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface, CFDictionaryRef policy)
 {
-       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       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 interfacePrivate->modemIsV92;
+       return ok;
 }
 
 
@@ -4325,13 +7752,18 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef           allocator,
                               SCPreferencesRef         prefs,
                               CFStringRef              serviceID)
 {
+#pragma unused(allocator)
        SCNetworkInterfacePrivateRef            oldPrivate      = (SCNetworkInterfacePrivateRef)interface;
        SCNetworkInterfacePrivateRef            newPrivate;
 
        /* initialize runtime (and kSCNetworkInterfaceIPv4) */
        pthread_once(&initialized, __SCNetworkInterfaceInitialize);
 
-       newPrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, prefs, serviceID, NULL);
+       if (interface == kSCNetworkInterfaceIPv4) {
+               return (SCNetworkInterfacePrivateRef)CFRetain(interface);
+       }
+
+       newPrivate = __SCNetworkInterfaceCreatePrivate(NULL, NULL, prefs, serviceID);
        newPrivate->interface_type              = oldPrivate->interface_type;
        if (oldPrivate->interface != NULL) {
                newPrivate->interface           = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL,                   // allocator
@@ -4342,6 +7774,9 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef             allocator,
        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);
        }
@@ -4358,6 +7793,9 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef             allocator,
        if (oldPrivate->entity_device != NULL) {
                newPrivate->entity_device       = CFRetain(oldPrivate->entity_device);
        }
+       if (oldPrivate->entity_device_unique != NULL) {
+               newPrivate->entity_device_unique = CFRetain(oldPrivate->entity_device_unique);
+       }
        newPrivate->entity_type                 = oldPrivate->entity_type;
        newPrivate->entity_subtype              = oldPrivate->entity_subtype;
        if (oldPrivate->supported_interface_types != NULL) {
@@ -4370,25 +7808,47 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef           allocator,
                newPrivate->address             = CFRetain(oldPrivate->address);
        }
        newPrivate->builtin                     = oldPrivate->builtin;
+       if (oldPrivate->configurationAction != NULL) {
+               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->path != NULL) {
                newPrivate->path                = CFRetain(oldPrivate->path);
        }
+       newPrivate->entryID                     = oldPrivate->entryID;
        if (oldPrivate->overrides != NULL) {
                newPrivate->overrides           = CFDictionaryCreateMutableCopy(NULL, 0, oldPrivate->overrides);
        }
-       newPrivate->modemIsV92                  = oldPrivate->modemIsV92;
-       newPrivate->supportsBond                = oldPrivate->supportsBond;
-       newPrivate->supportsVLAN                = oldPrivate->supportsVLAN;
        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);
+       }
+       if (oldPrivate->usb.vid != NULL) {
+               newPrivate->usb.vid             = CFRetain(oldPrivate->usb.vid);
+       }
+       if (oldPrivate->usb.pid != NULL) {
+               newPrivate->usb.pid             = CFRetain(oldPrivate->usb.pid);
+       }
        newPrivate->sort_order                  = oldPrivate->sort_order;
+
+       newPrivate->supportsBond                = oldPrivate->supportsBond;
        if (oldPrivate->bond.interfaces != NULL) {
                newPrivate->bond.interfaces     = CFRetain(oldPrivate->bond.interfaces);
        }
@@ -4398,6 +7858,16 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef            allocator,
        if (oldPrivate->bond.options != NULL) {
                newPrivate->bond.options        = CFRetain(oldPrivate->bond.options);
        }
+
+       newPrivate->supportsBridge              = oldPrivate->supportsBridge;
+       if (oldPrivate->bridge.interfaces != NULL) {
+               newPrivate->bridge.interfaces   = CFRetain(oldPrivate->bridge.interfaces);
+       }
+       if (oldPrivate->bridge.options != NULL) {
+               newPrivate->bridge.options      = CFRetain(oldPrivate->bridge.options);
+       }
+
+       newPrivate->supportsVLAN                = oldPrivate->supportsVLAN;
        if (oldPrivate->vlan.interface != NULL) {
                newPrivate->vlan.interface      = CFRetain(oldPrivate->vlan.interface);
        }
@@ -4414,7 +7884,7 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef             allocator,
 
 __private_extern__
 CFArrayRef
-__SCNetworkInterfaceCopyDeepConfiguration(SCNetworkInterfaceRef interface)
+__SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface)
 {
        CFMutableArrayRef       configs;
 
@@ -4434,7 +7904,11 @@ __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkInterfaceRef interface)
                        CFDictionaryRef config;
                        CFArrayRef      extendedTypes;
 
-                       config = __SCNetworkInterfaceGetConfiguration(interface, defaultType);
+                       if (set == NULL) {
+                               config = __SCNetworkInterfaceGetConfiguration(interface, defaultType);
+                       } else {
+                               config = __SCNetworkInterfaceGetDefaultConfiguration(set, interface);
+                       }
                        if (config == NULL) {
                                config = (CFDictionaryRef)kCFNull;
                        }
@@ -4471,15 +7945,63 @@ __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkInterfaceRef interface)
 }
 
 
+__private_extern__ Boolean
+__SCNetworkInterfaceIsMember(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
+{
+       CFArrayRef      interfaces;
+       Boolean         match           = FALSE;
+       CFMutableSetRef members;
+
+       members = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+
+#if    !TARGET_OS_IPHONE
+       // add Bond [member] interfaces
+       interfaces = SCBondInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               __SCBondInterfaceListCollectMembers(interfaces, members);
+               CFRelease(interfaces);
+       }
+#endif // !TARGET_OS_IPHONE
+
+       // add Bridge [member] interfaces
+       interfaces = SCBridgeInterfaceCopyAll(prefs);
+       if (interfaces != NULL) {
+               __SCBridgeInterfaceListCollectMembers(interfaces, members);
+               CFRelease(interfaces);
+       }
+
+       if (CFSetGetCount(members) == 0) {
+               goto done;
+       }
+
+       while (interface != NULL) {
+               match = CFSetContainsValue(members, interface);
+               if (match) {
+                       // if the interface is a member of an
+                       // Ethernet Bond or Bridge
+                       break;
+               }
+
+               interface = SCNetworkInterfaceGetInterface(interface);
+       }
+
+    done :
+
+       CFRelease(members);
+       return match;
+}
+
+
 __private_extern__
 void
-__SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface, CFArrayRef configs)
+__SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set, SCNetworkInterfaceRef interface, CFArrayRef configs)
 {
-       CFIndex         i;
+       CFIndex i;
 
        for (i = 0; interface != NULL; i++) {
                CFStringRef     defaultType;
                CFDictionaryRef interfaceConfiguration;
+               Boolean         ok;
 
                interfaceConfiguration = (configs != NULL) ? CFArrayGetValueAtIndex(configs, i) : NULL;
 
@@ -4493,11 +8015,22 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface, CFArra
                        if (config == (CFDictionaryRef)kCFNull) {
                                config = NULL;
                        }
-                       if (!__SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE)) {
-                               SCLog(TRUE, LOG_DEBUG,
-                                     CFSTR("__SCNetworkInterfaceSetDeepConfiguration __SCNetworkInterfaceSetConfiguration() failed, interface=%@, type=%@"),
-                                     interface,
-                                     defaultType);
+                       if (set == NULL) {
+                               // if service is not associated with the set
+                               ok = __SCNetworkInterfaceSetConfiguration(interface, defaultType, config, TRUE);
+                       } else {
+                               // apply default configuration to this set
+                               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);
@@ -4511,15 +8044,20 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface, CFArra
 
                                        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);
                                        }
                                }
 
@@ -4532,3 +8070,435 @@ __SCNetworkInterfaceSetDeepConfiguration(SCNetworkInterfaceRef interface, CFArra
 
        return;
 }
+
+
+SCNetworkInterfaceRef
+_SCNetworkInterfaceCopyActive(SCDynamicStoreRef store, CFStringRef bsdName)
+{
+       SCNetworkInterfaceRef           interface;
+
+       interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeAllVirtualInterfaces);
+       if (interface == NULL) {
+               return NULL;
+       }
+
+       if (store != NULL) {
+               SCNetworkInterfacePrivateRef    interfacePrivate =
+                       (SCNetworkInterfacePrivateRef)interface;
+
+               CFRetain(store);
+               interfacePrivate->store = store;
+       }
+
+       return interface;
+}
+
+
+#if    !TARGET_OS_SIMULATOR
+SCNetworkServicePrimaryRank
+SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef 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;
+
+       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 IPMonitorControlSetInterfacePrimaryRank(control,
+                                                      ifName,
+                                                      newRank);
+}
+
+Boolean
+SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface)
+{
+       Boolean                         disable_until_needed = FALSE;
+       CFNumberRef                     disable_prop = NULL;
+       CFIndex                         interfaceIndex;
+       SCNetworkInterfacePrivateRef    interfacePrivate
+               = (SCNetworkInterfacePrivateRef)interface;
+       CFArrayRef                      path_list;
+
+       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);
+
+               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;
+                               }
+                       }
+               }
+       }
+       if (disable_prop == NULL) {
+               disable_until_needed
+                       = _SCNetworkInterfaceIsTethered(interface);
+       }
+       _SCErrorSet(kSCStatusOK);
+       return (disable_until_needed);
+}
+
+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);
+               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;
+
+       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)
+{
+#pragma unused(interface)
+#pragma unused(newRank)
+       _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);
+       }
+
+       if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
+       if (isA_CFArray(if_list)) {
+               CFIndex i;
+               CFIndex n       = CFArrayGetCount(if_list);
+
+               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;
+}
+
+
+__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;
+                       }
+               }
+       }
+
+       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);
+
+       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");
+       }
+
+       return mappingBSDToInterface;
+}
+
+__private_extern__ Boolean
+__SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity)
+{
+       CFStringRef intfSubtype;
+
+       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;
+}