2 * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
29 * which includes code originally authored by
30 * Robert Ulrich <rulrich@apple.com>
31 * Elizabeth Douglas <elizabeth@apple.com>
32 * Quinn <eskimo1@apple.com>
36 #include <TargetConditionals.h>
37 #include <CoreFoundation/CoreFoundation.h>
38 #include <CoreFoundation/CFRuntime.h>
39 #include "SCNetworkConfigurationInternal.h"
40 #include "SCPreferencesInternal.h"
41 #include "SCHelper_client.h"
42 #include "plugin_shared.h"
45 #include <EAP8021X/EAPClientProperties.h>
46 #else // !TARGET_OS_IPHONE
47 #ifndef kEAPClientPropUserName
48 #define kEAPClientPropUserName CFSTR("UserName")
50 #ifndef kEAPClientPropUserPasswordKeychainItemID
51 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
53 #endif // !TARGET_OS_IPHONE
55 #include <IOKit/IOKitLib.h>
56 #include <IOKit/IOCFBundle.h>
57 #include <IOKit/IOBSD.h>
58 #include <IOKit/network/IONetworkController.h>
59 #include <IOKit/network/IONetworkInterface.h>
60 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
61 #include <IOKit/serial/IOSerialKeys.h>
62 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
63 #if !TARGET_OS_SIMULATOR
64 #include <IOKit/usb/IOUSBLib.h>
65 #endif // !TARGET_OS_SIMULATOR
67 #include "dy_framework.h"
69 #ifndef kPCIThunderboltString
70 #define kPCIThunderboltString "PCI-Thunderbolt"
74 #ifndef kUSBSupportsIPhoneOS
75 #define kUSBSupportsIPhoneOS "SupportsIPhoneOS"
76 #endif // !kUSBSupportsIPhoneOS
77 #endif // TARGET_OS_OSX
79 #ifndef kIOUserEthernetInterfaceRoleKey
80 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
83 #ifndef kIOUSBHostInterfaceClassName
84 #define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
89 #include <mach/mach.h>
91 #include <net/if_types.h>
92 #include <net/if_dl.h>
93 #include <net/route.h>
94 #include <sys/ioctl.h>
95 #include <sys/param.h>
96 #include <sys/types.h>
97 #include <sys/socket.h>
99 #include <sys/sysctl.h>
103 /* CrashReporter "Application Specific Information" */
104 #include <CrashReporterClient.h>
107 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
108 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
109 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
110 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
111 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
112 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
113 static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName
, CFArrayRef matchingInterfaces
);
114 static Boolean
__SCNetworkInterfaceCacheIsOpen (void);
115 static CFArrayRef
__SCNetworkInterfaceCacheCopy (CFStringRef bsdName
);
119 kSortInternalModem
= 0,
134 kSortBluetoothPAN_GN
,
135 kSortBluetoothPAN_NAP
,
146 static const char *sortOrderName
[] = {
174 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
175 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
176 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
177 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
178 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
179 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
180 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
181 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
182 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
183 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
184 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
185 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
186 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
187 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
188 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
189 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
190 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
191 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
193 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
195 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
196 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
197 .sort_order
= kSortUnknown
, // sort_order
200 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
202 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
203 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
204 .sort_order
= kSortUnknown
, // sort_order
207 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
209 static CFMutableSetRef vendor_interface_types
= NULL
;
211 // A thread-specific convenience cache of all interfaces matching a bsd name
212 // Key: CFStringRef (BSD name)
213 // Value: CFArrayRef (matching interfaces)
214 static __thread CFMutableDictionaryRef S_interface_cache
= NULL
;
217 #pragma mark SCNetworkInterface configuration details
226 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
231 #define doProxies 1<<4
232 #if !TARGET_OS_IPHONE
234 #else // !TARGET_OS_IPHONE
236 #endif // !TARGET_OS_IPHONE
238 static const struct {
239 const CFStringRef
*interface_type
;
240 const CFStringRef
*entity_hardware
;
241 Boolean per_interface_config
;
242 uint32_t supported_interfaces
;
243 const CFStringRef
*ppp_subtype
;
244 uint32_t supported_protocols
;
245 } configurations
[] = {
246 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
247 // ================================== ==================== ========== =============== ==================================== ======================================
248 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
249 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
250 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
251 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
252 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
253 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
254 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
255 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
256 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
257 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
258 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
259 #pragma GCC diagnostic push
260 #pragma GCC diagnostic ignored "-Wdeprecated"
261 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
262 #pragma GCC diagnostic pop
263 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
264 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
265 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
266 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
267 // ================================== ==================== ========== =============== ==================================== ======================================
268 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
269 // ================================== ==================== ========== =============== ==================================== ======================================
270 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
274 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
275 static CFBundleRef bundle
= NULL
;
278 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
281 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
283 "SCNetworkInterface", // className
286 __SCNetworkInterfaceDeallocate
, // dealloc
287 __SCNetworkInterfaceEqual
, // equal
288 __SCNetworkInterfaceHash
, // hash
289 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
290 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
294 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
295 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
296 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
299 static mach_port_t masterPort
= MACH_PORT_NULL
;
302 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
304 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
308 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
310 CFAllocatorRef allocator
= CFGetAllocator(cf
);
311 CFMutableStringRef result
;
312 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
314 result
= CFStringCreateMutable(allocator
, 0);
315 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
316 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
317 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
318 if (interfacePrivate
->entity_device_unique
!= NULL
) {
319 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
321 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
322 if (interfacePrivate
->entity_subtype
!= NULL
) {
323 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
325 if (interfacePrivate
->name
!= NULL
) {
326 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
328 if (interfacePrivate
->localized_name
!= NULL
) {
329 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
331 if (interfacePrivate
->localized_key
!= NULL
) {
332 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
333 if (interfacePrivate
->localized_arg1
!= NULL
) {
334 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
336 if (interfacePrivate
->localized_arg2
!= NULL
) {
337 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
341 if (interfacePrivate
->address
!= NULL
) {
346 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
348 data
= CFDataGetBytePtr(interfacePrivate
->address
);
349 dataLen
= CFDataGetLength(interfacePrivate
->address
);
350 for (i
= 0; i
< dataLen
; i
++) {
351 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
356 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
357 if (interfacePrivate
->hiddenConfiguration
) {
358 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
360 if (interfacePrivate
->hiddenInterface
) {
361 CFStringAppendFormat(result
, NULL
, CFSTR(", HIDDEN"));
364 if (interfacePrivate
->trustRequired
) {
365 CFStringAppendFormat(result
, NULL
, CFSTR(", trust required = TRUE"));
367 #endif // TARGET_OS_IPHONE
368 if (interfacePrivate
->location
!= NULL
) {
369 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
371 if (interfacePrivate
->path
!= NULL
) {
372 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
374 if (interfacePrivate
->entryID
!= 0) {
375 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
377 if (interfacePrivate
->type
!= NULL
) {
378 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
380 if (interfacePrivate
->unit
!= NULL
) {
381 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
383 if (interfacePrivate
->family
!= NULL
) {
384 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
386 if (interfacePrivate
->subfamily
!= NULL
) {
387 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
389 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
393 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
394 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
397 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
398 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
402 if (interfacePrivate
->usb
.name
!= NULL
) {
403 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
404 interfacePrivate
->usb
.name
);
407 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
411 if (interfacePrivate
->configurationAction
!= NULL
) {
412 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
414 if (interfacePrivate
->overrides
!= NULL
) {
417 str
= _SCCopyDescription(interfacePrivate
->overrides
, formatOptions
);
418 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %@"), str
);
421 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d (%s)"),
422 interfacePrivate
->sort_order
,
423 interfacePrivate
->sort_order
<= kSortUnknown
? sortOrderName
[interfacePrivate
->sort_order
] : "?");
424 if (interfacePrivate
->prefs
!= NULL
) {
425 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
427 if (interfacePrivate
->serviceID
!= NULL
) {
428 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
430 if (interfacePrivate
->interface
!= NULL
) {
431 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
433 if (interfacePrivate
->unsaved
!= NULL
) {
434 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
437 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
441 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
442 for (i
= 0; i
< n
; i
++) {
443 SCNetworkInterfaceRef member
;
445 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
446 CFStringAppendFormat(result
, NULL
,
448 (i
== 0) ? ", interfaces = " : ",",
449 SCNetworkInterfaceGetBSDName(member
));
452 if (interfacePrivate
->bond
.mode
!= NULL
) {
453 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
455 if (interfacePrivate
->bond
.options
!= NULL
) {
458 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
459 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
463 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
467 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
468 for (i
= 0; i
< n
; i
++) {
469 SCNetworkInterfaceRef member
;
471 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
472 CFStringAppendFormat(result
, NULL
,
474 (i
== 0) ? ", interfaces = " : ",",
475 SCNetworkInterfaceGetBSDName(member
));
478 if (interfacePrivate
->bridge
.options
!= NULL
) {
481 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
482 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
486 if (interfacePrivate
->vlan
.interface
!= NULL
) {
487 CFStringAppendFormat(result
, NULL
,
488 CFSTR(", interface = %@"),
489 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
491 if (interfacePrivate
->vlan
.tag
!= NULL
) {
492 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
494 if (interfacePrivate
->vlan
.options
!= NULL
) {
497 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
498 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
502 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
509 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
511 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
513 /* release resources */
515 if (interfacePrivate
->name
!= NULL
)
516 CFRelease(interfacePrivate
->name
);
518 if (interfacePrivate
->localized_name
!= NULL
)
519 CFRelease(interfacePrivate
->localized_name
);
521 if (interfacePrivate
->localized_arg1
!= NULL
)
522 CFRelease(interfacePrivate
->localized_arg1
);
524 if (interfacePrivate
->localized_arg2
!= NULL
)
525 CFRelease(interfacePrivate
->localized_arg2
);
527 if (interfacePrivate
->interface
!= NULL
)
528 CFRelease(interfacePrivate
->interface
);
530 if (interfacePrivate
->prefs
!= NULL
)
531 CFRelease(interfacePrivate
->prefs
);
533 if (interfacePrivate
->store
!= NULL
)
534 CFRelease(interfacePrivate
->store
);
536 if (interfacePrivate
->serviceID
!= NULL
)
537 CFRelease(interfacePrivate
->serviceID
);
539 if (interfacePrivate
->unsaved
!= NULL
)
540 CFRelease(interfacePrivate
->unsaved
);
542 if (interfacePrivate
->entity_device
!= NULL
)
543 CFRelease(interfacePrivate
->entity_device
);
545 if (interfacePrivate
->entity_device_unique
!= NULL
)
546 CFRelease(interfacePrivate
->entity_device_unique
);
548 if (interfacePrivate
->supported_interface_types
!= NULL
)
549 CFRelease(interfacePrivate
->supported_interface_types
);
551 if (interfacePrivate
->supported_protocol_types
!= NULL
)
552 CFRelease(interfacePrivate
->supported_protocol_types
);
554 if (interfacePrivate
->address
!= NULL
)
555 CFRelease(interfacePrivate
->address
);
557 if (interfacePrivate
->addressString
!= NULL
)
558 CFRelease(interfacePrivate
->addressString
);
560 if (interfacePrivate
->configurationAction
!= NULL
)
561 CFRelease(interfacePrivate
->configurationAction
);
563 if (interfacePrivate
->location
!= NULL
)
564 CFRelease(interfacePrivate
->location
);
566 if (interfacePrivate
->path
!= NULL
)
567 CFRelease(interfacePrivate
->path
);
569 if (interfacePrivate
->overrides
!= NULL
)
570 CFRelease(interfacePrivate
->overrides
);
572 if (interfacePrivate
->prefix
!= NULL
)
573 CFRelease(interfacePrivate
->prefix
);
575 if (interfacePrivate
->type
!= NULL
)
576 CFRelease(interfacePrivate
->type
);
578 if (interfacePrivate
->unit
!= NULL
)
579 CFRelease(interfacePrivate
->unit
);
581 if (interfacePrivate
->family
!= NULL
)
582 CFRelease(interfacePrivate
->family
);
584 if (interfacePrivate
->subfamily
!= NULL
)
585 CFRelease(interfacePrivate
->subfamily
);
587 if (interfacePrivate
->usb
.name
!= NULL
)
588 CFRelease(interfacePrivate
->usb
.name
);
590 if (interfacePrivate
->usb
.pid
!= NULL
)
591 CFRelease(interfacePrivate
->usb
.pid
);
593 if (interfacePrivate
->usb
.vid
!= NULL
)
594 CFRelease(interfacePrivate
->usb
.vid
);
596 if (interfacePrivate
->bond
.interfaces
!= NULL
)
597 CFRelease(interfacePrivate
->bond
.interfaces
);
599 if (interfacePrivate
->bond
.mode
!= NULL
)
600 CFRelease(interfacePrivate
->bond
.mode
);
602 if (interfacePrivate
->bond
.options
!= NULL
)
603 CFRelease(interfacePrivate
->bond
.options
);
605 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
606 CFRelease(interfacePrivate
->bridge
.interfaces
);
608 if (interfacePrivate
->bridge
.options
!= NULL
)
609 CFRelease(interfacePrivate
->bridge
.options
);
611 if (interfacePrivate
->vlan
.interface
!= NULL
)
612 CFRelease(interfacePrivate
->vlan
.interface
);
614 if (interfacePrivate
->vlan
.tag
!= NULL
)
615 CFRelease(interfacePrivate
->vlan
.tag
);
617 if (interfacePrivate
->vlan
.options
!= NULL
)
618 CFRelease(interfacePrivate
->vlan
.options
);
619 #if !TARGET_OS_SIMULATOR
620 if (interfacePrivate
->IPMonitorControl
!= NULL
)
621 CFRelease(interfacePrivate
->IPMonitorControl
);
622 #endif // !TARGET_OS_SIMULATOR
628 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
630 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
631 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
636 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
637 return FALSE
; // if not the same interface type
640 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
641 return FALSE
; // if not the same device
644 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
645 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
646 return FALSE
; // if not the same device unique identifier
648 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
652 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
653 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
654 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
655 return FALSE
; // if same device but not the same display name
659 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
660 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
661 return FALSE
; // if not the same interfaces
663 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
664 return FALSE
; // if not the same mode
668 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
669 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
670 return FALSE
; // if not the same interfaces
674 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
675 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
676 return FALSE
; // if not the same physical interface
678 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
679 return FALSE
; // if not the same tag
683 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
684 return FALSE
; // if not the same layering
692 __SCNetworkInterfaceHash(CFTypeRef cf
)
695 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
697 if (interfacePrivate
->entity_device
!= NULL
) {
698 if (interfacePrivate
->entity_device_unique
== NULL
) {
699 hash
= CFHash(interfacePrivate
->entity_device
);
703 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
704 interfacePrivate
->entity_device
,
705 interfacePrivate
->entity_device_unique
);
716 __SCNetworkInterfaceInitialize(void)
721 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
723 // initialize __kSCNetworkInterfaceIPv4
724 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
725 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
726 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
728 // initialize __kSCNetworkInterfaceLoopback
729 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
730 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
731 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
732 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
733 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
735 // get CFBundleRef for SystemConfiguration.framework
736 bundle
= _SC_CFBundleGet();
738 // get mach port used to communication with IOKit
739 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
740 if (kr
!= kIOReturnSuccess
) {
741 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
749 SCNetworkInterfacePrivateRef
750 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
751 SCNetworkInterfaceRef interface
,
752 SCPreferencesRef prefs
,
753 CFStringRef serviceID
)
755 SCNetworkInterfacePrivateRef interfacePrivate
;
758 /* initialize runtime */
759 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
761 /* allocate target */
762 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
763 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
764 __kSCNetworkInterfaceTypeID
,
767 if (interfacePrivate
== NULL
) {
771 /* initialize non-zero/NULL members */
772 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
773 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
774 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
775 interfacePrivate
->sort_order
= kSortUnknown
;
777 return interfacePrivate
;
783 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
787 struct if_msghdr
* ifm
;
788 char * if_name
= NULL
;
789 unsigned int if_index
;
791 Boolean vlanOK
= FALSE
;
793 // get the interface index
794 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
795 if (if_name
== NULL
) {
796 return FALSE
; // if conversion error
798 if_index
= if_nametoindex(if_name
);
800 goto done
; // if unknown interface
803 // get information for the specified interface
808 mib
[4] = NET_RT_IFLIST
;
809 mib
[5] = if_index
; /* ask for exactly one interface */
811 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
812 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
815 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
816 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
817 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
821 // check the link type and hwassist flags
822 // ALIGN: buf is aligned
823 ifm
= (struct if_msghdr
*)(void *)buf
;
824 switch (ifm
->ifm_type
) {
826 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
827 struct if_data
*if_data
= &ifm
->ifm_data
;
829 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
839 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
840 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
847 __SCCopyMacAddress(CFStringRef ifname
)
849 struct ifaddrs
*ifap
;
850 char ifname_c
[IFNAMSIZ
];
852 CFDataRef macAddress
= NULL
;
854 if(_SC_cfstring_to_cstring(ifname
,
857 kCFStringEncodingUTF8
) == NULL
) {
861 if (getifaddrs(&ifap
) == -1) {
863 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
867 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
868 struct sockaddr_dl
*sdl
;
870 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
874 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
875 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
876 if (sdl
->sdl_family
!= AF_LINK
) {
880 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
889 SCNetworkInterfacePrivateRef
890 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
893 SCNetworkInterfacePrivateRef interfacePrivate
;
895 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
896 if (interfacePrivate
== NULL
) {
900 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
901 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
902 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
903 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
904 interfacePrivate
->builtin
= TRUE
;
905 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
906 interfacePrivate
->sort_order
= kSortBond
;
908 interfacePrivate
->localized_key
= CFSTR("bond");
909 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
911 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
912 // interfacePrivate->bond.mode = NULL;
913 // interfacePrivate->bond.options = NULL;
915 return interfacePrivate
;
920 SCNetworkInterfacePrivateRef
921 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
922 CFStringRef bridge_if
)
924 SCNetworkInterfacePrivateRef interfacePrivate
;
926 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
927 if (interfacePrivate
== NULL
) {
931 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
932 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
933 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
934 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
935 interfacePrivate
->builtin
= TRUE
;
936 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
937 interfacePrivate
->sort_order
= kSortBridge
;
939 interfacePrivate
->localized_key
= CFSTR("bridge");
940 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
942 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
943 // interfacePrivate->bridge.options = NULL;
945 return interfacePrivate
;
950 SCNetworkInterfacePrivateRef
951 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
954 SCNetworkInterfacePrivateRef interfacePrivate
;
956 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
957 if (interfacePrivate
== NULL
) {
961 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
962 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
963 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
964 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
965 interfacePrivate
->builtin
= TRUE
;
966 interfacePrivate
->sort_order
= kSortVLAN
;
968 interfacePrivate
->localized_key
= CFSTR("vlan");
969 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
971 // interfacePrivate->vlan.interface = NULL;
972 // interfacePrivate->vlan.tag = NULL;
973 // interfacePrivate->vlan.options = NULL;
975 return interfacePrivate
;
980 #pragma mark Interface ordering
983 static CF_RETURNS_RETAINED CFArrayRef
984 split_path(CFStringRef path
)
986 CFArrayRef components
;
987 CFMutableStringRef nPath
;
989 // turn '@'s into '/'s
990 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
991 (void) CFStringFindAndReplace(nPath
,
994 CFRangeMake(0, CFStringGetLength(nPath
)),
997 // split path into components to be compared
998 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
1006 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
1008 #pragma unused(context)
1009 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
1010 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
1011 CFComparisonResult res
= kCFCompareEqualTo
;
1013 /* sort by interface type */
1014 if (dev1
->sort_order
!= dev2
->sort_order
) {
1015 if (dev1
->sort_order
< dev2
->sort_order
) {
1016 res
= kCFCompareLessThan
;
1018 res
= kCFCompareGreaterThan
;
1023 /* built-in interfaces sort first */
1024 if (dev1
->builtin
!= dev2
->builtin
) {
1025 if (dev1
->builtin
) {
1026 res
= kCFCompareLessThan
;
1028 res
= kCFCompareGreaterThan
;
1033 /* ... and then, sort built-in interfaces by "location" */
1034 if (dev1
->builtin
) {
1035 if (dev1
->location
!= dev2
->location
) {
1036 if (isA_CFString(dev1
->location
)) {
1037 if (isA_CFString(dev2
->location
)) {
1038 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1040 res
= kCFCompareLessThan
;
1043 res
= kCFCompareGreaterThan
;
1046 if (res
!= kCFCompareEqualTo
) {
1052 /* ... and, then sort by IOPathMatch */
1053 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1054 CFArrayRef elements1
;
1055 CFArrayRef elements2
;
1061 elements1
= split_path(dev1
->path
);
1062 n1
= CFArrayGetCount(elements1
);
1064 elements2
= split_path(dev2
->path
);
1065 n2
= CFArrayGetCount(elements2
);
1067 n
= (n1
<= n2
) ? n1
: n2
;
1068 for (i
= 0; i
< n
; i
++) {
1077 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1078 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1080 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1082 q1
= strtoq(str
, &end
, 16);
1083 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1084 CFAllocatorDeallocate(NULL
, str
);
1087 // if e1 is a valid numeric string
1088 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1090 q2
= strtoq(str
, &end
, 16);
1091 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1092 CFAllocatorDeallocate(NULL
, str
);
1095 // if e2 is also a valid numeric string
1098 res
= kCFCompareEqualTo
;
1100 } else if (q1
< q2
) {
1101 res
= kCFCompareLessThan
;
1103 res
= kCFCompareGreaterThan
;
1109 res
= CFStringCompare(e1
, e2
, 0);
1110 if (res
!= kCFCompareEqualTo
) {
1115 if (res
== kCFCompareEqualTo
) {
1117 res
= kCFCompareLessThan
;
1118 } else if (n1
< n2
) {
1119 res
= kCFCompareGreaterThan
;
1123 CFRelease(elements1
);
1124 CFRelease(elements2
);
1126 if (res
!= kCFCompareEqualTo
) {
1131 /* ... and, then sort by BSD interface name */
1132 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1133 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1134 if (res
!= kCFCompareEqualTo
) {
1139 /* ... and lastly, sort by BSD interface unique identifier */
1140 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1141 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1142 // if (res != kCFCompareEqualTo) {
1152 sort_interfaces(CFMutableArrayRef all_interfaces
)
1156 n
= CFArrayGetCount(all_interfaces
);
1161 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1168 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1170 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1173 order
= interfacePrivate
->sort_order
<< 1;
1174 if (!interfacePrivate
->builtin
) {
1175 order
|= 0x1; // push non-builtin after built-in
1183 #pragma mark Interface details
1187 IOCopyCFStringValue(CFTypeRef ioVal
)
1189 if (isA_CFString(ioVal
)) {
1190 return CFStringCreateCopy(NULL
, ioVal
);
1193 if (isA_CFData(ioVal
)) {
1194 return CFStringCreateWithCString(NULL
,
1195 (const char *)CFDataGetBytePtr(ioVal
),
1196 kCFStringEncodingUTF8
);
1204 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1206 CFStringRef if_bsdName
;
1207 CFStringRef if_prefix
;
1208 CFNumberRef if_unit
;
1210 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1211 if (if_bsdName
!= NULL
) {
1212 return IOCopyCFStringValue(if_bsdName
);
1215 // no BSD name, get interface prefix and unit
1216 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1217 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1218 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1219 // if both prefix and unit available, construct BSD name
1220 if_bsdName
= CFStringCreateWithFormat(NULL
,
1232 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1236 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1237 return IOCopyCFStringValue(ioVal
);
1242 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1244 Boolean match
= FALSE
;
1245 CFIndex prefixLen
= CFStringGetLength(prefix
);
1246 CFStringRef str
= NULL
;
1248 if (!isA_CFString(ioVal
)) {
1249 if (isA_CFData(ioVal
)) {
1250 str
= CFStringCreateWithCStringNoCopy(NULL
,
1251 (const char *)CFDataGetBytePtr(ioVal
),
1252 kCFStringEncodingUTF8
,
1260 if ((ioVal
!= NULL
) &&
1261 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1262 (CFStringCompareWithOptions(ioVal
,
1264 CFRangeMake(0, prefixLen
),
1265 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1269 if (str
!= NULL
) CFRelease(str
);
1274 static const CFStringRef slot_prefixes
[] = {
1275 CFSTR("thunderbolt slot "),
1281 static CF_RETURNS_RETAINED CFStringRef
1282 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1285 io_registry_entry_t parent
;
1286 CFMutableStringRef slot
;
1287 CFTypeRef slot_name
;
1290 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1292 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1293 if (slot_name
!= NULL
) {
1294 slot
= CFStringCreateMutable(NULL
, 0);
1295 if (isA_CFString(slot_name
)) {
1296 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1297 CFStringAppend(slot
, slot_name
);
1298 } else if (isA_CFData(slot_name
)) {
1299 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1300 CFStringAppendCString(slot
,
1301 (const char *)CFDataGetBytePtr(slot_name
),
1302 kCFStringEncodingUTF8
);
1305 for (size_t i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1308 len
= CFStringGetLength(slot_prefixes
[i
]);
1309 if (CFStringGetLength(slot
) > len
) {
1310 (void) CFStringFindAndReplace(slot
,
1313 CFRangeMake(0, len
),
1314 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1318 CFStringTrimWhitespace(slot
);
1320 CFRelease(slot_name
);
1323 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1325 case kIOReturnSuccess
: {
1326 CFTypeRef parent_pci_slot_name
= NULL
;
1327 CFStringRef parent_slot
;
1329 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1330 if (parent_slot
!= NULL
) {
1331 if (slot
!= NULL
) CFRelease(slot
);
1332 slot
= (CFMutableStringRef
)parent_slot
;
1334 if (pci_slot_name
!= NULL
) {
1335 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1336 *pci_slot_name
= parent_pci_slot_name
;
1337 if (*pci_slot_name
!= NULL
) CFRetain(*pci_slot_name
);
1340 if (parent_pci_slot_name
!= NULL
) CFRelease(parent_pci_slot_name
);
1342 IOObjectRelease(parent
);
1345 case kIOReturnNoDevice
:
1346 // if we have hit the root node
1349 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1357 static CFComparisonResult
1358 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1360 #pragma unused(context)
1361 CFStringRef bsd1
= (CFStringRef
)val1
;
1362 CFStringRef bsd2
= (CFStringRef
)val2
;
1364 return CFStringCompare(bsd1
, bsd2
, 0);
1368 static CF_RETURNS_RETAINED CFStringRef
1369 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1372 CFStringRef port_name
= NULL
;
1373 CFMutableArrayRef port_names
;
1376 CFStringRef match_keys
[2];
1377 CFTypeRef match_vals
[2];
1378 CFDictionaryRef match_dict
;
1379 CFDictionaryRef matching
;
1380 io_registry_entry_t slot
;
1381 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1383 match_keys
[0] = CFSTR("AAPL,slot-name");
1384 match_vals
[0] = slot_name
;
1386 match_dict
= CFDictionaryCreate(NULL
,
1387 (const void **)match_keys
,
1388 (const void **)match_vals
,
1390 &kCFTypeDictionaryKeyCallBacks
,
1391 &kCFTypeDictionaryValueCallBacks
);
1393 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1394 match_vals
[0] = CFSTR("IOPCIDevice");
1396 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1397 match_vals
[1] = match_dict
;
1399 // note: the "matching" dictionary will be consumed by the following
1400 matching
= CFDictionaryCreate(NULL
,
1401 (const void **)match_keys
,
1402 (const void **)match_vals
,
1403 sizeof(match_keys
)/sizeof(match_keys
[0]),
1404 &kCFTypeDictionaryKeyCallBacks
,
1405 &kCFTypeDictionaryValueCallBacks
);
1406 CFRelease(match_dict
);
1408 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1409 if (kr
!= kIOReturnSuccess
) {
1410 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1411 return MACH_PORT_NULL
;
1414 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1416 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1417 io_registry_entry_t child
;
1418 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1420 kr
= IORegistryEntryCreateIterator(slot
,
1422 kIORegistryIterateRecursively
,
1424 if (kr
!= kIOReturnSuccess
) {
1425 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1426 CFRelease(port_names
);
1427 return MACH_PORT_NULL
;
1430 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1431 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1432 CFMutableDictionaryRef interface_dict
= NULL
;
1434 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1435 if (interface_dict
!= NULL
) {
1436 CFNumberRef child_if_type
;
1437 int child_ift
= ift
;
1439 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1440 if (child_if_type
!= NULL
) {
1441 if (!isA_CFNumber(child_if_type
) ||
1442 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1443 // assume that it's a match
1448 if (ift
== child_ift
) {
1449 CFStringRef if_bsdName
;
1451 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1452 if (if_bsdName
!= NULL
) {
1453 CFArrayAppendValue(port_names
, if_bsdName
);
1454 CFRelease(if_bsdName
);
1458 CFRelease(interface_dict
);
1461 IOObjectRelease(child
);
1463 IOObjectRelease(child_iterator
);
1464 IOObjectRelease(slot
);
1466 IOObjectRelease(slot_iterator
);
1468 n
= CFArrayGetCount(port_names
);
1470 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1471 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1472 if (n
!= kCFNotFound
) {
1473 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1477 CFRelease(port_names
);
1483 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1485 CFStringRef bsd_name
= NULL
;
1486 CFMutableDictionaryRef interface_dict
= NULL
;
1488 CFTypeRef pci_slot_name
;
1493 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1494 if (interface_dict
!= NULL
) {
1495 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1496 CFRelease(interface_dict
);
1499 if (bsd_name
== NULL
) {
1503 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1504 if (*slot_name
!= NULL
) {
1505 if (pci_slot_name
!= NULL
) {
1506 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1510 if (pci_slot_name
!= NULL
) CFRelease(pci_slot_name
);
1512 CFRelease(bsd_name
);
1518 isBuiltin(io_registry_entry_t interface
)
1522 slot
= pci_slot(interface
, NULL
);
1524 // interfaces which have a "slot" are not built-in
1534 isBluetoothBuiltin(Boolean
*haveController
)
1536 Boolean builtin
= FALSE
;
1537 io_object_t hciController
;
1538 io_iterator_t iter
= MACH_PORT_NULL
;
1541 kr
= IOServiceGetMatchingServices(masterPort
,
1542 IOServiceMatching("IOBluetoothHCIController"),
1544 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1545 if (kr
!= kIOReturnSuccess
) {
1546 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1548 *haveController
= FALSE
;
1551 *haveController
= TRUE
;
1553 hciController
= IOIteratorNext(iter
);
1554 IOObjectRelease(iter
);
1555 if(hciController
!= MACH_PORT_NULL
) {
1556 #if !TARGET_OS_SIMULATOR
1557 CFNumberRef idVendor
;
1559 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1560 if (idVendor
!= NULL
) {
1563 if (isA_CFNumber(idVendor
) &&
1564 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1565 (idVendorVal
== kIOUSBAppleVendorID
)) {
1569 CFRelease(idVendor
);
1571 #endif // !TARGET_OS_SIMULATOR
1573 IOObjectRelease(hciController
);
1581 isThunderbolt(io_registry_entry_t interface
)
1585 val
= IORegistryEntrySearchCFProperty(interface
,
1587 CFSTR(kPCIThunderboltString
),
1589 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1600 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1601 io_registry_entry_t interface
,
1602 CFDictionaryRef interface_dict
,
1603 io_registry_entry_t controller
,
1604 CFDictionaryRef controller_dict
,
1605 io_registry_entry_t bus
,
1606 CFDictionaryRef bus_dict
)
1608 #if TARGET_OS_SIMULATOR
1609 #pragma unused(interfacePrivate)
1610 #pragma unused(interface)
1611 #endif // TARGET_OS_SIMULATOR
1612 #pragma unused(interface_dict)
1613 #pragma unused(controller)
1614 #pragma unused(controller_dict)
1616 #pragma unused(bus_dict)
1617 #if !TARGET_OS_SIMULATOR
1619 if (interfacePrivate
->usb
.name
== NULL
) {
1620 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1622 CFSTR(kUSBProductString
),
1624 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1626 if (interfacePrivate
->usb
.vid
== NULL
) {
1627 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1629 CFSTR(kUSBVendorID
),
1631 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1633 if (interfacePrivate
->usb
.pid
== NULL
) {
1634 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1636 CFSTR(kUSBProductID
),
1638 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1640 #endif // !TARGET_OS_SIMULATOR
1647 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1648 io_registry_entry_t interface
,
1651 Boolean updated
= FALSE
;
1654 // check if a "Product Name" has been provided
1655 val
= IORegistryEntrySearchCFProperty(interface
,
1657 CFSTR(kIOPropertyProductNameKey
),
1659 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1660 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1661 // else, use "USB Product Name" if available
1662 val
= CFRetain(interfacePrivate
->usb
.name
);
1665 CFStringRef productName
;
1667 productName
= IOCopyCFStringValue(val
);
1670 if (productName
!= NULL
) {
1671 if (CFStringGetLength(productName
) > 0) {
1672 // if we have a [somewhat reasonable?] product name
1673 if (interfacePrivate
->name
!= NULL
) {
1674 CFRelease(interfacePrivate
->name
);
1676 interfacePrivate
->name
= CFRetain(productName
);
1677 if (interfacePrivate
->localized_name
!= NULL
) {
1678 CFRelease(interfacePrivate
->localized_name
);
1679 interfacePrivate
->localized_name
= NULL
;
1681 if (bundle
!= NULL
) {
1682 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1688 CFRelease(productName
);
1697 #pragma mark Interface enumeration
1700 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1701 io_registry_entry_t interface
,
1702 CFDictionaryRef interface_dict
,
1703 io_registry_entry_t controller
,
1704 CFDictionaryRef controller_dict
,
1705 io_registry_entry_t bus
,
1706 CFDictionaryRef bus_dict
);
1710 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1711 io_registry_entry_t interface
,
1712 CFStringRef override
)
1717 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1718 val
= IORegistryEntrySearchCFProperty(interface
,
1722 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1725 if (isA_CFDictionary(val
)) {
1726 if (interfacePrivate
->overrides
== NULL
) {
1727 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1729 &kCFTypeDictionaryKeyCallBacks
,
1730 &kCFTypeDictionaryValueCallBacks
);
1732 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1742 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1743 io_registry_entry_t interface
,
1744 CFDictionaryRef interface_dict
,
1745 io_registry_entry_t controller
,
1746 CFDictionaryRef controller_dict
,
1747 io_registry_entry_t bus
,
1748 CFDictionaryRef bus_dict
)
1758 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1759 if (isA_CFNumber(num
) &&
1760 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1761 interfacePrivate
->type
= CFRetain(num
);
1763 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1771 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1772 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1773 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1774 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1775 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1776 interfacePrivate
->sort_order
= kSortAirPort
;
1777 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1778 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1779 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1780 interfacePrivate
->sort_order
= kSortThunderbolt
;
1781 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1782 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1783 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1784 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1785 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1786 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1787 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1788 interfacePrivate
->sort_order
= kSortTethered
;
1789 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1790 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1791 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1792 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1795 if (interfacePrivate
->interface_type
== NULL
) {
1796 val
= IORegistryEntrySearchCFProperty(interface
,
1798 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1800 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1802 if (isA_CFString(val
)) {
1803 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1804 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1805 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1806 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1807 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1808 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1809 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1810 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1811 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1812 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1813 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1814 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1815 } else if (CFEqual(val
, CFSTR("CarPlay"))) {
1816 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1817 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1818 interfacePrivate
->sort_order
= kSortCarPlay
;
1827 if (interfacePrivate
->interface_type
== NULL
) {
1828 val
= IORegistryEntrySearchCFProperty(interface
,
1830 CFSTR(kUSBSupportsIPhoneOS
),
1832 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1834 if (isA_CFBoolean(val
) && CFBooleanGetValue(val
)) {
1835 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1836 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1837 interfacePrivate
->sort_order
= kSortTethered
;
1843 #endif // TARGET_OS_OSX
1845 if (interfacePrivate
->interface_type
== NULL
) {
1846 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1848 if (CFEqual(str
, CFSTR("radio"))) {
1849 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1850 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1851 interfacePrivate
->sort_order
= kSortOtherWireless
;
1858 if (interfacePrivate
->interface_type
== NULL
) {
1859 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1860 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1861 interfacePrivate
->sort_order
= kSortEthernet
;
1863 // BOND support only enabled for ethernet devices
1864 interfacePrivate
->supportsBond
= TRUE
;
1867 if (!CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1868 // if not Wi-Fi, enable Bridge support
1869 interfacePrivate
->supportsBridge
= TRUE
;
1873 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1875 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1878 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1880 interfacePrivate
->builtin
= isBuiltin(interface
);
1883 if (!interfacePrivate
->builtin
&&
1884 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1885 // always treat AirPort interfaces as built-in
1886 interfacePrivate
->builtin
= TRUE
;
1890 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1891 if ((interfacePrivate
->location
!= NULL
) &&
1892 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1893 CFRelease(interfacePrivate
->location
);
1894 interfacePrivate
->location
= NULL
;
1898 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1899 if (isA_CFNumber(num
) &&
1900 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1901 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1902 interfacePrivate
->supportsVLAN
= TRUE
;
1907 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1908 interfacePrivate
->localized_key
= CFSTR("airport");
1909 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1910 if ((interfacePrivate
->location
== NULL
) ||
1911 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1912 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1914 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1915 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1917 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1918 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1919 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1920 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1921 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1922 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1923 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1924 interfacePrivate
->localized_key
= CFSTR("wireless");
1925 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1926 } else if (interfacePrivate
->builtin
) {
1927 if ((interfacePrivate
->location
== NULL
) ||
1928 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1929 interfacePrivate
->localized_key
= CFSTR("ether");
1931 interfacePrivate
->localized_key
= CFSTR("multiether");
1932 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1935 io_registry_entry_t node
;
1936 CFStringRef provider
;
1941 io_registry_entry_t parent
;
1944 provider
= IORegistryEntrySearchCFProperty(node
,
1946 CFSTR(kIOProviderClassKey
),
1948 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1949 if ((provider
== NULL
) ||
1950 !CFEqual(provider
, CFSTR("IOSkywalkEthernetInterface"))) {
1951 // if not "IOSkywalkEthernetInterface" provider
1955 // skip over this node
1957 CFRelease(provider
);
1959 status
= IORegistryEntryGetParentEntry(node
,
1962 if (status
!= kIOReturnSuccess
) {
1968 // check provider class
1969 if (provider
!= NULL
) {
1970 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1971 CFStringRef port_name
;
1972 CFStringRef slot_name
;
1974 // set interface "name"
1975 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1976 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1977 if (isThunderbolt(interface
)) {
1978 if (port_name
== NULL
) {
1979 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1980 interfacePrivate
->localized_arg1
= slot_name
;
1982 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1983 interfacePrivate
->localized_arg1
= slot_name
;
1984 interfacePrivate
->localized_arg2
= port_name
;
1987 if (port_name
== NULL
) {
1988 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1989 interfacePrivate
->localized_arg1
= slot_name
;
1991 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1992 interfacePrivate
->localized_arg1
= slot_name
;
1993 interfacePrivate
->localized_arg2
= port_name
;
1998 io_registry_entry_t node
= interface
;
2000 while (provider
!= NULL
) {
2001 #if !TARGET_OS_SIMULATOR
2002 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
2003 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
2004 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
)) ||
2005 (_SC_isAppleInternal() && IOObjectConformsTo(node
, "IOUserEthernetController"))) {
2006 // get USB info (if available)
2007 processUSBInterface(interfacePrivate
,
2015 // set interface "name"
2016 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2017 interfacePrivate
->localized_key
= CFSTR("usb-ether");
2018 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2022 #endif // !TARGET_OS_SIMULATOR
2024 if (node
== interface
) {
2026 } else if (node
== controller
) {
2032 CFRelease(provider
);
2033 provider
= IORegistryEntrySearchCFProperty(node
,
2035 CFSTR(kIOProviderClassKey
),
2037 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2040 if (interfacePrivate
->localized_key
== NULL
) {
2041 update_interface_name(interfacePrivate
, interface
, FALSE
);
2045 if (provider
!= NULL
) CFRelease(provider
);
2048 if (interfacePrivate
->localized_key
== NULL
) {
2049 // if no provider, not a PCI device, or no slot information
2050 interfacePrivate
->localized_key
= CFSTR("generic-ether");
2051 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2058 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2061 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2064 interfacePrivate
->builtin
= isBuiltin(interface
);
2067 interfacePrivate
->sort_order
= kSortFireWire
;
2070 if (interfacePrivate
->builtin
) {
2071 interfacePrivate
->localized_key
= CFSTR("firewire");
2073 CFStringRef port_name
;
2074 CFStringRef slot_name
;
2076 // set interface "name"
2077 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2078 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2079 if (isThunderbolt(interface
)) {
2080 if (port_name
== NULL
) {
2081 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2082 interfacePrivate
->localized_arg1
= slot_name
;
2084 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2085 interfacePrivate
->localized_arg1
= slot_name
;
2086 interfacePrivate
->localized_arg2
= port_name
;
2089 if (port_name
== NULL
) {
2090 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2091 interfacePrivate
->localized_arg1
= slot_name
;
2093 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2094 interfacePrivate
->localized_arg1
= slot_name
;
2095 interfacePrivate
->localized_arg2
= port_name
;
2103 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2108 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2110 // Hardware (MAC) address
2111 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2112 if (isA_CFData(data
)) {
2113 interfacePrivate
->address
= CFRetain(data
);
2117 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2118 if (isA_CFString(str
)) {
2119 interfacePrivate
->prefix
= CFRetain(str
);
2123 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2124 if (isA_CFNumber(num
) &&
2125 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2126 interfacePrivate
->unit
= CFRetain(num
);
2129 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2130 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2137 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2139 CFDictionaryRef dict
;
2140 CFMutableDictionaryRef newDict
;
2142 if (interfacePrivate
->overrides
== NULL
) {
2143 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2145 &kCFTypeDictionaryKeyCallBacks
,
2146 &kCFTypeDictionaryValueCallBacks
);
2149 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2151 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2153 newDict
= CFDictionaryCreateMutable(NULL
,
2155 &kCFTypeDictionaryKeyCallBacks
,
2156 &kCFTypeDictionaryValueCallBacks
);
2158 if (script
!= NULL
) {
2159 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2161 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2163 if (CFDictionaryGetCount(newDict
) > 0) {
2164 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2166 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2170 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2171 CFRelease(interfacePrivate
->overrides
);
2172 interfacePrivate
->overrides
= NULL
;
2179 is_valid_connection_script(CFStringRef script
)
2181 char ccl
[MAXPATHLEN
];
2182 char path
[MAXPATHLEN
];
2183 sysdir_search_path_enumeration_state state
;
2185 (void) _SC_cfstring_to_cstring(script
,
2188 kCFStringEncodingUTF8
);
2190 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2191 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2192 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2194 struct stat statBuf
;
2196 if (ccl
[0] == '/') {
2197 path
[0] = '\0'; // if modemCCL is a full path
2199 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2201 strlcat(path
, ccl
, sizeof(path
));
2203 if (stat(path
, &statBuf
) != 0) {
2204 if (errno
== ENOENT
) {
2208 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2211 if (S_ISREG(statBuf
.st_mode
)) {
2212 // if we have a valid CCL script
2216 #define BUNDLE_EXT ".ccl"
2217 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2222 if ((n
<= BUNDLE_EXT_LEN
) ||
2223 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2224 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2225 if (stat(path
, &statBuf
) != 0) {
2226 if (errno
== ENOENT
) {
2230 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2234 if (S_ISDIR(statBuf
.st_mode
)) {
2235 // if we have a valid CCL bundle
2245 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2246 io_registry_entry_t interface
,
2247 CFDictionaryRef interface_dict
,
2248 io_registry_entry_t controller
,
2249 CFDictionaryRef controller_dict
,
2250 io_registry_entry_t bus
,
2251 CFDictionaryRef bus_dict
)
2253 CFStringRef base
= NULL
;
2255 Boolean isModem
= FALSE
;
2256 Boolean isWWAN
= FALSE
;
2257 CFStringRef modemCCL
= NULL
;
2261 // check if initializing
2262 val
= IORegistryEntrySearchCFProperty(interface
,
2264 kSCNetworkInterfaceInitializingKey
,
2266 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2268 Boolean initializing
;
2270 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2273 return FALSE
; // if this interface is still initializing
2278 val
= IORegistryEntrySearchCFProperty(interface
,
2282 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2284 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2289 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2290 if (interfacePrivate
->entity_device
== NULL
) {
2294 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2296 base
= CFRetain(interfacePrivate
->entity_device
);
2302 * Exclude ports named "irda" because otherwise the IrDA ports on the
2303 * original iMac (rev's A through D) show up as serial ports. Given
2304 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2305 * even support it, these ports definitely shouldn't be listed.
2307 if (CFStringCompare(base
,
2309 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2313 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2314 Boolean haveController
= FALSE
;
2317 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2318 interfacePrivate
->sort_order
= kSortBluetooth
;
2319 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2320 if (!haveController
) {
2321 // if device with no controller present
2324 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2326 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2327 interfacePrivate
->sort_order
= kSortIrDA
;
2328 } else if (isWWAN
) {
2330 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2331 interfacePrivate
->sort_order
= kSortWWAN
;
2334 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2335 interfacePrivate
->sort_order
= kSortModem
;
2339 interfacePrivate
->entity_type
= kSCEntNetModem
;
2341 // Entity (Hardware)
2342 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2343 if (!isA_CFString(ift
)) {
2347 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2351 if (CFEqual(base
, CFSTR("modem"))) {
2352 interfacePrivate
->builtin
= TRUE
;
2353 interfacePrivate
->sort_order
= kSortInternalModem
;
2354 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2355 interfacePrivate
->sort_order
= kSortUSBModem
;
2357 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2359 interfacePrivate
->sort_order
= kSortSerialPort
;
2364 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2365 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2367 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2368 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2370 // look for modem CCL, unique identifier
2371 if (interfacePrivate
->overrides
!= NULL
) {
2372 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2374 CFStringRef uniqueID
;
2376 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2377 modemCCL
= isA_CFString(modemCCL
);
2379 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2380 uniqueID
= isA_CFString(uniqueID
);
2381 if (uniqueID
!= NULL
) {
2382 // retain the device's base name and the unique id
2383 CFRelease(interfacePrivate
->entity_device
);
2384 interfacePrivate
->entity_device
= CFRetain(base
);
2385 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2390 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2391 // a bit harder for the modem CCL
2392 if (modemCCL
== NULL
) {
2393 val
= IORegistryEntrySearchCFProperty(interface
,
2397 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2399 modemCCL
= IOCopyCFStringValue(val
);
2400 if (modemCCL
!= NULL
) {
2401 set_connection_script(interfacePrivate
, modemCCL
);
2402 CFRelease(modemCCL
);
2410 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2411 interfacePrivate
->localized_key
= CFSTR("irda");
2412 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2413 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2415 CFStringRef localized
= NULL
;
2416 CFStringRef name
= NULL
;
2417 CFMutableStringRef port
;
2419 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2420 CFStringLowercase(port
, NULL
);
2423 CFStringAppend(port
, CFSTR("-port"));
2426 // set non-localized name
2427 if (bundle
!= NULL
) {
2428 name
= copy_interface_string(bundle
, port
, FALSE
);
2431 if (!CFEqual(port
, name
)) {
2432 // if [English] localization available
2433 interfacePrivate
->name
= name
;
2435 // if no [English] localization available, use TTY base name
2437 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2440 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2443 // set localized name
2444 if (bundle
!= NULL
) {
2445 localized
= copy_interface_string(bundle
, port
, TRUE
);
2447 if (localized
!= NULL
) {
2448 if (!CFEqual(port
, localized
)) {
2449 // if localization available
2450 interfacePrivate
->localized_name
= localized
;
2452 // if no localization available, use TTY base name
2453 CFRelease(localized
);
2454 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2457 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2460 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2461 // get USB info (if available)
2462 processUSBInterface(interfacePrivate
,
2470 // set interface "name"
2471 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2472 // if "ModemCCL" not provided, also check if the product/interface
2473 // name matches a CCL script
2474 if ((modemCCL
== NULL
) &&
2475 is_valid_connection_script(interfacePrivate
->name
)) {
2476 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2488 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2489 CFRelease(interfacePrivate
->entity_device
);
2490 interfacePrivate
->entity_device
= NULL
;
2492 if (base
!= NULL
) CFRelease(base
);
2499 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2502 * Create a path for a registry entry.
2506 CFStringRef str
= NULL
;
2508 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2509 if (status
== kIOReturnSuccess
) {
2510 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2511 } else if (status
== kIOReturnBadArgument
) {
2512 io_registry_entry_t parent
;
2514 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2515 if (status
== kIOReturnSuccess
) {
2516 CFStringRef str_parent
;
2518 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2519 if (str_parent
!= NULL
) {
2522 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2523 if (status
== kIOReturnSuccess
) {
2526 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2527 if (status
== kIOReturnSuccess
) {
2528 str
= CFStringCreateWithFormat(NULL
,
2535 str
= CFStringCreateWithFormat(NULL
,
2543 CFRelease(str_parent
);
2546 IOObjectRelease(parent
);
2553 static CFMutableDictionaryRef
2554 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2557 CFMutableDictionaryRef reg_dict
= NULL
;
2558 CFTypeRef value
= NULL
;
2560 reg_dict
= CFDictionaryCreateMutable(NULL
,
2562 &kCFTypeDictionaryKeyCallBacks
,
2563 &kCFTypeDictionaryValueCallBacks
);
2565 for (; idx
< numKeys
; idx
++) {
2566 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2567 if (value
!= NULL
) {
2568 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2577 isHidden(CFTypeRef hidden
)
2581 // looks at the [passed] value of the hidden property
2582 if (hidden
== NULL
) {
2586 if (isA_CFBoolean(hidden
)) {
2587 return CFBooleanGetValue(hidden
);
2588 } else if (isA_CFNumber(hidden
)) {
2589 if (CFNumberGetValue(hidden
, kCFNumberIntType
, (void *)&val
) &&
2595 return TRUE
; // if not explicitly FALSE or 0
2598 static SCNetworkInterfaceRef
2599 createInterface(io_registry_entry_t interface
,
2600 processInterface func
,
2601 CFStringRef hidden_key
,
2602 Boolean keep_hidden
)
2604 io_registry_entry_t bus
= MACH_PORT_NULL
;
2605 CFMutableDictionaryRef bus_dict
= NULL
;
2606 io_registry_entry_t controller
= MACH_PORT_NULL
;
2607 CFMutableDictionaryRef controller_dict
= NULL
;
2608 uint64_t entryID
= 0;
2609 Boolean hidden_interface
= FALSE
;
2610 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2611 CFMutableDictionaryRef interface_dict
= NULL
;
2616 const CFStringRef interface_dict_keys
[] = {
2617 CFSTR(kIOInterfaceType
),
2619 CFSTR(kIOBSDNameKey
),
2620 CFSTR(kIOPrimaryInterface
),
2621 CFSTR(kIOInterfaceNamePrefix
),
2622 CFSTR(kIOInterfaceUnit
),
2623 CFSTR(kIOTTYDeviceKey
),
2624 CFSTR(kIOTTYBaseNameKey
),
2625 CFSTR(kIOSerialBSDTypeKey
),
2629 const CFStringRef controller_dict_keys
[] = {
2631 CFSTR(kIOMACAddress
)
2634 const CFStringRef bus_dict_keys
[] = {
2638 if (hidden_key
!= NULL
) {
2640 val
= IORegistryEntrySearchCFProperty(interface
,
2644 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2646 hidden_interface
= isHidden(val
);
2648 if (hidden_interface
&& !keep_hidden
) {
2649 goto done
; // if this interface should not be exposed
2654 interface_dict
= copyIORegistryProperties(interface
,
2655 interface_dict_keys
,
2656 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2658 // get the controller node
2659 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2660 if (kr
!= kIOReturnSuccess
) {
2661 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2665 controller_dict
= copyIORegistryProperties(controller
,
2666 controller_dict_keys
,
2667 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2670 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2671 if (kr
!= kIOReturnSuccess
) {
2672 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2676 bus_dict
= copyIORegistryProperties(bus
,
2678 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2680 // get the registry entry ID
2681 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2682 if (kr
!= kIOReturnSuccess
) {
2683 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2687 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2688 assert(interfacePrivate
!= NULL
);
2689 interfacePrivate
->hiddenInterface
= hidden_interface
;
2690 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2691 interfacePrivate
->entryID
= entryID
;
2693 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2694 val
= IORegistryEntrySearchCFProperty(interface
,
2696 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2698 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2700 if (isA_CFDictionary(val
)) {
2701 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2706 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2707 // get user-notification / auto-configuration preference
2708 val
= IORegistryEntrySearchCFProperty(interface
,
2710 kSCNetworkInterfaceConfigurationActionKey
,
2712 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2714 if (isA_CFString(val
)) {
2715 interfacePrivate
->configurationAction
= CFRetain(val
);
2720 // get HiddenConfiguration preference
2721 val
= IORegistryEntrySearchCFProperty(interface
,
2723 kSCNetworkInterfaceHiddenConfigurationKey
,
2725 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2727 interfacePrivate
->hiddenConfiguration
= isHidden(val
);
2731 #if TARGET_OS_IPHONE
2732 // get TrustRequired preference
2733 val
= IORegistryEntrySearchCFProperty(interface
,
2735 kSCNetworkInterfaceTrustRequiredKey
,
2737 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2739 if (isA_CFBoolean(val
)) {
2740 interfacePrivate
->trustRequired
= CFBooleanGetValue(val
);
2744 #endif // TARGET_OS_IPHONE
2746 CFRelease(interfacePrivate
);
2747 interfacePrivate
= NULL
;
2752 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2754 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2755 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2757 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2758 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2760 return (SCNetworkInterfaceRef
)interfacePrivate
;
2764 static CF_RETURNS_RETAINED CFArrayRef
2765 findMatchingInterfaces(CFDictionaryRef matching
,
2766 processInterface func
,
2767 CFStringRef hidden_key
,
2768 Boolean keep_hidden
,
2769 Boolean keep_pre_configured
)
2771 CFMutableArrayRef interfaces
;
2772 io_registry_entry_t interface
;
2774 io_iterator_t iterator
= MACH_PORT_NULL
;
2777 * A reference to the "matching" dictionary will be consumed by the
2778 * the call to IOServiceGetMatchingServices so we bump up the retain
2783 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2784 if (kr
!= kIOReturnSuccess
) {
2785 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2789 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2791 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2792 SCNetworkInterfaceRef match
;
2794 match
= createInterface(interface
, func
, hidden_key
, keep_hidden
);
2795 if (match
!= NULL
) {
2796 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2797 CFArrayAppendValue(interfaces
, match
);
2802 IOObjectRelease(interface
);
2805 IOObjectRelease(iterator
);
2812 #pragma mark helper functions
2816 findConfiguration(CFStringRef interface_type
)
2818 for (size_t i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2819 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2830 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2832 CFIndex interfaceIndex
;
2833 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2835 if (interfacePrivate
->serviceID
== NULL
) {
2836 // if not associated with a service (yet)
2837 _SCErrorSet(kSCStatusInvalidArgument
);
2841 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2842 if (interfaceIndex
== kCFNotFound
) {
2843 // unknown interface type, use per-service configuration preferences
2844 return interfacePrivate
->interface_type
; // entity
2847 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2848 // if configuration information can be associated with this interface type
2849 return *configurations
[interfaceIndex
].entity_hardware
;
2852 _SCErrorSet(kSCStatusInvalidArgument
);
2859 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2860 CFStringRef extendedType
,
2861 Boolean requirePerInterface
)
2863 CFStringRef defaultType
;
2864 CFIndex extendedIndex
;
2865 CFIndex interfaceIndex
;
2866 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2867 Boolean isL2TP
= FALSE
;
2870 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2871 if (defaultType
== NULL
) {
2875 if (CFEqual(extendedType
, defaultType
)) {
2876 // extended and default configuration types cannot conflict
2880 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2881 if (interfaceIndex
== kCFNotFound
) {
2882 // configuration information for unknown interface type's
2883 // are stored along with the service and we don't allow
2884 // per-service extended configurations
2888 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2889 CFStringRef interfaceType
;
2891 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2892 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2893 SCNetworkInterfaceRef child
;
2895 child
= SCNetworkInterfaceGetInterface(interface
);
2896 if (child
!= NULL
) {
2897 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2898 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2905 if (requirePerInterface
&&
2906 !configurations
[interfaceIndex
].per_interface_config
&&
2908 // we don't allow per-service extended configurations (except
2909 // that we do allow IPSec as an extended type for PPP->L2TP)
2913 extendedIndex
= findConfiguration(extendedType
);
2914 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2915 // extended type cannot match a known interface type (except
2916 // that we do allow IPSec as an extended type for PPP->L2TP)
2922 * Should we check/match and specifically allow known extended
2923 * configuration types (e.g. EAPOL)?
2925 * Should we check/match and specifically block known internal
2926 * configuration types (e.g. QoSMarking)?
2928 * Lastly, should we ensure that any non-standard extended configuration
2929 * types be of the form com.myCompany.myType?
2938 _SCErrorSet(kSCStatusInvalidArgument
);
2945 CFStringRef defaultType
;
2946 CFMutableArrayRef types
;
2947 } extendedConfiguration
, *extendedConfigurationRef
;
2951 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2953 #pragma unused(value)
2954 CFStringRef extendedType
= (CFStringRef
)key
;
2955 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2957 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2958 // do not include the default configuration type
2962 if (CFArrayContainsValue(myContextRef
->types
,
2963 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2965 // if extendedType already has already been added
2969 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2976 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2978 CFIndex interfaceIndex
;
2979 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2981 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2982 if (interfaceIndex
== kCFNotFound
) {
2983 // if per-service (not per interface) configuration
2987 if (!configurations
[interfaceIndex
].per_interface_config
) {
2988 // if per-interface configuration not allowed
2992 return interfaceIndex
;
2996 static CF_RETURNS_RETAINED CFArrayRef
2997 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
3000 CFIndex interfaceIndex
;
3001 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3002 extendedConfiguration myContext
;
3003 SCNetworkServiceRef service
;
3007 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
3008 if (myContext
.defaultType
== NULL
) {
3009 myContext
.types
= NULL
;
3013 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3015 if (interfacePrivate
->serviceID
== NULL
) {
3016 // if not associated with a service (yet)
3020 interfaceIndex
= findPerInterfaceConfiguration(interface
);
3021 if (interfaceIndex
== kCFNotFound
) {
3022 // if no per-interface configuration
3026 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3027 interfacePrivate
->prefs
,
3028 interfacePrivate
->serviceID
,
3031 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3032 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3034 for (i
= 0; i
< n
; i
++) {
3035 CFDictionaryRef configs
;
3038 CFArrayRef services
;
3039 SCNetworkSetRef set
;
3041 set
= CFArrayGetValueAtIndex(sets
, i
);
3042 services
= SCNetworkSetCopyServices(set
);
3043 found
= CFArrayContainsValue(services
,
3044 CFRangeMake(0, CFArrayGetCount(services
)),
3046 CFRelease(services
);
3052 // add stored extended configuration types
3053 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3054 SCNetworkSetGetSetID(set
), // set
3055 interfacePrivate
->entity_device
, // service
3057 configs
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
3059 if (isA_CFDictionary(configs
)) {
3060 CFDictionaryApplyFunction(configs
,
3061 __addExtendedConfigurationType
,
3065 // add not-yet-stored extended configuration types
3066 if (interfacePrivate
->unsaved
!= NULL
) {
3067 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
3068 __addExtendedConfigurationType
,
3076 if (sets
!= NULL
) CFRelease(sets
);
3080 return myContext
.types
;
3084 stringCreateArray(CFStringRef str
)
3086 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3090 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3091 CFStringRef extendedType
)
3093 CFMutableArrayRef array
= NULL
;
3097 SCNetworkServiceRef service
;
3100 // known interface type, per-interface configuration preferences
3102 // 1. look for all sets which contain the associated service
3103 // 2. add a per-set path for the interface configuration for
3106 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3107 interfacePrivate
->prefs
,
3108 interfacePrivate
->serviceID
,
3109 (SCNetworkInterfaceRef
)interfacePrivate
);
3111 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3112 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3114 for (i
= 0; i
< n
; i
++) {
3115 CFArrayRef services
;
3116 SCNetworkSetRef set
;
3118 set
= CFArrayGetValueAtIndex(sets
, i
);
3119 services
= SCNetworkSetCopyServices(set
);
3120 if (CFArrayContainsValue(services
,
3121 CFRangeMake(0, CFArrayGetCount(services
)),
3123 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3124 SCNetworkSetGetSetID(set
), // set
3125 interfacePrivate
->entity_device
, // service
3126 extendedType
); // entity
3127 if (array
== NULL
) {
3128 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3130 CFArrayAppendValue(array
, path
);
3133 CFRelease(services
);
3137 if (sets
!= NULL
) CFRelease(sets
);
3143 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3144 CFStringRef extendedType
)
3146 CFArrayRef array
= NULL
;
3147 CFIndex interfaceIndex
;
3150 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3151 if (interfaceIndex
== kCFNotFound
) {
3152 // unknown interface type, use per-service configuration preferences
3153 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3154 interfacePrivate
->serviceID
, // service
3155 extendedType
); // entity
3156 array
= stringCreateArray(path
);
3160 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3161 // known interface type, per-service configuration preferences
3162 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3163 interfacePrivate
->serviceID
, // service
3164 extendedType
); // entity
3165 array
= stringCreateArray(path
);
3169 else if (interfacePrivate
->serviceID
!= NULL
) {
3170 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3178 #pragma mark SCNetworkInterface <--> preferences entity
3181 static SCNetworkServicePrivate __SCNetworkInterfaceSearchExternal
= {
3182 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
3186 const SCNetworkServiceRef __kSCNetworkInterfaceSearchExternal
= (SCNetworkServiceRef
)&__SCNetworkInterfaceSearchExternal
;
3188 static SCNetworkServicePrivate __SCNetworkInterfaceSearchSystem
= {
3189 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
3193 const SCNetworkServiceRef __kSCNetworkInterfaceSearchSystem
= (SCNetworkServiceRef
)&__SCNetworkInterfaceSearchSystem
;
3198 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3200 CFMutableDictionaryRef entity
;
3201 CFIndex interfaceIndex
;
3202 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3204 entity
= CFDictionaryCreateMutable(NULL
,
3206 &kCFTypeDictionaryKeyCallBacks
,
3207 &kCFTypeDictionaryValueCallBacks
);
3208 if (interfacePrivate
->entity_type
!= NULL
) {
3209 CFDictionarySetValue(entity
,
3210 kSCPropNetInterfaceType
,
3211 interfacePrivate
->entity_type
);
3213 if (interfacePrivate
->entity_subtype
!= NULL
) {
3214 CFDictionarySetValue(entity
,
3215 kSCPropNetInterfaceSubType
,
3216 interfacePrivate
->entity_subtype
);
3218 if (interfacePrivate
->entity_device
!= NULL
) {
3219 CFDictionarySetValue(entity
,
3220 kSCPropNetInterfaceDeviceName
,
3221 interfacePrivate
->entity_device
);
3223 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3224 CFDictionarySetValue(entity
,
3225 CFSTR("DeviceUniqueIdentifier"),
3226 interfacePrivate
->entity_device_unique
);
3228 if (interfacePrivate
->hiddenConfiguration
) {
3229 CFDictionarySetValue(entity
,
3230 kSCNetworkInterfaceHiddenConfigurationKey
,
3233 #if TARGET_OS_IPHONE
3234 if (interfacePrivate
->trustRequired
) {
3235 CFDictionarySetValue(entity
,
3236 kSCNetworkInterfaceTrustRequiredKey
,
3239 #endif // TARGET_OS_IPHONE
3241 // match the "hardware" with the lowest layer
3243 SCNetworkInterfaceRef nextInterface
;
3245 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3246 if (nextInterface
== NULL
) {
3250 interface
= nextInterface
;
3252 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3254 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3258 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3259 if (interfaceIndex
!= kCFNotFound
) {
3260 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3261 CFDictionarySetValue(entity
,
3262 kSCPropNetInterfaceHardware
,
3263 *configurations
[interfaceIndex
].entity_hardware
);
3266 CFDictionarySetValue(entity
,
3267 kSCPropNetInterfaceHardware
,
3268 interfacePrivate
->interface_type
);
3271 // add the localized display name (which will only be used when/if the
3272 // interface is removed from the system)
3273 CFDictionarySetValue(entity
,
3274 kSCPropUserDefinedName
,
3275 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3281 static SCNetworkInterfaceRef
3282 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3287 n
= CFArrayGetCount(interfaces
);
3288 for (i
= 0; i
< n
; i
++) {
3289 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3290 CFStringRef interfaceName
;
3292 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3293 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3294 CFRetain(interface
);
3302 #if !TARGET_OS_IPHONE
3303 static SCNetworkInterfaceRef
3304 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3307 SCNetworkInterfaceRef interface
= NULL
;
3309 if (prefs
== NULL
) {
3313 // check if the interface is an Ethernet Bond
3314 bonds
= SCBondInterfaceCopyAll(prefs
);
3315 if (bonds
!= NULL
) {
3316 interface
= findInterface(bonds
, ifDevice
);
3321 #endif // !TARGET_OS_IPHONE
3323 static SCNetworkInterfaceRef
3324 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3327 SCNetworkInterfaceRef interface
= NULL
;
3329 if (prefs
== NULL
) {
3333 // check if the interface is an bridge
3334 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3335 if (bridges
!= NULL
) {
3336 interface
= findInterface(bridges
, ifDevice
);
3342 static SCNetworkInterfaceRef
3343 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3345 SCNetworkInterfaceRef interface
= NULL
;
3348 if (prefs
== NULL
) {
3352 // check if the interface is a VLAN
3353 vlans
= SCVLANInterfaceCopyAll(prefs
);
3354 if (vlans
!= NULL
) {
3355 interface
= findInterface(vlans
, ifDevice
);
3365 static CFMutableDictionaryRef
3366 copy_ppp_entity(CFStringRef bsdName
)
3368 CFMutableDictionaryRef entity
= NULL
;
3369 CFStringRef pattern
;
3370 CFMutableArrayRef patterns
;
3371 CFDictionaryRef dict
;
3373 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3374 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3375 CFArrayAppendValue(patterns
, pattern
);
3377 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3378 CFArrayAppendValue(patterns
, pattern
);
3380 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3381 CFRelease(patterns
);
3384 const void * keys_q
[N_QUICK
];
3385 const void ** keys
= keys_q
;
3387 const void * vals_q
[N_QUICK
];
3388 const void ** vals
= vals_q
;
3390 n
= CFDictionaryGetCount(dict
);
3391 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3392 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3393 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3395 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3396 for (i
= 0; i
< n
; i
++) {
3397 CFArrayRef components
;
3398 CFStringRef interfaceKey
;
3399 CFDictionaryRef interfaceVal
;
3401 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3402 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3403 CFStringRef serviceID
;
3405 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3406 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3407 !CFEqual(bsdName
, ifName
)) {
3408 // if not matching PPP interface
3412 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3413 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3414 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3415 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3416 CFRelease(interfaceKey
);
3417 CFRelease(components
);
3418 if (interfaceVal
!= NULL
) {
3419 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3423 if (keys
!= keys_q
) {
3424 CFAllocatorDeallocate(NULL
, keys
);
3425 CFAllocatorDeallocate(NULL
, vals
);
3435 SCNetworkInterfaceRef
3436 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3437 CFStringRef bsdName
,
3440 #pragma unused(allocator)
3441 CFMutableDictionaryRef entity
= NULL
;
3443 SCNetworkInterfaceRef interface
;
3445 memset(&ifr
, 0, sizeof(ifr
));
3446 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3449 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3451 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3457 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3459 entity
= copy_ppp_entity(bsdName
);
3463 if (entity
== NULL
) {
3464 entity
= CFDictionaryCreateMutable(NULL
,
3466 &kCFTypeDictionaryKeyCallBacks
,
3467 &kCFTypeDictionaryValueCallBacks
);
3468 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3471 #if !TARGET_OS_IPHONE
3472 if ((flags
& kIncludeBondInterfaces
) == 0) {
3473 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3475 #endif // !TARGET_OS_IPHONE
3477 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3478 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3481 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3482 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3485 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, __kSCNetworkInterfaceSearchSystem
);
3493 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3495 CFMutableStringRef interfacePrefix
= NULL
;
3499 if (!isA_CFString(bsdName
)) {
3500 SC_log(LOG_DEBUG
, "No BSD name");
3504 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3505 length
= CFStringGetLength(interfacePrefix
);
3507 while (length
> 0) {
3508 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3509 if (lastChar
>= '0' && lastChar
<= '9') {
3510 CFStringDelete(interfacePrefix
,
3511 CFRangeMake(length
-1, 1));
3516 length
= CFStringGetLength(interfacePrefix
);
3519 return interfacePrefix
;
3524 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3525 CFStringRef prefix
);
3529 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3531 Boolean success
= FALSE
;
3532 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3534 if (!isA_SCNetworkInterface(interface
)) {
3535 SC_log(LOG_INFO
, "No interface");
3539 if (CFEqual(currentBSDName
, newBSDName
)) {
3544 if (interfacePrivate
->entity_device
!= NULL
) {
3545 CFRelease(interfacePrivate
->entity_device
);
3547 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3555 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3557 Boolean success
= FALSE
;
3558 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3559 CFStringRef oldPath
= NULL
;
3560 CFStringRef newPath
= NULL
;
3562 // Using the BSD Name update the path
3563 oldPath
= interfacePrivate
->path
;
3564 if (!isA_CFString(oldPath
)) {
3567 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3568 if (interfacePrivate
->path
!= NULL
) {
3569 CFRelease(interfacePrivate
->path
);
3571 interfacePrivate
->path
= CFRetain(newPath
);
3575 if (newPath
!= NULL
) {
3583 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3586 SCNetworkInterfacePrivateRef interfacePrivate
;
3588 if (!isA_CFString(prefix
)) {
3592 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3596 if (interfacePrivate
->prefix
!= NULL
) {
3597 CFRelease(interfacePrivate
->prefix
);
3600 interfacePrivate
->prefix
= prefix
;
3607 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3610 SCNetworkInterfacePrivateRef interfacePrivate
;
3611 CFStringRef newBSDName
= NULL
;
3612 CFStringRef oldBSDName
= NULL
;
3614 if (!isA_CFNumber(unit
)) {
3617 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3619 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3621 if (interfacePrivate
->prefix
== NULL
) {
3622 if (isA_CFString(interfacePrivate
->entity_device
)) {
3623 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3624 if (interfaceNamePrefix
== NULL
) {
3625 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3628 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3629 CFRelease(interfaceNamePrefix
);
3634 if (interfacePrivate
->prefix
!= NULL
) {
3635 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3638 // Update the BSD Name
3639 if ((newBSDName
== NULL
) ||
3640 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3641 SC_log(LOG_INFO
, "BSD name update failed");
3645 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3646 SC_log(LOG_INFO
, "IOPath update failed");
3650 if (interfacePrivate
->unit
!= NULL
) {
3651 CFRelease(interfacePrivate
->unit
);
3653 interfacePrivate
->unit
= unit
;
3656 if (newBSDName
!= NULL
) {
3657 CFRelease(newBSDName
);
3665 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3667 CFMutableDictionaryRef interface_entity
= NULL
;
3668 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3669 CFStringRef bsdName
;
3670 CFBooleanRef builtin
;
3671 CFStringRef interfaceNamePrefix
;
3672 CFNumberRef interfaceType
;
3673 CFNumberRef interfaceUnit
;
3674 CFDataRef macAddress
;
3675 CFStringRef pathMatch
;
3676 CFDictionaryRef info
= NULL
;
3679 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3680 if (!isA_CFString(bsdName
)) {
3684 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3686 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3687 if (!isA_CFString(interfaceNamePrefix
)) {
3691 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3692 if (!isA_CFNumber(interfaceType
)) {
3696 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3697 if (!isA_CFNumber(interfaceUnit
)) {
3701 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3702 if (!isA_CFData(macAddress
)) {
3706 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3707 if (!isA_CFString(pathMatch
)) {
3711 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3712 if (!isA_CFDictionary(info
)) {
3716 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3717 if (!isA_CFString(type
)) {
3721 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3722 &kCFTypeDictionaryKeyCallBacks
,
3723 &kCFTypeDictionaryValueCallBacks
);
3724 if (interfacePrivate
->active
) {
3725 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), kCFBooleanTrue
);
3727 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3728 if (interfacePrivate
->hiddenConfiguration
) {
3729 CFDictionaryAddValue(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
, kCFBooleanTrue
);
3731 if (interfacePrivate
->hiddenInterface
) {
3732 CFDictionaryAddValue(interface_entity
, kSCNetworkInterfaceHiddenInterfaceKey
, kCFBooleanTrue
);
3734 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3735 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3736 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3737 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3738 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3739 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3740 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3741 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3742 if (isA_CFArray(interfacePrivate
->matchingMACs
)) {
3743 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceMatchingMACs
), interfacePrivate
->matchingMACs
);
3751 return interface_entity
;
3756 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3757 SCNetworkServiceRef service
)
3759 SCNetworkInterfacePrivateRef interfacePrivate
;
3760 SCNetworkServicePrivateRef servicePrivate
;
3762 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3763 if (interfacePrivate
->prefs
!= NULL
) {
3764 CFRelease(interfacePrivate
->prefs
);
3765 interfacePrivate
->prefs
= NULL
;
3767 if (interfacePrivate
->serviceID
!= NULL
) {
3768 CFRelease(interfacePrivate
->serviceID
);
3769 interfacePrivate
->serviceID
= NULL
;
3772 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3773 if (servicePrivate
->prefs
!= NULL
) {
3774 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3776 if (servicePrivate
->serviceID
!= NULL
) {
3777 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3785 matchesName(CFBundleRef bundle
, CFStringRef name
, CFStringRef key
, Boolean localized
)
3787 Boolean match
= FALSE
;
3790 str
= copy_interface_string(bundle
, key
, localized
);
3792 match
= CFEqual(name
, str
);
3793 if (!match
&& CFStringHasSuffix(str
, CFSTR(" %@"))) {
3794 CFMutableStringRef str_multi
;
3796 str_multi
= CFStringCreateMutableCopy(NULL
, 0, str
);
3797 CFStringTrim(str_multi
, CFSTR("%@"));
3798 match
= CFStringHasPrefix(name
, str_multi
);
3799 CFRelease(str_multi
);
3811 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3815 if (bundle
== NULL
) {
3816 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3820 if (!isA_CFString(name
)) {
3821 // if no interface "name"
3825 // check non-localized name for a match
3826 match
= matchesName(bundle
, name
, key
, FALSE
);
3829 // check localized name for a match
3830 match
= matchesName(bundle
, name
, key
, TRUE
);
3837 static SCNetworkInterfaceRef
3838 __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef storage_entity
)
3840 CFMutableDictionaryRef interface_entity
;
3841 CFIndex interface_index
;
3842 CFStringRef interface_type
;
3843 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3844 CFBooleanRef active
;
3845 CFStringRef bsdName
;
3846 CFBooleanRef hiddenConfiguration
;
3847 CFBooleanRef hiddenInterface
;
3848 CFStringRef ifType
= kSCValNetInterfaceTypeEthernet
;
3849 CFDictionaryRef interfaceInfo
;
3850 CFBooleanRef ioBuiltin
;
3851 CFStringRef ioInterfaceNamePrefix
= NULL
;
3852 CFNumberRef ioInterfaceType
;
3853 int ioInterfaceTypeNum
;
3854 CFNumberRef ioInterfaceUnit
;
3855 CFDataRef ioMACAddress
;
3856 CFStringRef ioPathMatch
;
3857 CFArrayRef matchingMacs
;
3858 CFStringRef userDefinedName
;
3859 #if !TARGET_OS_SIMULATOR
3860 CFStringRef usbProductName
;
3861 CFNumberRef idProduct
;
3862 CFNumberRef idVendor
;
3863 #endif // !TARGET_OS_SIMULATOR
3865 /* initialize runtime */
3866 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3868 if (!isA_CFDictionary(storage_entity
)) {
3869 SC_log(LOG_INFO
, "No interface entity");
3872 active
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceActive
));
3873 if (!isA_CFBoolean(active
)) {
3874 active
= kCFBooleanFalse
;
3876 bsdName
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3877 if (!isA_CFString(bsdName
)) {
3878 SC_log(LOG_DEBUG
, "No BSD name");
3881 hiddenConfiguration
= CFDictionaryGetValue(storage_entity
, kSCNetworkInterfaceHiddenConfigurationKey
);
3882 if (!isA_CFBoolean(hiddenConfiguration
)) {
3883 hiddenConfiguration
= kCFBooleanFalse
;
3885 hiddenInterface
= CFDictionaryGetValue(storage_entity
, kSCNetworkInterfaceHiddenInterfaceKey
);
3886 if (!isA_CFBoolean(hiddenInterface
)) {
3887 hiddenInterface
= kCFBooleanFalse
;
3889 ioBuiltin
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3890 if (!isA_CFBoolean(ioBuiltin
)) {
3891 SC_log(LOG_INFO
, "No IOBuiltin property");
3894 ioInterfaceNamePrefix
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3895 if (!isA_CFString(ioInterfaceNamePrefix
)) {
3896 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3897 if (ioInterfaceNamePrefix
== NULL
) {
3898 SC_log(LOG_INFO
, "No BSD interface name prefix");
3902 CFRetain(ioInterfaceNamePrefix
);
3904 ioInterfaceType
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3905 if (!isA_CFNumber(ioInterfaceType
)) {
3906 SC_log(LOG_INFO
, "No IOInterfaceType");
3909 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3910 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3912 ioInterfaceUnit
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3913 if (!isA_CFNumber(ioInterfaceUnit
)) {
3914 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3917 ioMACAddress
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3918 if (!isA_CFData(ioMACAddress
)) {
3919 SC_log(LOG_INFO
, "No IOMACAddress");
3922 ioPathMatch
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3923 if (!isA_CFString(ioPathMatch
)) {
3924 SC_log(LOG_INFO
, "No IOPathMatch");
3927 // Check if Path contains the BSD Name in the end
3929 interfaceInfo
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3930 if (!isA_CFDictionary(interfaceInfo
)) {
3931 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3934 userDefinedName
= CFDictionaryGetValue(interfaceInfo
, kSCPropUserDefinedName
);
3935 userDefinedName
= isA_CFString(userDefinedName
);
3936 #if !TARGET_OS_SIMULATOR
3937 usbProductName
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBProductString
));
3938 usbProductName
= isA_CFString(usbProductName
);
3939 idProduct
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBProductID
));
3940 idProduct
= isA_CFNumber(idProduct
);
3941 idVendor
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBVendorID
));
3942 idVendor
= isA_CFNumber(idVendor
);
3943 #endif // !TARGET_OS_SIMULATOR
3944 matchingMacs
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceMatchingMACs
));
3945 matchingMacs
= isA_CFArray(matchingMacs
);
3947 interface_type
= CFDictionaryGetValue(storage_entity
, CFSTR(kSCNetworkInterfaceType
));
3948 if (!isA_CFString(interface_type
)) {
3949 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3953 interface_entity
= CFDictionaryCreateMutable(NULL
,
3955 &kCFTypeDictionaryKeyCallBacks
,
3956 &kCFTypeDictionaryValueCallBacks
);
3957 // set [entity] interface type
3958 if (ioInterfaceTypeNum
== IFT_ETHER
) {
3959 ifType
= kSCValNetInterfaceTypeEthernet
;
3960 } else if (ioInterfaceTypeNum
== IFT_IEEE1394
) {
3961 ifType
= kSCValNetInterfaceTypeFireWire
;
3963 ifType
= interface_type
;
3965 CFDictionarySetValue(interface_entity
,
3966 kSCPropNetInterfaceType
,
3968 // set [entity] interface hardware
3969 interface_index
= findConfiguration(interface_type
);
3970 if (interface_index
!= kCFNotFound
) {
3971 // set interface type
3972 if (configurations
[interface_index
].entity_hardware
!= NULL
) {
3973 // set interface hardware
3974 CFDictionarySetValue(interface_entity
,
3975 kSCPropNetInterfaceHardware
,
3976 *configurations
[interface_index
].entity_hardware
);
3979 CFDictionarySetValue(interface_entity
,
3980 kSCPropNetInterfaceHardware
,
3983 // set [entity] BSD interface name
3984 CFDictionarySetValue(interface_entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3985 // set [entity] hidden
3986 if (CFBooleanGetValue(hiddenConfiguration
)) {
3987 CFDictionarySetValue(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
, kCFBooleanTrue
);
3989 // set [entity] user defined name
3990 if (userDefinedName
!= NULL
) {
3991 CFDictionarySetValue(interface_entity
, kSCPropUserDefinedName
, userDefinedName
);
3994 // create the interface
3995 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_SCNetworkInterfaceCreateWithEntity(NULL
,
3997 __kSCNetworkInterfaceSearchExternal
);
3998 CFRelease(interface_entity
);
4000 // and fill in a few more of the [storage_entity] details
4001 interfacePrivate
->active
= CFBooleanGetValue(active
);
4002 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
4003 interfacePrivate
->hiddenInterface
= CFBooleanGetValue(hiddenInterface
);
4004 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
4005 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
4006 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
4007 interfacePrivate
->address
= CFRetain(ioMACAddress
);
4008 interfacePrivate
->path
= CFRetain(ioPathMatch
);
4009 #if !TARGET_OS_SIMULATOR
4010 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
4011 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
4012 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
4013 #endif // !TARGET_OS_SIMULATOR
4014 interfacePrivate
->matchingMACs
= ((matchingMacs
!= NULL
) ? CFRetain(matchingMacs
) : NULL
);
4018 if (ioInterfaceNamePrefix
!= NULL
) {
4019 CFRelease(ioInterfaceNamePrefix
);
4022 return (SCNetworkInterfaceRef
)interfacePrivate
;
4028 _SCNetworkInterfaceCacheOpen(void)
4030 if (!__SCNetworkInterfaceCacheIsOpen()) {
4031 S_interface_cache
= CFDictionaryCreateMutable(NULL
,
4033 &kCFTypeDictionaryKeyCallBacks
,
4034 &kCFTypeDictionaryValueCallBacks
);
4035 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): open", S_interface_cache
);
4042 _SCNetworkInterfaceCacheClose(void)
4044 if (__SCNetworkInterfaceCacheIsOpen()) {
4045 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): close", S_interface_cache
);
4046 CFRelease(S_interface_cache
);
4047 S_interface_cache
= NULL
;
4053 __SCNetworkInterfaceCacheAdd(CFStringRef bsdName
, CFArrayRef matchingInterfaces
)
4055 if (__SCNetworkInterfaceCacheIsOpen() &&
4057 matchingInterfaces
!= NULL
) {
4058 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): add %@", S_interface_cache
, bsdName
);
4059 CFDictionaryAddValue(S_interface_cache
, bsdName
, matchingInterfaces
);
4064 static inline Boolean
4065 __SCNetworkInterfaceCacheIsOpen(void)
4067 return (S_interface_cache
!= NULL
);
4072 __SCNetworkInterfaceCacheCopy(CFStringRef bsdName
)
4074 if (__SCNetworkInterfaceCacheIsOpen() &&
4076 CFArrayRef matchingInterfaces
= CFDictionaryGetValue(S_interface_cache
, bsdName
);
4077 if (matchingInterfaces
) {
4078 CFRetain(matchingInterfaces
);
4079 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache
, bsdName
);
4081 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache
, bsdName
);
4084 return matchingInterfaces
;
4091 SCNetworkInterfaceRef
4092 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
4093 CFDictionaryRef interface_entity
,
4094 SCNetworkServiceRef service
)
4096 #pragma unused(allocator)
4097 Boolean keepHidden
= FALSE
;
4098 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
4099 CFStringRef ifDevice
;
4100 CFStringRef ifName
= NULL
;
4101 CFStringRef ifSubType
;
4103 CFStringRef ifUnique
;
4104 CFArrayRef matching_interfaces
= NULL
;
4105 Boolean useSystemInterfaces
= TRUE
;
4106 SCPreferencesRef virtualPrefs
= NULL
;
4108 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4109 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4111 if (service
== __kSCNetworkInterfaceSearchExternal
) {
4112 // no service/prefs, ignore system interfaces
4114 useSystemInterfaces
= FALSE
;
4115 } else if (service
== __kSCNetworkInterfaceSearchSystem
) {
4116 // no service/prefs, include all system interfaces (including excluded)
4119 useSystemInterfaces
= TRUE
;
4120 } else if (service
!= NULL
) {
4121 virtualPrefs
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
4122 useSystemInterfaces
= !_SCNetworkConfigurationBypassSystemInterfaces(virtualPrefs
);
4125 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
4126 if (ifType
== NULL
) {
4128 * The interface "Type" was not specified. We'll make an
4129 * assumption that this is an "Ethernet" interface. If a
4130 * real interface exists with the provided interface name
4131 * then the actual type will be set accordingly. If not, we'll
4132 * end up crafting an "Ethernet" SCNetworkInterface that
4133 * will keep the rest of the configuration APIs happy.
4135 ifType
= kSCValNetInterfaceTypeEthernet
;
4138 if (!isA_CFString(ifType
)) {
4142 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
4143 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
4144 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4145 if (!isA_CFString(ifSubType
)) {
4150 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
4151 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
4153 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
4154 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
4155 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
4156 char bsdName
[IFNAMSIZ
];
4157 CFMutableDictionaryRef matching
;
4159 if (!isA_CFString(ifDevice
)) {
4163 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
4164 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4167 if (useSystemInterfaces
) {
4168 // Check to see if we already have the info in the cache
4169 matching_interfaces
= __SCNetworkInterfaceCacheCopy(ifDevice
);
4170 if (matching_interfaces
== NULL
) {
4171 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
4175 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
4176 if (matching
== NULL
) {
4179 matching_interfaces
= findMatchingInterfaces(matching
,
4180 processNetworkInterface
,
4181 kSCNetworkInterfaceHiddenInterfaceKey
,
4185 __SCNetworkInterfaceCacheAdd(ifDevice
, matching_interfaces
);
4186 CFRelease(matching
);
4189 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4190 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4191 CFDictionaryRef matching
;
4192 CFStringRef match_keys
[2];
4193 CFStringRef match_vals
[2];
4195 if (!isA_CFString(ifDevice
)) {
4199 if (useSystemInterfaces
) {
4200 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4201 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4203 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4204 match_vals
[1] = ifDevice
;
4206 matching
= CFDictionaryCreate(NULL
,
4207 (const void **)match_keys
,
4208 (const void **)match_vals
,
4209 sizeof(match_keys
)/sizeof(match_keys
[0]),
4210 &kCFTypeDictionaryKeyCallBacks
,
4211 &kCFTypeDictionaryValueCallBacks
);
4212 matching_interfaces
= findMatchingInterfaces(matching
,
4213 processSerialInterface
,
4214 kSCNetworkInterfaceHiddenPortKey
,
4217 CFRelease(matching
);
4219 if (ifUnique
== NULL
) {
4221 Boolean useDeviceName
= TRUE
;
4223 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4227 for (i
= 0; i
< n
; i
++) {
4228 SCNetworkInterfacePrivateRef scanPrivate
;
4230 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4231 if (scanPrivate
->entity_device_unique
!= NULL
) {
4232 useDeviceName
= FALSE
;
4238 if (useDeviceName
&& useSystemInterfaces
) {
4239 if (matching_interfaces
!= NULL
) {
4240 CFRelease(matching_interfaces
);
4243 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4244 matching
= CFDictionaryCreate(NULL
,
4245 (const void **)match_keys
,
4246 (const void **)match_vals
,
4247 sizeof(match_keys
)/sizeof(match_keys
[0]),
4248 &kCFTypeDictionaryKeyCallBacks
,
4249 &kCFTypeDictionaryValueCallBacks
);
4250 matching_interfaces
= findMatchingInterfaces(matching
,
4251 processSerialInterface
,
4252 kSCNetworkInterfaceHiddenPortKey
,
4255 CFRelease(matching
);
4258 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4259 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4260 kSCNetworkInterfaceTypeL2TP
);
4261 #pragma GCC diagnostic push
4262 #pragma GCC diagnostic ignored "-Wdeprecated"
4263 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4264 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4265 kSCNetworkInterfaceTypePPTP
);
4266 #pragma GCC diagnostic pop
4268 // XXX do we allow non-Apple variants of PPP??? XXX
4269 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4272 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4273 if (!isA_CFString(ifDevice
)) {
4277 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4278 kSCNetworkInterfaceType6to4
);
4279 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4280 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4281 kSCNetworkInterfaceTypeIPSec
);
4282 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4283 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4284 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4285 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4286 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4289 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4290 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4294 if (matching_interfaces
!= NULL
) {
4297 n
= CFArrayGetCount(matching_interfaces
);
4300 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4301 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4302 // if the unique ID's match
4303 CFRetain(interfacePrivate
);
4307 interfacePrivate
= NULL
;
4310 Boolean temp_preferences
= FALSE
;
4312 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4316 if (CFDictionaryGetValueIfPresent(interface_entity
,
4317 kSCPropUserDefinedName
,
4318 (const void **)&ifName
) &&
4319 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4323 if (virtualPrefs
== NULL
) {
4324 virtualPrefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4325 if (virtualPrefs
!= NULL
) {
4326 temp_preferences
= TRUE
;
4329 if (virtualPrefs
== NULL
) {
4332 #if !TARGET_OS_IPHONE
4333 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4334 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(virtualPrefs
, ifDevice
);
4336 #endif // !TARGET_OS_IPHONE
4337 if ((interfacePrivate
== NULL
)
4338 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4339 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(virtualPrefs
, ifDevice
);
4342 if ((interfacePrivate
== NULL
)
4343 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4344 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(virtualPrefs
, ifDevice
);
4346 if (temp_preferences
) {
4347 CFRelease(virtualPrefs
);
4348 virtualPrefs
= NULL
;
4353 if (ifUnique
!= NULL
) {
4356 // we are looking for an interface with a unique ID
4357 // so let's try to focus our choices
4358 for (i
= 0; i
< n
; i
++) {
4359 SCNetworkInterfacePrivateRef scanPrivate
;
4361 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4362 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4363 if (interfacePrivate
!= NULL
) {
4364 // if we've matched more than one interface
4365 interfacePrivate
= NULL
;
4368 interfacePrivate
= scanPrivate
;
4371 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4372 kSCPropUserDefinedName
,
4373 (const void **)&ifName
)) {
4376 // we don't have a unique ID but do have an interface
4377 // name. If the matching interfaces do have IDs than
4378 // we can try to focus our choices using the name
4379 for (i
= 0; i
< n
; i
++) {
4380 SCNetworkInterfacePrivateRef scanPrivate
;
4382 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4383 if (scanPrivate
->entity_device_unique
!= NULL
) {
4384 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4385 CFStringRef scanName
;
4387 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4388 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4389 continue; // if not the same display name
4393 if (interfacePrivate
!= NULL
) {
4394 // if we've matched more than one interface
4395 interfacePrivate
= NULL
;
4398 interfacePrivate
= scanPrivate
;
4401 if (interfacePrivate
== NULL
) {
4402 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4403 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4405 CFRetain(interfacePrivate
);
4408 CFRelease(matching_interfaces
);
4413 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4414 CFStringRef userDefinedName
;
4418 * if device not present on this system
4420 if (!useSystemInterfaces
) {
4421 if (interfacePrivate
!= NULL
) {
4422 CFRelease(interfacePrivate
);
4426 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4427 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4428 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4429 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4430 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4432 userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4433 userDefinedName
= isA_CFString(userDefinedName
);
4435 // if not consulting the current systems interfaces, use the UserDefinedName
4436 // to check the validity of preferences file
4437 if (!useSystemInterfaces
) {
4438 if (userDefinedName
!= NULL
) {
4439 CFRetain(userDefinedName
);
4440 if (interfacePrivate
->name
!= NULL
) {
4441 CFRelease(interfacePrivate
->name
);
4443 interfacePrivate
->name
= userDefinedName
;
4445 CFRetain(userDefinedName
);
4446 if (interfacePrivate
->localized_name
!= NULL
) {
4447 CFRelease(interfacePrivate
->localized_name
);
4449 interfacePrivate
->localized_name
= userDefinedName
;
4453 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4454 CFStringRef entity_hardware
;
4455 SCNetworkInterfaceRef virtualInterface
;
4457 if (!useSystemInterfaces
&&
4458 (((virtualInterface
= findBridgeInterface(virtualPrefs
, ifDevice
)) != NULL
) ||
4459 #if !TARGET_OS_IPHONE
4460 ((virtualInterface
= findBondInterface (virtualPrefs
, ifDevice
)) != NULL
) ||
4461 #endif // !TARGET_OS_IPHONE
4462 ((virtualInterface
= findVLANInterface (virtualPrefs
, ifDevice
)) != NULL
))) {
4463 CFRelease(interfacePrivate
);
4464 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4466 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4467 if (isA_CFString((entity_hardware
)) &&
4468 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4469 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4470 interfacePrivate
->localized_key
= CFSTR("airport");
4471 interfacePrivate
->sort_order
= kSortAirPort
;
4472 interfacePrivate
->builtin
= TRUE
;
4474 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4475 if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("ether")) ||
4476 __SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("multiether"))) {
4477 interfacePrivate
->sort_order
= kSortEthernet
;
4478 interfacePrivate
->builtin
= TRUE
;
4479 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("iPhone"))) {
4480 interfacePrivate
->localized_key
= CFSTR("iPhone");
4481 interfacePrivate
->sort_order
= kSortTethered
;
4482 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("iPad"))) {
4483 interfacePrivate
->localized_key
= CFSTR("iPad");
4484 interfacePrivate
->sort_order
= kSortTethered
;
4485 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("thunderbolt")) ||
4486 __SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("multithunderbolt"))) {
4487 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4488 interfacePrivate
->sort_order
= kSortThunderbolt
;
4489 interfacePrivate
->builtin
= TRUE
;
4490 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("bluetooth-pan-gn"))) {
4491 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4492 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4493 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("bluetooth-pan-nap"))) {
4494 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4495 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4496 } else if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("bluetooth-pan-u"))) {
4497 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4498 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4500 interfacePrivate
->sort_order
= kSortEthernet
;
4504 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4505 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4506 interfacePrivate
->sort_order
= kSortFireWire
;
4507 if (__SCNetworkInterfaceMatchesName(userDefinedName
, CFSTR("firewire"))) {
4508 interfacePrivate
->builtin
= TRUE
;
4510 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4511 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4512 CFStringRef entity_hardware
;
4514 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4515 if (isA_CFString((entity_hardware
)) &&
4516 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4517 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4518 interfacePrivate
->sort_order
= kSortAirPort
;
4520 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4521 interfacePrivate
->sort_order
= kSortEthernet
;
4523 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4524 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4525 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4526 interfacePrivate
->sort_order
= kSortBluetooth
;
4527 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4528 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4529 interfacePrivate
->sort_order
= kSortIrDA
;
4530 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4531 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4532 interfacePrivate
->sort_order
= kSortWWAN
;
4534 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4535 interfacePrivate
->sort_order
= kSortModem
;
4538 SCNetworkInterfaceRef child
;
4540 CFRelease(interfacePrivate
);
4541 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4542 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4543 if (interfacePrivate
== NULL
) {
4547 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4548 SCNetworkInterfaceRef child
;
4550 CFRelease(interfacePrivate
);
4551 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4552 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4553 if (interfacePrivate
== NULL
) {
4556 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4557 CFRelease(interfacePrivate
);
4558 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4559 kSCNetworkInterfaceTypeIPSec
);
4560 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4561 CFRelease(interfacePrivate
);
4562 if (!isA_CFString(ifDevice
)) {
4565 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4566 kSCNetworkInterfaceType6to4
);
4567 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4568 CFRelease(interfacePrivate
);
4569 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4570 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4571 // if vendor interface
4572 pthread_mutex_lock(&lock
);
4573 if (vendor_interface_types
== NULL
) {
4574 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4576 CFSetAddValue(vendor_interface_types
, ifType
);
4577 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4578 pthread_mutex_unlock(&lock
);
4580 // if unknown interface
4581 CFRelease(interfacePrivate
);
4582 interfacePrivate
= NULL
;
4586 val
= CFDictionaryGetValue(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
);
4587 interfacePrivate
->hiddenConfiguration
= isHidden(val
);
4588 #if TARGET_OS_IPHONE
4589 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceTrustRequiredKey
)) {
4590 interfacePrivate
->trustRequired
= TRUE
;
4592 #endif // TARGET_OS_IPHONE
4595 if (service
!= NULL
) {
4596 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4599 #if !TARGET_OS_IPHONE
4600 // set prefs & serviceID to Bond member interfaces
4601 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4606 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4607 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4608 for (i
= 0; i
< n
; i
++) {
4609 SCNetworkInterfaceRef member
;
4611 member
= CFArrayGetValueAtIndex(members
, i
);
4612 __SCNetworkInterfaceSetService(member
, service
);
4615 #endif // !TARGET_OS_IPHONE
4617 // set prefs & serviceID to Bridge member interfaces
4618 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4623 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4624 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4625 for (i
= 0; i
< n
; i
++) {
4626 SCNetworkInterfaceRef member
;
4628 member
= CFArrayGetValueAtIndex(members
, i
);
4629 __SCNetworkInterfaceSetService(member
, service
);
4632 // set prefs & serviceID to VLAN pyhsical interface
4633 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4634 SCNetworkInterfaceRef vlan_physical
;
4636 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4637 if (vlan_physical
!= NULL
) {
4638 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4643 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4644 SCNetworkInterfaceRef parent
;
4647 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4648 kSCNetworkInterfaceTypePPP
);
4649 CFRelease(interfacePrivate
);
4650 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4651 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4652 SCNetworkInterfaceRef parent
;
4655 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4656 kSCNetworkInterfaceTypeVPN
);
4657 CFRelease(interfacePrivate
);
4658 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4661 return (SCNetworkInterfaceRef
)interfacePrivate
;
4666 #pragma mark SCNetworkInterface APIs
4671 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4673 CFDictionaryRef matching
;
4674 CFArrayRef new_interfaces
;
4676 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4678 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4679 new_interfaces
= findMatchingInterfaces(matching
,
4680 processNetworkInterface
,
4681 kSCNetworkInterfaceHiddenInterfaceKey
,
4683 keep_pre_configured
);
4684 CFRelease(matching
);
4686 return new_interfaces
;
4692 __SCNetworkInterfaceCopyAll_Modem()
4694 CFDictionaryRef matching
;
4695 CFStringRef match_keys
[2];
4696 CFStringRef match_vals
[2];
4697 CFArrayRef new_interfaces
;
4699 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4700 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4702 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4703 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4705 matching
= CFDictionaryCreate(NULL
,
4706 (const void **)match_keys
,
4707 (const void **)match_vals
,
4708 sizeof(match_keys
)/sizeof(match_keys
[0]),
4709 &kCFTypeDictionaryKeyCallBacks
,
4710 &kCFTypeDictionaryValueCallBacks
);
4711 new_interfaces
= findMatchingInterfaces(matching
,
4712 processSerialInterface
,
4713 kSCNetworkInterfaceHiddenPortKey
,
4716 CFRelease(matching
);
4718 return new_interfaces
;
4724 __SCNetworkInterfaceCopyAll_RS232()
4726 CFDictionaryRef matching
;
4727 CFStringRef match_keys
[2];
4728 CFStringRef match_vals
[2];
4729 CFArrayRef new_interfaces
;
4731 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4732 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4734 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4735 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4737 matching
= CFDictionaryCreate(NULL
,
4738 (const void **)match_keys
,
4739 (const void **)match_vals
,
4740 sizeof(match_keys
)/sizeof(match_keys
[0]),
4741 &kCFTypeDictionaryKeyCallBacks
,
4742 &kCFTypeDictionaryValueCallBacks
);
4743 new_interfaces
= findMatchingInterfaces(matching
,
4744 processSerialInterface
,
4745 kSCNetworkInterfaceHiddenPortKey
,
4748 CFRelease(matching
);
4750 return new_interfaces
;
4754 #if !TARGET_OS_IPHONE
4756 addBTPANInterface(CFMutableArrayRef all_interfaces
)
4759 SCNetworkInterfaceRef interface
;
4762 n
= CFArrayGetCount(all_interfaces
);
4763 for (i
= 0; i
< n
; i
++) {
4764 SCNetworkInterfaceRef interface
;
4766 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4767 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4768 // if we already have a BT-PAN interface
4773 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4774 if (interface
!= NULL
) {
4775 // include BT-PAN interface
4776 CFArrayAppendValue(all_interfaces
, interface
);
4777 CFRelease(interface
);
4782 #endif // !TARGET_OS_IPHONE
4786 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4791 n
= CFArrayGetCount(new_interfaces
);
4792 for (i
= 0; i
< n
; i
++) {
4793 CFStringRef bsdName
;
4794 SCNetworkInterfaceRef interface
;
4796 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4797 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4798 if (bsdName
!= NULL
) {
4799 CFArrayAppendValue(all_interfaces
, interface
);
4808 __wait_for_IOKit_to_quiesce(void)
4810 CFStringRef key
= NULL
;
4813 SCDynamicStoreRef store
= NULL
;
4815 CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
4817 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4818 if (store
== NULL
) {
4822 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4823 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4824 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4827 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4832 CFArrayRef changedKeys
;
4833 CFDictionaryRef dict
;
4834 Boolean quiet
= FALSE
;
4837 dict
= SCDynamicStoreCopyValue(store
, key
);
4839 if (isA_CFDictionary(dict
) &&
4840 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4841 #if TARGET_OS_IPHONE
4842 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Complete
) ||
4843 #endif // TARGET_OS_IPHONE
4844 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4853 ok
= SCDynamicStoreNotifyWait(store
);
4855 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4859 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4860 if (changedKeys
!= NULL
) {
4861 CFRelease(changedKeys
);
4867 CRSetCrashLogMessage(NULL
);
4869 if (key
!= NULL
) CFRelease(key
);
4870 if (store
!= NULL
) CFRelease(store
);
4875 CFArrayRef
/* of SCNetworkInterfaceRef's */
4876 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4878 CFMutableArrayRef all_interfaces
;
4879 CFArrayRef new_interfaces
;
4880 Boolean temp_preferences
= FALSE
;
4882 /* initialize runtime */
4883 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4885 /* wait for IOKit to quiesce */
4886 pthread_once(&iokit_quiet
, __wait_for_IOKit_to_quiesce
);
4888 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4890 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4891 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4892 if (new_interfaces
!= NULL
) {
4893 add_interfaces(all_interfaces
, new_interfaces
);
4894 CFRelease(new_interfaces
);
4897 // get Modem interfaces
4898 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4899 if (new_interfaces
!= NULL
) {
4900 add_interfaces(all_interfaces
, new_interfaces
);
4901 CFRelease(new_interfaces
);
4904 // get serial (RS232) interfaces
4905 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4906 if (new_interfaces
!= NULL
) {
4907 add_interfaces(all_interfaces
, new_interfaces
);
4908 CFRelease(new_interfaces
);
4911 // get virtual network interfaces (Bond, Bridge, VLAN)
4912 if (prefs
== NULL
) {
4913 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4914 if (prefs
!= NULL
) {
4915 temp_preferences
= TRUE
;
4918 if (prefs
!= NULL
) {
4919 #if !TARGET_OS_IPHONE
4920 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4921 if (new_interfaces
!= NULL
) {
4922 add_interfaces(all_interfaces
, new_interfaces
);
4923 CFRelease(new_interfaces
);
4925 #endif // !TARGET_OS_IPHONE
4927 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4928 if (new_interfaces
!= NULL
) {
4929 add_interfaces(all_interfaces
, new_interfaces
);
4930 CFRelease(new_interfaces
);
4933 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4934 if (new_interfaces
!= NULL
) {
4935 add_interfaces(all_interfaces
, new_interfaces
);
4936 CFRelease(new_interfaces
);
4939 #if !TARGET_OS_IPHONE
4940 // add BT-PAN interface
4941 addBTPANInterface(all_interfaces
);
4942 #endif // !TARGET_OS_IPHONE
4944 if (temp_preferences
) CFRelease(prefs
);
4947 // all interfaces have been identified, order and return
4948 sort_interfaces(all_interfaces
);
4950 return all_interfaces
;
4954 CFArrayRef
/* of SCNetworkInterfaceRef's */
4955 SCNetworkInterfaceCopyAll()
4957 CFArrayRef all_interfaces
;
4959 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4960 return all_interfaces
;
4964 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4965 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4968 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4970 if (!isA_SCNetworkInterface(interface
)) {
4971 _SCErrorSet(kSCStatusInvalidArgument
);
4975 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4979 i
= findConfiguration(interfacePrivate
->interface_type
);
4980 if (i
!= kCFNotFound
) {
4981 if (configurations
[i
].supported_interfaces
!= doNone
) {
4982 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4983 if (configurations
[i
].supported_interfaces
& do6to4
) {
4984 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4986 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4987 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4989 if (configurations
[i
].supported_interfaces
& doPPP
) {
4990 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4992 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4993 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4997 SCNetworkInterfaceRef child
;
4999 child
= SCNetworkInterfaceGetInterface(interface
);
5000 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
5001 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
5002 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
5008 return interfacePrivate
->supported_interface_types
;
5012 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
5013 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
5016 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5018 if (!isA_SCNetworkInterface(interface
)) {
5019 _SCErrorSet(kSCStatusInvalidArgument
);
5023 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
5027 i
= findConfiguration(interfacePrivate
->interface_type
);
5028 if (i
!= kCFNotFound
) {
5029 if (configurations
[i
].supported_protocols
!= doNone
) {
5030 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
5031 if (configurations
[i
].supported_protocols
& doDNS
) {
5032 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
5034 if (configurations
[i
].supported_protocols
& doIPv4
) {
5035 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
5037 if (configurations
[i
].supported_protocols
& doIPv6
) {
5038 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
5040 if (configurations
[i
].supported_protocols
& doProxies
) {
5041 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
5043 #if !TARGET_OS_IPHONE
5044 if (configurations
[i
].supported_protocols
& doSMB
) {
5045 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
5047 #endif // !TARGET_OS_IPHONE
5053 return interfacePrivate
->supported_protocol_types
;
5057 SCNetworkInterfaceRef
5058 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
5060 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
5062 SCNetworkInterfacePrivateRef parentPrivate
;
5064 if (!isA_SCNetworkInterface(child
)) {
5065 _SCErrorSet(kSCStatusInvalidArgument
);
5069 if (!isA_CFString(interfaceType
)) {
5070 _SCErrorSet(kSCStatusInvalidArgument
);
5074 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
5075 // can't layer on top of loopback
5076 _SCErrorSet(kSCStatusInvalidArgument
);
5080 childIndex
= findConfiguration(childPrivate
->interface_type
);
5082 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
5084 childPrivate
->prefs
,
5085 childPrivate
->serviceID
);
5086 if (parentPrivate
== NULL
) {
5087 _SCErrorSet(kSCStatusFailed
);
5091 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5092 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
5093 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
5096 if (childIndex
!= kCFNotFound
) {
5097 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
5098 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
5100 // sorry, the child interface does not support PPP
5104 // if the child's interface type not known, use the child entities "Type"
5105 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
5108 if (childPrivate
->entity_device
!= NULL
) {
5109 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
5112 if (childPrivate
->entity_device_unique
!= NULL
) {
5113 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
5115 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
5116 if ((childIndex
== kCFNotFound
) ||
5117 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
5118 // if the child interface does not support L2TP
5121 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
5122 parentPrivate
->localized_key
= CFSTR("l2tp");
5123 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
5124 #pragma GCC diagnostic push
5125 #pragma GCC diagnostic ignored "-Wdeprecated"
5126 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
5127 if ((childIndex
== kCFNotFound
) ||
5128 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
5129 // if the child interface does not support PPTP
5132 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
5133 parentPrivate
->localized_key
= CFSTR("pptp");
5134 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
5135 #pragma GCC diagnostic pop
5136 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
5137 if ((childIndex
== kCFNotFound
) ||
5138 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
5139 // if the child interface does not support 6to4
5143 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
5144 parentPrivate
->localized_key
= CFSTR("6to4");
5145 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
5146 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
5147 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5148 if ((childIndex
== kCFNotFound
) ||
5149 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
5150 // if the child interface does not support IPSec
5153 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
5154 parentPrivate
->localized_key
= CFSTR("ipsec");
5155 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
5156 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5157 if (childIndex
!= kCFNotFound
) {
5158 // if not a "vendor" child interface
5162 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
5163 parentPrivate
->localized_key
= CFSTR("vpn");
5164 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
5165 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
5166 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
5167 if (childPrivate
->entity_device
!= NULL
) {
5168 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
5170 if (parentPrivate
->entity_subtype
!= NULL
) {
5171 CFArrayRef components
;
5173 CFStringRef vpnType
;
5176 // the "default" interface name is derived from the VPN type
5179 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
5182 vpnType
= parentPrivate
->entity_subtype
;
5183 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
5184 n
= CFArrayGetCount(components
);
5186 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
5187 CFMutableStringRef str
;
5189 str
= CFStringCreateMutableCopy(NULL
,
5191 CFArrayGetValueAtIndex(components
, n
- 2));
5192 (void) CFStringFindAndReplace(str
,
5195 CFRangeMake(0, CFStringGetLength(str
)),
5197 parentPrivate
->localized_name
= str
;
5199 CFRelease(components
);
5201 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
5202 // if custom interface type
5203 pthread_mutex_lock(&lock
);
5204 if (vendor_interface_types
== NULL
) {
5205 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
5207 CFSetAddValue(vendor_interface_types
, interfaceType
);
5208 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
5209 pthread_mutex_unlock(&lock
);
5211 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
5212 // a dictionary with the same
5213 // name as the interfaceType
5215 // unknown interface type
5219 parentPrivate
->hiddenConfiguration
= childPrivate
->hiddenConfiguration
;
5221 parentPrivate
->hiddenInterface
= childPrivate
->hiddenInterface
;
5223 #if TARGET_OS_IPHONE
5224 parentPrivate
->trustRequired
= childPrivate
->trustRequired
;
5225 #endif // TARGET_OS_IPHONE
5227 if (childPrivate
->overrides
!= NULL
) {
5228 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5231 // The following change handles the case where a user has both an Ethernet and
5232 // PPPoE network service. Because a PPPoE service is typically associated with
5233 // an ISP we want it to be sorted higher in the service order.
5234 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5235 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5236 if ((childPrivate
->interface_type
!= NULL
) &&
5237 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5238 parentPrivate
->sort_order
= kSortAirportPPP
;
5240 parentPrivate
->sort_order
= kSortEthernetPPP
;
5243 // set sort order of the parent to match the child interface
5244 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5247 return (SCNetworkInterfaceRef
)parentPrivate
;
5251 CFRelease(parentPrivate
);
5252 _SCErrorSet(kSCStatusInvalidArgument
);
5259 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5261 CFDictionaryRef config
= NULL
;
5262 CFStringRef defaultType
;
5263 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5265 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5266 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5268 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5269 if (defaultType
!= NULL
) {
5273 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5274 SCNetworkSetGetSetID(set
), // set
5275 interfacePrivate
->entity_device
, // interface
5276 defaultType
); // entity
5278 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5281 if (config
== NULL
) {
5282 // if the "set" does not have a saved configuration, use
5283 // the [template] "interface" configuration
5284 if (interfacePrivate
->unsaved
!= NULL
) {
5285 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5286 if (config
== (CFDictionaryRef
)kCFNull
) {
5291 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5302 static CFDictionaryRef
5303 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5304 CFStringRef extendedType
)
5306 CFDictionaryRef config
= NULL
;
5307 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5310 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5311 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5313 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5314 if (paths
!= NULL
) {
5317 path
= CFArrayGetValueAtIndex(paths
, 0);
5318 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5322 if (interfacePrivate
->unsaved
!= NULL
) {
5323 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5324 if (config
== (CFDictionaryRef
)kCFNull
) {
5330 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5339 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5341 CFDictionaryRef config
;
5342 CFStringRef defaultType
;
5344 if (!isA_SCNetworkInterface(interface
)) {
5345 _SCErrorSet(kSCStatusInvalidArgument
);
5349 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5350 if (defaultType
== NULL
) {
5354 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5355 if (config
== NULL
) {
5356 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5357 SCNetworkInterfacePrivateRef interfacePrivate
;
5360 // if AirPort interface, check for a per-service config
5361 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5362 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5363 interfacePrivate
->serviceID
, // service
5364 kSCEntNetAirPort
); // entity
5365 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5369 if (config
== NULL
) {
5370 _SCErrorSet(kSCStatusOK
);
5378 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5379 CFStringRef extendedType
)
5381 CFDictionaryRef config
;
5383 if (!isA_SCNetworkInterface(interface
)) {
5384 _SCErrorSet(kSCStatusInvalidArgument
);
5388 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5389 _SCErrorSet(kSCStatusInvalidArgument
);
5393 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5394 if (config
== NULL
) {
5395 _SCErrorSet(kSCStatusOK
);
5404 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5406 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5408 return interfacePrivate
->entity_type
;
5414 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5416 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5418 return interfacePrivate
->entity_subtype
;
5423 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5425 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5427 if (!isA_SCNetworkInterface(interface
)) {
5428 _SCErrorSet(kSCStatusInvalidArgument
);
5432 if ((interfacePrivate
->interface
!= NULL
) &&
5433 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5434 _SCErrorSet(kSCStatusOK
);
5438 return interfacePrivate
->entity_device
;
5443 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5445 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5447 if (!isA_SCNetworkInterface(interface
)) {
5448 _SCErrorSet(kSCStatusInvalidArgument
);
5452 if ((interfacePrivate
->address
!= NULL
) &&
5453 (interfacePrivate
->addressString
== NULL
)) {
5457 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5460 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5461 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5463 if (n
> sizeof(mac
)) {
5464 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5467 for (cp
= mac_p
; n
> 0; n
-= 3) {
5468 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5471 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5472 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5475 return interfacePrivate
->addressString
;
5479 SCNetworkInterfaceRef
5480 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5482 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5484 if (!isA_SCNetworkInterface(interface
)) {
5485 _SCErrorSet(kSCStatusInvalidArgument
);
5489 return interfacePrivate
->interface
;
5494 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5496 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5498 if (!isA_SCNetworkInterface(interface
)) {
5499 _SCErrorSet(kSCStatusInvalidArgument
);
5503 return interfacePrivate
->interface_type
;
5508 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5510 CFStringRef str
= NULL
;
5513 str
= CFBundleCopyLocalizedString(bundle
,
5516 NETWORKINTERFACE_LOCALIZATIONS
);
5518 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5521 NETWORKINTERFACE_LOCALIZATIONS
);
5529 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5531 static Boolean reported
= FALSE
;
5532 CFStringRef str
= NULL
;
5534 str
= copy_string_from_bundle(bundle
, key
, localized
);
5537 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5543 if (CFEqual(str
, key
) && !reported
) {
5544 const CFStringRef knownStrKey
= CFSTR("airport");
5545 CFStringRef knownStrValue
= NULL
;
5547 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5548 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5549 /* We are here because we requested for a localized/non-localized string
5550 based on the localization key, but we were given the same key/NULL back,
5551 implying a bad...bad thing!
5553 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5557 #if TARGET_OS_IPHONE
5558 /* ...and we want to know about it! */
5559 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5560 #endif //TARGET_OS_IPHONE
5564 if (knownStrValue
!= NULL
) {
5565 CFRelease(knownStrValue
);
5575 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5577 CFMutableStringRef local
;
5580 local
= CFStringCreateMutable(NULL
, 0);
5582 while (interface
!= NULL
) {
5583 Boolean added
= FALSE
;
5584 SCNetworkInterfaceRef child
= NULL
;
5585 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5587 if ((interfacePrivate
->interface
!= NULL
) &&
5588 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5589 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5590 child
= interfacePrivate
->interface
;
5593 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5595 CFStringRef key
= interfacePrivate
->localized_key
;
5597 if (oldLocalization
) {
5598 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5599 interfacePrivate
->localized_key
);
5601 fmt
= copy_interface_string(bundle
, key
, localized
);
5603 CFStringAppendFormat(local
,
5606 interfacePrivate
->localized_arg1
,
5607 interfacePrivate
->localized_arg2
);
5611 if (oldLocalization
) {
5617 (interfacePrivate
->prefs
!= NULL
) &&
5618 (interfacePrivate
->serviceID
!= NULL
) &&
5620 CFDictionaryRef entity
;
5623 // check for (and use) the name of the interface when it
5624 // was last available
5625 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5626 interfacePrivate
->serviceID
,
5627 kSCEntNetInterface
);
5628 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5630 if (isA_CFDictionary(entity
)) {
5633 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5634 if (isA_CFString(name
)) {
5635 CFStringAppend(local
, name
);
5642 // create (non-)localized name based on the interface type
5643 CFStringAppend(local
, interfacePrivate
->interface_type
);
5645 // ... and, if this is a leaf node, the interface device
5646 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5647 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5651 if (child
!= NULL
) {
5652 // if this interface is layered over another
5653 CFStringAppend(local
, CFSTR(" --> "));
5659 name
= CFStringCreateCopy(NULL
, local
);
5666 #if !TARGET_OS_IPHONE
5669 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5673 if (!isA_SCNetworkInterface(interface
)) {
5674 _SCErrorSet(kSCStatusInvalidArgument
);
5678 name
= copy_display_name(interface
, TRUE
, TRUE
);
5685 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5687 CFStringRef localized_name
;
5689 if (!isA_SCNetworkInterface(interface
)) {
5690 _SCErrorSet(kSCStatusInvalidArgument
);
5694 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5695 return localized_name
;
5697 #endif // !TARGET_OS_IPHONE
5701 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5703 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5705 if (!isA_SCNetworkInterface(interface
)) {
5711 if (interfacePrivate
->name
!= NULL
) {
5712 CFRelease(interfacePrivate
->name
);
5714 interfacePrivate
->name
= name
;
5719 if (interfacePrivate
->localized_name
!= NULL
) {
5720 CFRelease(interfacePrivate
->localized_name
);
5722 interfacePrivate
->localized_name
= name
;
5727 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5729 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5731 if (!isA_SCNetworkInterface(interface
)) {
5735 return interfacePrivate
->name
;
5741 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5743 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5745 if (!isA_SCNetworkInterface(interface
)) {
5746 _SCErrorSet(kSCStatusInvalidArgument
);
5750 if (interfacePrivate
->name
== NULL
) {
5751 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5754 return interfacePrivate
->name
;
5759 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5761 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5763 if (!isA_SCNetworkInterface(interface
)) {
5764 _SCErrorSet(kSCStatusInvalidArgument
);
5768 if (interfacePrivate
->localized_name
== NULL
) {
5769 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5772 return interfacePrivate
->localized_name
;
5778 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5780 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5781 CFPropertyListRef overrides
= NULL
;
5783 if (interfacePrivate
->overrides
!= NULL
) {
5784 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5792 SCNetworkInterfaceGetTypeID(void)
5794 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5795 return __kSCNetworkInterfaceTypeID
;
5801 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5802 SCNetworkInterfaceRef interface
,
5803 CFStringRef defaultType
,
5804 CFDictionaryRef config
,
5807 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5810 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5811 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5813 if (defaultType
== NULL
) {
5814 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5815 if (defaultType
== NULL
) {
5820 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5827 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5828 SCNetworkSetGetSetID(set
), // set
5829 interfacePrivate
->entity_device
, // interface
5830 defaultType
); // entity
5832 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
, path
, config
, FALSE
);
5835 // if configuration has been saved
5836 if (interfacePrivate
->unsaved
!= NULL
) {
5837 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5838 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5839 CFRelease(interfacePrivate
->unsaved
);
5840 interfacePrivate
->unsaved
= NULL
;
5846 if (config
== NULL
) {
5847 // remember that we are clearing the configuration
5848 config
= (CFDictionaryRef
)kCFNull
;
5851 if (interfacePrivate
->unsaved
== NULL
) {
5852 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5854 &kCFTypeDictionaryKeyCallBacks
,
5855 &kCFTypeDictionaryValueCallBacks
);
5857 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5860 _SCErrorSet(kSCStatusNoKey
);
5871 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5872 CFStringRef extendedType
,
5873 CFDictionaryRef config
,
5876 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5880 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5881 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5883 if (extendedType
== NULL
) {
5884 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5885 if (extendedType
== NULL
) {
5890 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5894 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5895 if (paths
!= NULL
) {
5899 n
= CFArrayGetCount(paths
);
5900 for (i
= 0; i
< n
; i
++) {
5903 path
= CFArrayGetValueAtIndex(paths
, i
);
5904 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
, path
, config
, FALSE
);
5911 // if configuration has been saved
5912 if (interfacePrivate
->unsaved
!= NULL
) {
5913 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5914 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5915 CFRelease(interfacePrivate
->unsaved
);
5916 interfacePrivate
->unsaved
= NULL
;
5924 if (config
== NULL
) {
5925 // remember that we are clearing the configuration
5926 config
= (CFDictionaryRef
)kCFNull
;
5929 if (interfacePrivate
->unsaved
== NULL
) {
5930 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5932 &kCFTypeDictionaryKeyCallBacks
,
5933 &kCFTypeDictionaryValueCallBacks
);
5935 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5938 _SCErrorSet(kSCStatusNoKey
);
5947 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5949 CFStringRef defaultType
;
5952 if (!isA_SCNetworkInterface(interface
)) {
5953 _SCErrorSet(kSCStatusInvalidArgument
);
5957 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5958 if (defaultType
== NULL
) {
5962 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5964 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5966 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5974 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5975 CFStringRef extendedType
,
5976 CFDictionaryRef config
)
5980 if (!isA_SCNetworkInterface(interface
)) {
5981 _SCErrorSet(kSCStatusInvalidArgument
);
5985 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5989 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5991 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5993 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
6001 #pragma mark SCNetworkInterface [Refresh Configuration] API
6005 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
6010 if (!isA_CFString(ifName
)) {
6011 _SCErrorSet(kSCStatusInvalidArgument
);
6015 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
6016 kSCDynamicStoreDomainState
,
6018 kSCEntNetRefreshConfiguration
);
6019 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
6026 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
6028 CFDataRef data
= NULL
;
6030 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
6031 uint32_t status
= kSCStatusOK
;
6032 CFDataRef reply
= NULL
;
6034 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
6035 ok
= __SCPreferencesCreate_helper(prefs
);
6041 // serialize the interface name
6042 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
6047 // have the helper "refresh" the configuration
6048 status
= kSCStatusOK
;
6050 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
6051 SCHELPER_MSG_INTERFACE_REFRESH
,
6055 if (data
!= NULL
) CFRelease(data
);
6060 if (status
!= kSCStatusOK
) {
6069 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
6070 _SCHelperClose(&prefsPrivate
->helper_port
);
6073 status
= kSCStatusAccessError
;
6078 _SCErrorSet(status
);
6084 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
6087 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6089 if (!isA_SCNetworkInterface(interface
)) {
6090 _SCErrorSet(kSCStatusInvalidArgument
);
6094 ifName
= SCNetworkInterfaceGetBSDName(interface
);
6095 if (ifName
== NULL
) {
6096 _SCErrorSet(kSCStatusInvalidArgument
);
6100 if (interfacePrivate
->prefs
!= NULL
) {
6101 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
6102 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
6104 if (prefsPrivate
->authorizationData
!= NULL
) {
6105 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
6109 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
6113 #if !TARGET_OS_IPHONE
6115 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
6117 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
6119 #endif // !TARGET_OS_IPHONE
6123 #pragma mark SCNetworkInterface Password APIs
6127 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
6129 CFStringRef unique_id
= NULL
;
6131 if (config
!= NULL
) {
6132 CFStringRef encryption
;
6134 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
6135 if (isA_CFString(encryption
) &&
6136 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
6137 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
6140 if (unique_id
== NULL
) {
6141 unique_id
= serviceID
;
6149 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
6151 CFMutableStringRef shared_id
= NULL
;
6153 if (config
!= NULL
) {
6154 CFStringRef encryption
;
6156 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
6157 if (isA_CFString(encryption
) &&
6158 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
6159 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
6160 if (shared_id
!= NULL
) {
6161 CFRetain(shared_id
);
6166 if (shared_id
== NULL
) {
6167 CFStringRef unique_id
;
6169 unique_id
= getPasswordID(config
, serviceID
);
6170 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6171 CFStringAppend(shared_id
, CFSTR(".SS"));
6179 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
6181 CFMutableStringRef xauth_id
= NULL
;
6183 if (config
!= NULL
) {
6184 CFStringRef encryption
;
6186 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
6187 if (isA_CFString(encryption
) &&
6188 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
6189 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
6190 if (xauth_id
!= NULL
) {
6196 if (xauth_id
== NULL
) {
6197 CFStringRef unique_id
;
6199 unique_id
= getPasswordID(config
, serviceID
);
6200 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6201 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
6209 checkInterfacePassword(SCNetworkInterfaceRef interface
,
6210 SCNetworkInterfacePasswordType passwordType
,
6211 SCPreferencesRef
*prefs
,
6212 CFStringRef
*serviceID
)
6214 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6216 if (!isA_SCNetworkInterface(interface
)) {
6220 *serviceID
= interfacePrivate
->serviceID
;
6221 if (*serviceID
== NULL
) {
6225 *prefs
= interfacePrivate
->prefs
;
6226 if (*prefs
== NULL
) {
6230 switch (passwordType
) {
6231 case kSCNetworkInterfacePasswordTypePPP
: {
6232 CFStringRef interfaceType
;
6234 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6235 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6243 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6244 CFStringRef interfaceType
;
6246 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6247 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6248 interface
= SCNetworkInterfaceGetInterface(interface
);
6249 if (interface
!= NULL
) {
6250 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6251 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6252 // if PPP->L2TP interface
6256 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6257 // if IPSec interface
6264 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6268 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6269 CFStringRef interfaceType
;
6271 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6272 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6273 // if IPSec interface
6280 case kSCNetworkInterfacePasswordTypeVPN
: {
6281 CFStringRef interfaceType
;
6283 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6284 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6300 _SCErrorSet(kSCStatusInvalidArgument
);
6306 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6307 SCNetworkInterfacePasswordType passwordType
)
6309 Boolean exists
= FALSE
;
6310 SCPreferencesRef prefs
= NULL
;
6311 CFStringRef serviceID
= NULL
;
6313 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6317 switch (passwordType
) {
6318 case kSCNetworkInterfacePasswordTypePPP
: {
6319 CFDictionaryRef config
;
6320 CFStringRef unique_id
;
6322 // get configuration
6323 config
= SCNetworkInterfaceGetConfiguration(interface
);
6326 unique_id
= getPasswordID(config
, serviceID
);
6329 exists
= __extract_password(prefs
,
6331 kSCPropNetPPPAuthPassword
,
6332 kSCPropNetPPPAuthPasswordEncryption
,
6333 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6339 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6340 CFDictionaryRef config
;
6342 CFStringRef shared_id
;
6344 // get configuration
6345 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6347 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6349 config
= SCNetworkInterfaceGetConfiguration(interface
);
6352 // get sharedSecret ID
6353 shared_id
= copySharedSecretID(config
, serviceID
);
6356 exists
= __extract_password(prefs
,
6358 kSCPropNetIPSecSharedSecret
,
6359 kSCPropNetIPSecSharedSecretEncryption
,
6360 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6363 CFRelease(shared_id
);
6367 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6368 CFDictionaryRef config
;
6369 CFStringRef unique_id
= NULL
;
6371 // get configuration
6372 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6374 // get 802.1X identifier
6375 if (config
!= NULL
) {
6376 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6378 if (!isA_CFString(unique_id
)) {
6383 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6387 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6388 CFDictionaryRef config
;
6389 CFStringRef xauth_id
;
6391 // get configuration
6392 config
= SCNetworkInterfaceGetConfiguration(interface
);
6395 xauth_id
= copyXAuthID(config
, serviceID
);
6398 exists
= __extract_password(prefs
,
6400 kSCPropNetIPSecXAuthPassword
,
6401 kSCPropNetIPSecXAuthPasswordEncryption
,
6402 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6405 CFRelease(xauth_id
);
6409 case kSCNetworkInterfacePasswordTypeVPN
: {
6410 CFDictionaryRef config
;
6413 // get configuration
6414 config
= SCNetworkInterfaceGetConfiguration(interface
);
6417 vpn_id
= getPasswordID(config
, serviceID
);
6420 exists
= __extract_password(prefs
,
6422 kSCPropNetVPNAuthPassword
,
6423 kSCPropNetVPNAuthPasswordEncryption
,
6424 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6431 _SCErrorSet(kSCStatusInvalidArgument
);
6440 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6441 SCNetworkInterfacePasswordType passwordType
)
6443 CFDataRef password
= NULL
;
6444 SCPreferencesRef prefs
= NULL
;
6445 CFStringRef serviceID
= NULL
;
6447 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6451 switch (passwordType
) {
6452 case kSCNetworkInterfacePasswordTypePPP
: {
6453 CFDictionaryRef config
;
6454 CFStringRef unique_id
;
6456 // get configuration
6457 config
= SCNetworkInterfaceGetConfiguration(interface
);
6460 unique_id
= getPasswordID(config
, serviceID
);
6463 (void) __extract_password(prefs
,
6465 kSCPropNetPPPAuthPassword
,
6466 kSCPropNetPPPAuthPasswordEncryption
,
6467 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6473 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6474 CFDictionaryRef config
;
6476 CFStringRef shared_id
;
6478 // get configuration
6479 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6481 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6483 config
= SCNetworkInterfaceGetConfiguration(interface
);
6486 // get sharedSecret ID
6487 shared_id
= copySharedSecretID(config
, serviceID
);
6490 (void) __extract_password(prefs
,
6492 kSCPropNetIPSecSharedSecret
,
6493 kSCPropNetIPSecSharedSecretEncryption
,
6494 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6498 CFRelease(shared_id
);
6502 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6503 CFDictionaryRef config
;
6504 CFStringRef unique_id
= NULL
;
6506 // get configuration
6507 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6509 // get 802.1X identifier
6510 if (config
!= NULL
) {
6511 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6513 if (!isA_CFString(unique_id
)) {
6514 _SCErrorSet(kSCStatusFailed
);
6519 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6523 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6524 CFDictionaryRef config
;
6525 CFStringRef xauth_id
;
6527 // get configuration
6528 config
= SCNetworkInterfaceGetConfiguration(interface
);
6531 xauth_id
= copyXAuthID(config
, serviceID
);
6534 (void) __extract_password(prefs
,
6536 kSCPropNetIPSecXAuthPassword
,
6537 kSCPropNetIPSecXAuthPasswordEncryption
,
6538 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6541 CFRelease(xauth_id
);
6545 case kSCNetworkInterfacePasswordTypeVPN
: {
6546 CFDictionaryRef config
;
6549 // get configuration
6550 config
= SCNetworkInterfaceGetConfiguration(interface
);
6553 vpn_id
= getPasswordID(config
, serviceID
);
6556 (void) __extract_password(prefs
,
6558 kSCPropNetVPNAuthPassword
,
6559 kSCPropNetVPNAuthPasswordEncryption
,
6560 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6567 _SCErrorSet(kSCStatusInvalidArgument
);
6576 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6577 SCNetworkInterfacePasswordType passwordType
)
6580 SCPreferencesRef prefs
= NULL
;
6581 CFStringRef serviceID
= NULL
;
6583 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6587 switch (passwordType
) {
6588 case kSCNetworkInterfacePasswordTypePPP
: {
6589 CFDictionaryRef config
;
6590 CFDictionaryRef newConfig
= NULL
;
6591 CFStringRef unique_id
;
6593 // get configuration
6594 config
= SCNetworkInterfaceGetConfiguration(interface
);
6597 unique_id
= getPasswordID(config
, serviceID
);
6600 ok
= __remove_password(prefs
,
6602 kSCPropNetPPPAuthPassword
,
6603 kSCPropNetPPPAuthPasswordEncryption
,
6604 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6608 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6609 if (newConfig
!= NULL
) CFRelease(newConfig
);
6615 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6616 CFDictionaryRef config
;
6618 CFDictionaryRef newConfig
= NULL
;
6619 CFStringRef shared_id
;
6621 // get configuration
6622 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6624 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6626 config
= SCNetworkInterfaceGetConfiguration(interface
);
6629 // get sharedSecret ID
6630 shared_id
= copySharedSecretID(config
, serviceID
);
6633 ok
= __remove_password(prefs
,
6635 kSCPropNetIPSecSharedSecret
,
6636 kSCPropNetIPSecSharedSecretEncryption
,
6637 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6642 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6646 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6649 if (newConfig
!= NULL
) CFRelease(newConfig
);
6652 CFRelease(shared_id
);
6656 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6657 CFDictionaryRef config
;
6658 CFStringRef unique_id
= NULL
;
6660 // get configuration
6661 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6663 // get 802.1X identifier
6664 if (config
!= NULL
) {
6665 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6667 if (!isA_CFString(unique_id
)) {
6668 _SCErrorSet(kSCStatusFailed
);
6673 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6677 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6678 CFDictionaryRef config
;
6679 CFDictionaryRef newConfig
= NULL
;
6680 CFStringRef xauth_id
;
6682 // get configuration
6683 config
= SCNetworkInterfaceGetConfiguration(interface
);
6686 xauth_id
= copyXAuthID(config
, serviceID
);
6689 ok
= __remove_password(prefs
,
6691 kSCPropNetIPSecXAuthPassword
,
6692 kSCPropNetIPSecXAuthPasswordEncryption
,
6693 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6697 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6698 if (newConfig
!= NULL
) CFRelease(newConfig
);
6701 CFRelease(xauth_id
);
6705 case kSCNetworkInterfacePasswordTypeVPN
: {
6706 CFDictionaryRef config
;
6707 CFDictionaryRef newConfig
= NULL
;
6710 // get configuration
6711 config
= SCNetworkInterfaceGetConfiguration(interface
);
6714 vpn_id
= getPasswordID(config
, serviceID
);
6717 ok
= __remove_password(prefs
,
6719 kSCPropNetVPNAuthPassword
,
6720 kSCPropNetVPNAuthPasswordEncryption
,
6721 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6725 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6726 if (newConfig
!= NULL
) CFRelease(newConfig
);
6732 _SCErrorSet(kSCStatusInvalidArgument
);
6741 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6742 SCNetworkInterfacePasswordType passwordType
,
6744 CFDictionaryRef options
)
6746 CFStringRef account
= NULL
;
6747 CFDictionaryRef config
;
6748 CFStringRef description
= NULL
;
6749 CFStringRef label
= NULL
;
6751 SCPreferencesRef prefs
= NULL
;
6752 CFStringRef serviceID
= NULL
;
6754 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6758 switch (passwordType
) {
6759 case kSCNetworkInterfacePasswordTypePPP
: {
6760 SCNetworkServiceRef service
= NULL
;
6761 CFStringRef unique_id
;
6763 // get configuration
6764 config
= SCNetworkInterfaceGetConfiguration(interface
);
6767 unique_id
= getPasswordID(config
, serviceID
);
6769 // get "Account", "Name", "Kind"
6770 if (config
!= NULL
) {
6771 // auth name --> keychain "Account"
6772 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6774 // PPP [user defined] "name" --> keychain "Name"
6775 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6778 if (label
== NULL
) {
6779 // service name --> keychain "Name"
6780 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6785 label
= SCNetworkServiceGetName(service
);
6786 if (label
== NULL
) {
6787 // interface name --> keychain "Name"
6788 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6792 if (bundle
!= NULL
) {
6793 // "PPP Password" --> keychain "Kind"
6794 description
= CFBundleCopyLocalizedString(bundle
,
6795 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6796 CFSTR("PPP Password"),
6801 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6803 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6804 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6809 CFMutableDictionaryRef newConfig
;
6811 if (config
!= NULL
) {
6812 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6814 newConfig
= CFDictionaryCreateMutable(NULL
,
6816 &kCFTypeDictionaryKeyCallBacks
,
6817 &kCFTypeDictionaryValueCallBacks
);
6819 CFDictionarySetValue(newConfig
,
6820 kSCPropNetPPPAuthPassword
,
6822 CFDictionarySetValue(newConfig
,
6823 kSCPropNetPPPAuthPasswordEncryption
,
6824 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6825 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6826 CFRelease(newConfig
);
6829 if (description
!= NULL
) CFRelease(description
);
6830 if (service
!= NULL
) CFRelease(service
);
6834 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6835 CFDictionaryRef baseConfig
= NULL
;
6837 SCNetworkServiceRef service
= NULL
;
6838 CFStringRef shared_id
;
6840 // get configuration
6841 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6842 config
= SCNetworkInterfaceGetConfiguration(interface
);
6844 baseConfig
= config
;
6845 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6848 // get sharedSecret ID
6849 shared_id
= copySharedSecretID(config
, serviceID
);
6851 // get "Account", "Name", "Kind"
6852 if (config
!= NULL
) {
6853 CFStringRef localIdentifier
;
6854 CFStringRef localIdentifierType
;
6856 if (CFDictionaryGetValueIfPresent(config
,
6857 kSCPropNetIPSecLocalIdentifierType
,
6858 (const void **)&localIdentifierType
)
6859 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6860 && CFDictionaryGetValueIfPresent(config
,
6861 kSCPropNetIPSecLocalIdentifier
,
6862 (const void **)&localIdentifier
)
6863 && isA_CFString(localIdentifier
)) {
6864 // local identifier --> keychain "Account"
6865 account
= localIdentifier
;
6868 // PPP [user defined] "name" --> keychain "Name"
6870 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6872 if (baseConfig
!= NULL
) {
6873 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6878 if (label
== NULL
) {
6879 // service name --> keychain "Name"
6880 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6885 label
= SCNetworkServiceGetName(service
);
6886 if (label
== NULL
) {
6887 // interface name --> keychain "Name"
6888 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6892 if (bundle
!= NULL
) {
6893 // "IPSec Shared Secret" --> keychain "Kind"
6894 description
= CFBundleCopyLocalizedString(bundle
,
6895 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6896 CFSTR("IPSec Shared Secret"),
6901 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6903 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6904 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6909 CFMutableDictionaryRef newConfig
= NULL
;
6911 if (config
!= NULL
) {
6912 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6914 newConfig
= CFDictionaryCreateMutable(NULL
,
6916 &kCFTypeDictionaryKeyCallBacks
,
6917 &kCFTypeDictionaryValueCallBacks
);
6919 CFDictionarySetValue(newConfig
,
6920 kSCPropNetIPSecSharedSecret
,
6922 CFDictionarySetValue(newConfig
,
6923 kSCPropNetIPSecSharedSecretEncryption
,
6924 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6926 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6930 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6932 CFRelease(newConfig
);
6935 if (description
!= NULL
) CFRelease(description
);
6936 if (service
!= NULL
) CFRelease(service
);
6937 CFRelease(shared_id
);
6941 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6942 CFStringRef account
= NULL
;
6943 CFStringRef unique_id
= NULL
;
6945 // get configuration
6946 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6948 // get 802.1X identifier
6949 if (config
!= NULL
) {
6950 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6951 unique_id
= isA_CFString(unique_id
);
6953 if (unique_id
!= NULL
) {
6954 CFRetain(unique_id
);
6958 uuid
= CFUUIDCreate(NULL
);
6959 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6963 // 802.1x UserName --> keychain "Account"
6964 if (config
!= NULL
) {
6965 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6968 // get "Name", "Kind"
6969 if (bundle
!= NULL
) {
6970 CFStringRef interface_name
;
6972 // "Network Connection (%@)" --> keychain "Name"
6973 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6974 if (interface_name
!= NULL
) {
6975 CFStringRef label_fmt
;
6977 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6978 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6979 CFSTR("Network Connection (%@)"),
6981 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6982 CFRelease(label_fmt
);
6984 label
= CFBundleCopyLocalizedString(bundle
,
6985 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6986 CFSTR("Network Connection"),
6990 // "802.1X Password" --> keychain "Kind"
6991 description
= CFBundleCopyLocalizedString(bundle
,
6992 CFSTR("KEYCHAIN_KIND_EAPOL"),
6993 CFSTR("802.1X Password"),
6998 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
7000 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
7001 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
7006 CFMutableDictionaryRef newConfig
= NULL
;
7008 if (config
!= NULL
) {
7009 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7011 newConfig
= CFDictionaryCreateMutable(NULL
,
7013 &kCFTypeDictionaryKeyCallBacks
,
7014 &kCFTypeDictionaryValueCallBacks
);
7016 CFDictionarySetValue(newConfig
,
7017 kEAPClientPropUserPasswordKeychainItemID
,
7019 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
7022 CFRelease(newConfig
);
7025 CFRelease(unique_id
);
7026 if (label
!= NULL
) CFRelease(label
);
7027 if (description
!= NULL
) CFRelease(description
);
7031 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
7032 SCNetworkServiceRef service
= NULL
;
7033 CFStringRef xauth_id
;
7035 // get configuration
7036 config
= SCNetworkInterfaceGetConfiguration(interface
);
7039 xauth_id
= copyXAuthID(config
, serviceID
);
7041 // get "Account", "Name", "Kind"
7042 if (config
!= NULL
) {
7043 // auth name --> keychain "Account"
7044 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
7046 // IPSec [user defined] "name" --> keychain "Name"
7047 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
7050 if (label
== NULL
) {
7051 // service name --> keychain "Name"
7052 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
7057 label
= SCNetworkServiceGetName(service
);
7058 if (label
== NULL
) {
7059 // interface name --> keychain "Name"
7060 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
7064 if (bundle
!= NULL
) {
7065 // "IPSec XAuth Password" --> keychain "Kind"
7066 description
= CFBundleCopyLocalizedString(bundle
,
7067 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
7068 CFSTR("IPSec XAuth Password"),
7073 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
7075 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
7076 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
7081 CFMutableDictionaryRef newConfig
;
7083 if (config
!= NULL
) {
7084 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7086 newConfig
= CFDictionaryCreateMutable(NULL
,
7088 &kCFTypeDictionaryKeyCallBacks
,
7089 &kCFTypeDictionaryValueCallBacks
);
7091 CFDictionarySetValue(newConfig
,
7092 kSCPropNetIPSecXAuthPassword
,
7094 CFDictionarySetValue(newConfig
,
7095 kSCPropNetIPSecXAuthPasswordEncryption
,
7096 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
7097 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
7098 CFRelease(newConfig
);
7101 CFRelease(xauth_id
);
7102 if (description
!= NULL
) CFRelease(description
);
7103 if (service
!= NULL
) CFRelease(service
);
7107 case kSCNetworkInterfacePasswordTypeVPN
: {
7108 SCNetworkServiceRef service
= NULL
;
7111 // get configuration
7112 config
= SCNetworkInterfaceGetConfiguration(interface
);
7115 vpn_id
= getPasswordID(config
, serviceID
);
7117 // get "Account", "Name", "Kind"
7118 if (config
!= NULL
) {
7119 // auth name --> keychain "Account"
7120 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
7122 // VPN [user defined] "name" --> keychain "Name"
7123 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
7126 if (label
== NULL
) {
7127 // service name --> keychain "Name"
7128 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
7133 label
= SCNetworkServiceGetName(service
);
7134 if (label
== NULL
) {
7135 // interface name --> keychain "Name"
7136 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
7140 if (bundle
!= NULL
) {
7141 // "VPN Password" --> keychain "Kind"
7142 description
= CFBundleCopyLocalizedString(bundle
,
7143 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
7144 CFSTR("VPN Password"),
7149 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
7151 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
7152 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
7157 CFMutableDictionaryRef newConfig
;
7159 if (config
!= NULL
) {
7160 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7162 newConfig
= CFDictionaryCreateMutable(NULL
,
7164 &kCFTypeDictionaryKeyCallBacks
,
7165 &kCFTypeDictionaryValueCallBacks
);
7167 CFDictionarySetValue(newConfig
,
7168 kSCPropNetVPNAuthPassword
,
7170 CFDictionarySetValue(newConfig
,
7171 kSCPropNetVPNAuthPasswordEncryption
,
7172 kSCValNetVPNAuthPasswordEncryptionKeychain
);
7173 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
7174 CFRelease(newConfig
);
7177 if (description
!= NULL
) CFRelease(description
);
7178 if (service
!= NULL
) CFRelease(service
);
7183 _SCErrorSet(kSCStatusInvalidArgument
);
7191 #pragma mark SCNetworkInterface [Advisory] SPIs
7192 #if TARGET_OS_SIMULATOR
7194 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7195 SCNetworkInterfaceAdvisory advisory
,
7198 #pragma unused(interface)
7199 #pragma unused(advisory)
7200 #pragma unused(reason)
7205 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7207 #pragma unused(interface)
7212 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7214 #pragma unused(interface)
7218 #else /* TARGET_OS_SIMULATOR */
7220 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7221 SCNetworkInterfaceAdvisory advisory
,
7224 IPMonitorControlRef control
;
7225 SCNetworkInterfacePrivateRef interfacePrivate
=
7226 (SCNetworkInterfacePrivateRef
)interface
;
7229 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7230 if (ifName
== NULL
) {
7231 _SCErrorSet(kSCStatusInvalidArgument
);
7234 control
= interfacePrivate
->IPMonitorControl
;
7235 if (control
== NULL
) {
7236 control
= IPMonitorControlCreate();
7237 if (control
== NULL
) {
7238 _SCErrorSet(kSCStatusFailed
);
7241 interfacePrivate
->IPMonitorControl
= control
;
7243 return IPMonitorControlSetInterfaceAdvisory(control
,
7250 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7252 IPMonitorControlRef control
;
7253 SCNetworkInterfacePrivateRef interfacePrivate
=
7254 (SCNetworkInterfacePrivateRef
)interface
;
7257 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7258 if (ifName
== NULL
) {
7259 _SCErrorSet(kSCStatusInvalidArgument
);
7262 control
= interfacePrivate
->IPMonitorControl
;
7263 if (control
== NULL
) {
7264 control
= IPMonitorControlCreate();
7265 if (control
== NULL
) {
7266 _SCErrorSet(kSCStatusFailed
);
7269 interfacePrivate
->IPMonitorControl
= control
;
7271 return IPMonitorControlInterfaceAdvisoryIsSet(control
, ifName
);
7275 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7279 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7280 if (ifName
== NULL
) {
7281 _SCErrorSet(kSCStatusInvalidArgument
);
7284 return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName
);
7286 #endif /* TARGET_OS_SIMULATOR */
7289 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
7293 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
7295 CFMutableDictionaryRef info
;
7296 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7299 if (interface
== NULL
) {
7303 info
= CFDictionaryCreateMutable(NULL
,
7305 &kCFTypeDictionaryKeyCallBacks
,
7306 &kCFTypeDictionaryValueCallBacks
);
7308 // add non-localized interface name
7309 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
7311 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
7315 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
7316 #if !TARGET_OS_SIMULATOR
7317 if (interfacePrivate
->usb
.name
!= NULL
) {
7318 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
7320 if (interfacePrivate
->usb
.vid
!= NULL
) {
7321 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
7323 if (interfacePrivate
->usb
.pid
!= NULL
) {
7324 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
7326 #endif // !TARGET_OS_SIMULATOR
7329 if (CFDictionaryGetCount(info
) == 0) {
7330 // do not return an empty dictionary
7339 SCNetworkInterfaceRef
7340 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7342 SCNetworkInterfaceRef interface
= NULL
;
7344 /* initialize runtime */
7345 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7347 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7348 interface
= createInterface(if_obj
,
7349 processNetworkInterface
,
7350 kSCNetworkInterfaceHiddenInterfaceKey
,
7352 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7353 interface
= createInterface(if_obj
,
7354 processSerialInterface
,
7355 kSCNetworkInterfaceHiddenPortKey
,
7364 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7366 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7368 return interfacePrivate
->configurationAction
;
7373 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7375 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7377 return interfacePrivate
->address
;
7382 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7384 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7386 return interfacePrivate
->prefix
;
7391 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7393 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7395 return interfacePrivate
->type
;
7400 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7402 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7404 return interfacePrivate
->unit
;
7409 update_ift_family(SCNetworkInterfaceRef interface
)
7411 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7413 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7415 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7416 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7419 memset(&ifr
, 0, sizeof(ifr
));
7420 if ((bsdName
!= NULL
) &&
7421 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7424 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7426 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7427 ifr
.ifr_type
.ift_family
= 0;
7428 ifr
.ifr_type
.ift_subfamily
= 0;
7434 interfacePrivate
->family
= CFNumberCreate(NULL
,
7435 kCFNumberSInt32Type
,
7436 &ifr
.ifr_type
.ift_family
);
7437 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7438 kCFNumberSInt32Type
,
7439 &ifr
.ifr_type
.ift_subfamily
);
7445 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7447 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7449 // note: family not in IORegistry, fetch with ioctl()
7451 if (interfacePrivate
->family
== NULL
) {
7452 update_ift_family(interface
);
7455 return interfacePrivate
->family
;
7460 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7462 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7464 // note: subfamily not in IORegistry, fetch with ioctl()
7466 if (interfacePrivate
->subfamily
== NULL
) {
7467 update_ift_family(interface
);
7470 return interfacePrivate
->subfamily
;
7475 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7477 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7479 return interfacePrivate
->path
;
7484 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7486 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7488 return interfacePrivate
->entryID
;
7494 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7496 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7498 return interfacePrivate
->active
;
7503 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7505 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7507 return interfacePrivate
->builtin
;
7512 _SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface
)
7514 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7516 return interfacePrivate
->trustRequired
;
7521 #pragma mark SCNetworkInterface SPIs
7526 SCNetworkInterfaceRef
7527 _SCNetworkInterfaceCopyBTPANInterface(void)
7529 CFDictionaryRef dict
;
7530 SCNetworkInterfaceRef interface
= NULL
;
7533 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7534 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7538 CFStringRef if_name
;
7539 SCNetworkInterfacePrivateRef interfacePrivate
;
7541 if (isA_CFDictionary(dict
) &&
7542 CFDictionaryGetValueIfPresent(dict
,
7543 kInterfaceNamerKey_BT_PAN_Name
,
7544 (const void **)&if_name
) &&
7545 isA_CFString(if_name
)) {
7546 CFMutableDictionaryRef entity
;
7548 entity
= CFDictionaryCreateMutable(NULL
,
7550 &kCFTypeDictionaryKeyCallBacks
,
7551 &kCFTypeDictionaryValueCallBacks
);
7552 CFDictionarySetValue(entity
,
7553 kSCPropNetInterfaceType
,
7554 kSCValNetInterfaceTypeEthernet
);
7555 CFDictionarySetValue(entity
,
7556 kSCPropNetInterfaceDeviceName
,
7558 CFDictionarySetValue(entity
,
7559 kSCPropUserDefinedName
,
7560 CFSTR(BT_PAN_NAME
));
7561 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7565 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7567 if ((interfacePrivate
!= NULL
) &&
7568 (interfacePrivate
->address
== NULL
) &&
7569 CFDictionaryGetValueIfPresent(dict
,
7570 kInterfaceNamerKey_BT_PAN_Mac
,
7571 (const void **)&addr
) &&
7573 interfacePrivate
->address
= CFRetain(addr
);
7581 #endif // TARGET_OS_OSX
7585 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7587 io_registry_entry_t device
;
7588 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7589 CFStringRef device_path
= NULL
;
7590 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7592 CFStringRef match_keys
[2];
7593 CFTypeRef match_vals
[2];
7594 CFDictionaryRef match_dict
;
7595 CFDictionaryRef matching
;
7597 if (interfacePrivate
->entity_device
== NULL
) {
7601 if (interfacePrivate
->entity_device_unique
== NULL
) {
7605 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7606 match_vals
[0] = interfacePrivate
->entity_device
;
7607 match_dict
= CFDictionaryCreate(NULL
,
7608 (const void **)match_keys
,
7609 (const void **)match_vals
,
7611 &kCFTypeDictionaryKeyCallBacks
,
7612 &kCFTypeDictionaryValueCallBacks
);
7614 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7615 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7616 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7617 match_vals
[1] = match_dict
;
7618 matching
= CFDictionaryCreate(NULL
,
7619 (const void **)match_keys
,
7620 (const void **)match_vals
,
7621 sizeof(match_keys
)/sizeof(match_keys
[0]),
7622 &kCFTypeDictionaryKeyCallBacks
,
7623 &kCFTypeDictionaryValueCallBacks
);
7624 CFRelease(match_dict
);
7626 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7627 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7628 if (kr
!= kIOReturnSuccess
) {
7629 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7633 while ((device_path
== NULL
) &&
7634 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7635 CFDictionaryRef overrides
;
7637 overrides
= IORegistryEntrySearchCFProperty(device
,
7639 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7641 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7642 if (overrides
!= NULL
) {
7643 CFDictionaryRef modemOverrides
;
7645 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7646 if (modemOverrides
!= NULL
) {
7647 CFRetain(modemOverrides
);
7649 CFRelease(overrides
);
7650 overrides
= modemOverrides
;
7652 if (overrides
== NULL
) {
7653 overrides
= IORegistryEntrySearchCFProperty(device
,
7655 CFSTR("DeviceModemOverrides"),
7657 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7659 if (overrides
!= NULL
) {
7660 if (isA_CFDictionary(overrides
)) {
7661 CFStringRef matchIdentifier
;
7663 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7664 if (isA_CFString(matchIdentifier
) &&
7665 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7666 device_path
= IORegistryEntryCreateCFProperty(device
,
7667 CFSTR(kIOTTYDeviceKey
),
7672 CFRelease(overrides
);
7674 IOObjectRelease(device
);
7677 IOObjectRelease(device_iterator
);
7681 if (device_path
== NULL
) {
7682 // if we haven't found an exact match to our UniqueIdentifier
7683 // so we simply return the base name.
7684 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7685 if (device_path
!= NULL
) {
7686 CFRetain(device_path
);
7698 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7700 #if TARGET_OS_SIMULATOR
7701 #pragma unused(interface)
7702 #else // TARGET_OS_SIMULATOR
7703 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7705 if (!_SCNetworkInterfaceIsHiddenConfiguration(interface
)) {
7706 // if not HiddenConfiguration
7710 if (_SCNetworkInterfaceIsBuiltin(interface
)) {
7715 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7718 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7719 (vid
== kIOUSBAppleVendorID
)) {
7720 // if Apple interface
7725 if (_SCNetworkInterfaceIsCarPlay(interface
)) {
7727 if ((interfacePrivate
->overrides
!= NULL
) &&
7728 (CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) ||
7729 CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7730 // and overrides are present
7734 #endif // TARGET_OS_SIMULATOR
7741 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7743 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7745 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7750 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7752 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7754 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7759 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7761 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7763 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7768 _SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface
)
7770 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7772 return (interfacePrivate
->sort_order
== kSortCarPlay
);
7777 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7779 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7781 return interfacePrivate
->hiddenConfiguration
;
7786 _SCNetworkInterfaceIsHiddenInterface(SCNetworkInterfaceRef interface
)
7788 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7790 return interfacePrivate
->hiddenInterface
;
7795 _SCNetworkInterfaceIsQoSMarkingProfileInstalled(SCNetworkInterfaceRef interface
)
7797 CFStringRef bsdName
;
7799 Boolean isInstalled
= FALSE
;
7800 CFDictionaryRef profile
;
7802 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7803 if (bsdName
== NULL
) {
7807 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
7808 kSCDynamicStoreDomainState
,
7810 kSCEntNetQoSMarkingPolicy
);
7811 profile
= SCDynamicStoreCopyValue(NULL
, key
);
7813 if (profile
!= NULL
) {
7823 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7825 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7827 return (interfacePrivate
->sort_order
== kSortTethered
);
7832 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7834 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7835 CFStringRef interfaceType
;
7837 if (!isA_SCNetworkInterface(interface
)) {
7841 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7842 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7847 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7848 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7850 // if an empty bridge
7854 for (i
= 0; i
< n
; i
++) {
7855 SCNetworkInterfaceRef member
;
7856 SCNetworkInterfacePrivateRef memberPrivate
;
7858 member
= CFArrayGetValueAtIndex(members
, i
);
7859 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7860 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7865 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7869 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7877 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7879 CFDictionaryRef policy
;
7881 if (!isA_SCNetworkInterface(interface
)) {
7882 _SCErrorSet(kSCStatusInvalidArgument
);
7886 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7887 if (policy
== NULL
) {
7888 _SCErrorSet(kSCStatusOK
);
7895 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7899 if (!isA_SCNetworkInterface(interface
)) {
7900 _SCErrorSet(kSCStatusInvalidArgument
);
7904 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7906 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7908 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7916 #pragma mark SCNetworkInterface [internal] SPIs
7920 SCNetworkInterfacePrivateRef
7921 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7922 SCNetworkInterfaceRef interface
,
7923 SCPreferencesRef prefs
,
7924 CFStringRef serviceID
)
7926 #pragma unused(allocator)
7927 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7928 SCNetworkInterfacePrivateRef newPrivate
;
7930 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7931 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7933 if (interface
== kSCNetworkInterfaceIPv4
) {
7934 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7937 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7938 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7939 if (oldPrivate
->interface
!= NULL
) {
7940 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7941 oldPrivate
->interface
, // interface
7942 prefs
, // [new] prefs
7943 serviceID
); // [new] serviceID
7945 if (oldPrivate
->name
!= NULL
) {
7946 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7948 if (oldPrivate
->prefix
!= NULL
) {
7949 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7951 if (oldPrivate
->localized_name
!= NULL
) {
7952 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7954 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7955 if (oldPrivate
->localized_arg1
!= NULL
) {
7956 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7958 if (oldPrivate
->localized_arg2
!= NULL
) {
7959 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7961 if (oldPrivate
->unsaved
!= NULL
) {
7962 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7964 if (oldPrivate
->entity_device
!= NULL
) {
7965 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7967 if (oldPrivate
->entity_device_unique
!= NULL
) {
7968 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7970 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7971 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7972 if (oldPrivate
->supported_interface_types
!= NULL
) {
7973 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7975 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7976 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7978 if (oldPrivate
->address
!= NULL
) {
7979 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7981 newPrivate
->builtin
= oldPrivate
->builtin
;
7982 if (oldPrivate
->configurationAction
!= NULL
) {
7983 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7985 newPrivate
->hiddenConfiguration
= oldPrivate
->hiddenConfiguration
;
7986 newPrivate
->hiddenInterface
= oldPrivate
->hiddenInterface
;
7987 #if TARGET_OS_IPHONE
7988 newPrivate
->trustRequired
= oldPrivate
->trustRequired
;
7989 #endif // TARGET_OS_IPHONE
7990 if (oldPrivate
->location
!= NULL
) {
7991 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7993 if (oldPrivate
->path
!= NULL
) {
7994 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7996 newPrivate
->entryID
= oldPrivate
->entryID
;
7997 if (oldPrivate
->overrides
!= NULL
) {
7998 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
8000 if (oldPrivate
->type
!= NULL
) {
8001 newPrivate
->type
= CFRetain(oldPrivate
->type
);
8003 if (oldPrivate
->unit
!= NULL
) {
8004 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
8006 if (oldPrivate
->family
!= NULL
) {
8007 newPrivate
->family
= CFRetain(oldPrivate
->family
);
8009 if (oldPrivate
->subfamily
!= NULL
) {
8010 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
8012 if (oldPrivate
->usb
.name
!= NULL
) {
8013 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
8015 if (oldPrivate
->usb
.vid
!= NULL
) {
8016 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
8018 if (oldPrivate
->usb
.pid
!= NULL
) {
8019 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
8021 newPrivate
->sort_order
= oldPrivate
->sort_order
;
8023 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
8024 if (oldPrivate
->bond
.interfaces
!= NULL
) {
8025 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
8027 if (oldPrivate
->bond
.mode
!= NULL
) {
8028 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
8030 if (oldPrivate
->bond
.options
!= NULL
) {
8031 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
8034 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
8035 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
8036 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
8038 if (oldPrivate
->bridge
.options
!= NULL
) {
8039 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
8042 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
8043 if (oldPrivate
->vlan
.interface
!= NULL
) {
8044 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
8046 if (oldPrivate
->vlan
.tag
!= NULL
) {
8047 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
8049 if (oldPrivate
->vlan
.options
!= NULL
) {
8050 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
8059 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
8061 CFMutableArrayRef configs
;
8063 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8065 while (interface
!= NULL
) {
8066 CFStringRef defaultType
;
8067 CFMutableDictionaryRef interfaceConfiguration
;
8069 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
8071 &kCFTypeDictionaryKeyCallBacks
,
8072 &kCFTypeDictionaryValueCallBacks
);
8074 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
8075 if (defaultType
!= NULL
) {
8076 CFDictionaryRef config
;
8077 CFArrayRef extendedTypes
;
8080 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
8082 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
8084 if (config
== NULL
) {
8085 config
= (CFDictionaryRef
)kCFNull
;
8087 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
8089 extendedTypes
= extendedConfigurationTypes(interface
);
8090 if (extendedTypes
!= NULL
) {
8094 n
= CFArrayGetCount(extendedTypes
);
8095 for (i
= 0; i
< n
; i
++) {
8096 CFStringRef extendedType
;
8098 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
8099 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
8100 if (config
== NULL
) {
8101 config
= (CFDictionaryRef
)kCFNull
;
8103 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
8106 CFRelease(extendedTypes
);
8110 CFArrayAppendValue(configs
, interfaceConfiguration
);
8111 CFRelease(interfaceConfiguration
);
8113 interface
= SCNetworkInterfaceGetInterface(interface
);
8120 __private_extern__ Boolean
8121 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
8123 CFArrayRef interfaces
;
8124 Boolean match
= FALSE
;
8125 CFMutableSetRef members
;
8127 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
8129 #if !TARGET_OS_IPHONE
8130 // add Bond [member] interfaces
8131 interfaces
= SCBondInterfaceCopyAll(prefs
);
8132 if (interfaces
!= NULL
) {
8133 __SCBondInterfaceListCollectMembers(interfaces
, members
);
8134 CFRelease(interfaces
);
8136 #endif // !TARGET_OS_IPHONE
8138 // add Bridge [member] interfaces
8139 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
8140 if (interfaces
!= NULL
) {
8141 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
8142 CFRelease(interfaces
);
8145 if (CFSetGetCount(members
) == 0) {
8149 while (interface
!= NULL
) {
8150 match
= CFSetContainsValue(members
, interface
);
8152 // if the interface is a member of an
8153 // Ethernet Bond or Bridge
8157 interface
= SCNetworkInterfaceGetInterface(interface
);
8169 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
,
8170 SCNetworkInterfaceRef interface
,
8175 for (i
= 0; interface
!= NULL
; i
++) {
8176 CFStringRef defaultType
;
8177 CFDictionaryRef interfaceConfiguration
;
8180 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
8182 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
8183 if (defaultType
!= NULL
) {
8184 CFDictionaryRef config
;
8185 CFArrayRef extendedTypes
;
8187 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
8189 if (config
== (CFDictionaryRef
)kCFNull
) {
8193 // if service is not associated with the set
8194 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
8196 // apply default configuration to this set
8197 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
8200 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8203 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8205 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8210 extendedTypes
= extendedConfigurationTypes(interface
);
8211 if (extendedTypes
!= NULL
) {
8215 n
= CFArrayGetCount(extendedTypes
);
8216 for (j
= 0; j
< n
; j
++) {
8217 CFStringRef extendedType
;
8219 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
8220 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
8222 if (config
== (CFDictionaryRef
)kCFNull
) {
8225 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
8227 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8230 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8232 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8238 CFRelease(extendedTypes
);
8242 interface
= SCNetworkInterfaceGetInterface(interface
);
8249 SCNetworkInterfaceRef
8250 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
8252 SCNetworkInterfaceRef interface
;
8254 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
8255 if (interface
== NULL
) {
8259 if (store
!= NULL
) {
8260 SCNetworkInterfacePrivateRef interfacePrivate
=
8261 (SCNetworkInterfacePrivateRef
)interface
;
8264 interfacePrivate
->store
= store
;
8271 #if !TARGET_OS_SIMULATOR
8272 SCNetworkServicePrimaryRank
8273 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8275 IPMonitorControlRef control
;
8276 SCNetworkInterfacePrivateRef interfacePrivate
=
8277 (SCNetworkInterfacePrivateRef
)interface
;
8278 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
8280 control
= interfacePrivate
->IPMonitorControl
;
8281 if (control
!= NULL
) {
8284 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8285 if (ifName
!= NULL
) {
8286 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
8290 _SCErrorSet(kSCStatusInvalidArgument
);
8297 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8298 SCNetworkServicePrimaryRank newRank
)
8300 IPMonitorControlRef control
;
8301 SCNetworkInterfacePrivateRef interfacePrivate
=
8302 (SCNetworkInterfacePrivateRef
)interface
;
8305 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8306 if (ifName
== NULL
) {
8307 _SCErrorSet(kSCStatusInvalidArgument
);
8310 control
= interfacePrivate
->IPMonitorControl
;
8311 if (control
== NULL
) {
8312 control
= IPMonitorControlCreate();
8313 if (control
== NULL
) {
8314 _SCErrorSet(kSCStatusFailed
);
8317 interfacePrivate
->IPMonitorControl
= control
;
8319 return IPMonitorControlSetInterfacePrimaryRank(control
,
8325 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8327 Boolean disable_until_needed
= FALSE
;
8328 CFNumberRef disable_prop
= NULL
;
8329 CFIndex interfaceIndex
;
8330 SCNetworkInterfacePrivateRef interfacePrivate
8331 = (SCNetworkInterfacePrivateRef
)interface
;
8332 CFArrayRef path_list
;
8334 if (interfacePrivate
->prefs
== NULL
) {
8335 _SCErrorSet(kSCStatusInvalidArgument
);
8338 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8339 if (interfaceIndex
== kCFNotFound
) {
8340 _SCErrorSet(kSCStatusInvalidArgument
);
8343 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8344 if (path_list
!= NULL
) {
8345 CFDictionaryRef config
;
8346 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
8348 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
8349 CFRelease(path_list
);
8350 if (config
!= NULL
) {
8353 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
8354 disable_prop
= isA_CFNumber(disable_prop
);
8355 if (disable_prop
!= NULL
) {
8356 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
8357 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
8360 /* invalid property, ignore it */
8361 disable_prop
= NULL
;
8366 if (disable_prop
== NULL
) {
8367 disable_until_needed
8368 = _SCNetworkInterfaceIsTethered(interface
);
8370 _SCErrorSet(kSCStatusOK
);
8371 return (disable_until_needed
);
8375 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8379 CFIndex interfaceIndex
;
8380 SCNetworkInterfacePrivateRef interfacePrivate
8381 = (SCNetworkInterfacePrivateRef
)interface
;
8383 CFArrayRef path_list
;
8385 if (interfacePrivate
->prefs
== NULL
) {
8386 _SCErrorSet(kSCStatusInvalidArgument
);
8389 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
8390 _SCErrorSet(kSCStatusInvalidArgument
);
8393 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8394 if (interfaceIndex
== kCFNotFound
) {
8395 _SCErrorSet(kSCStatusInvalidArgument
);
8398 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8399 if (path_list
== NULL
) {
8400 _SCErrorSet(kSCStatusInvalidArgument
);
8403 count
= CFArrayGetCount(path_list
);
8404 for (i
= 0; i
< count
; i
++) {
8405 CFDictionaryRef config
;
8406 CFMutableDictionaryRef new_config
;
8407 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
8409 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
8410 if (config
!= NULL
) {
8412 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
8415 = CFDictionaryCreateMutable(NULL
, 0,
8416 &kCFTypeDictionaryKeyCallBacks
,
8417 &kCFTypeDictionaryValueCallBacks
);
8419 if (disable
!= NULL
) {
8420 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
8422 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
8424 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
,
8426 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
8428 CFRelease(new_config
);
8433 CFRelease(path_list
);
8438 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8445 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8446 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8452 #else // !TARGET_OS_SIMULATOR
8454 SCNetworkServicePrimaryRank
8455 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8457 #pragma unused(interface)
8458 return (kSCNetworkServicePrimaryRankDefault
);
8462 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8463 SCNetworkServicePrimaryRank newRank
)
8465 #pragma unused(interface)
8466 #pragma unused(newRank)
8467 _SCErrorSet(kSCStatusInvalidArgument
);
8472 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8474 #pragma unused(interface)
8479 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8481 #pragma unused(interface)
8482 #pragma unused(disable)
8487 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8489 #pragma unused(interface)
8490 #pragma unused(disable)
8491 _SCErrorSet(kSCStatusInvalidArgument
);
8495 #endif // !TARGET_OS_SIMULATOR
8499 CFArrayRef
// SCNetworkInterfaceRef
8500 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs
)
8503 CFMutableArrayRef interfaceList
= NULL
;
8505 /* initialize runtime */
8506 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8508 if (ni_prefs
!= NULL
) {
8511 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8515 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8516 if (isA_CFArray(if_list
)) {
8517 CFIndex n
= CFArrayGetCount(if_list
);
8519 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8520 for (CFIndex i
= 0; i
< n
; i
++) {
8521 CFDictionaryRef dict
;
8523 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8524 if (isA_CFDictionary(dict
) != NULL
) {
8525 SCNetworkInterfaceRef interface
;
8527 interface
= __SCNetworkInterfaceCreateWithStorageEntity(dict
);
8528 if (interface
!= NULL
) {
8529 CFArrayAppendValue(interfaceList
, interface
);
8530 CFRelease(interface
);
8536 CFRelease(ni_prefs
);
8537 return interfaceList
;
8543 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef ni_prefs
, CFArrayRef interfacesToSave
)
8547 if (!isA_CFArray(interfacesToSave
)) {
8551 if (ni_prefs
!= NULL
) {
8554 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8558 ok
= SCPreferencesSetValue(ni_prefs
, INTERFACES
, interfacesToSave
);
8559 CFRelease(ni_prefs
);
8564 SCNetworkInterfaceRef
8565 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8567 #pragma unused(allocator)
8569 SCNetworkInterfaceRef interface
= NULL
;
8571 /* initialize runtime */
8572 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8574 if (ni_prefs
!= NULL
) {
8577 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8581 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8582 if (isA_CFArray(if_list
)) {
8583 CFIndex n
= CFArrayGetCount(if_list
);
8585 for (CFIndex i
= 0; i
< n
; i
++) {
8586 CFDictionaryRef dict
;
8587 CFStringRef tmp_bsdName
;
8589 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8590 if (!isA_CFDictionary(dict
)) {
8594 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8595 if (!isA_CFString(tmp_bsdName
)) {
8599 if (CFEqual(bsdName
, tmp_bsdName
)) {
8600 interface
= __SCNetworkInterfaceCreateWithStorageEntity(dict
);
8606 CFRelease(ni_prefs
);
8612 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8614 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8615 CFStringRef bsdName
= NULL
;
8616 SCNetworkInterfaceRef interface
= NULL
;
8619 count
= CFArrayGetCount(interfaces
);
8621 SC_log(LOG_INFO
, "No interfaces");
8625 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8627 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8628 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8630 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8631 if (!isA_CFString(bsdName
)) {
8632 SC_log(LOG_DEBUG
, "No BSD name");
8635 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8638 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8639 CFRelease(mappingBSDToInterface
);
8640 mappingBSDToInterface
= NULL
;
8641 SC_log(LOG_INFO
, "No mappings");
8644 return mappingBSDToInterface
;
8647 __private_extern__ Boolean
8648 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8650 CFStringRef intfSubtype
;
8652 if (entity
== NULL
) {
8656 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8657 #pragma GCC diagnostic push
8658 #pragma GCC diagnostic ignored "-Wdeprecated"
8659 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8662 #pragma GCC diagnostic pop