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 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
257 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
258 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
259 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
260 #pragma GCC diagnostic push
261 #pragma GCC diagnostic ignored "-Wdeprecated"
262 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
263 #pragma GCC diagnostic pop
264 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
265 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
266 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
267 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
268 // ===================================== =================== ========== =============== ======================================= =========================================
269 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
270 // ===================================== =================== ========== =============== ======================================= =========================================
271 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
275 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
276 static CFBundleRef bundle
= NULL
;
279 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
282 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
284 "SCNetworkInterface", // className
287 __SCNetworkInterfaceDeallocate
, // dealloc
288 __SCNetworkInterfaceEqual
, // equal
289 __SCNetworkInterfaceHash
, // hash
290 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
291 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
295 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
296 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
297 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
300 static mach_port_t masterPort
= MACH_PORT_NULL
;
303 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
305 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
309 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
311 CFAllocatorRef allocator
= CFGetAllocator(cf
);
312 CFMutableStringRef result
;
313 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
315 result
= CFStringCreateMutable(allocator
, 0);
316 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
317 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
318 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
319 if (interfacePrivate
->entity_device_unique
!= NULL
) {
320 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
322 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
323 if (interfacePrivate
->entity_subtype
!= NULL
) {
324 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
326 if (interfacePrivate
->name
!= NULL
) {
327 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
329 if (interfacePrivate
->localized_name
!= NULL
) {
330 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
332 if (interfacePrivate
->localized_key
!= NULL
) {
333 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
334 if (interfacePrivate
->localized_arg1
!= NULL
) {
335 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
337 if (interfacePrivate
->localized_arg2
!= NULL
) {
338 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
342 if (interfacePrivate
->address
!= NULL
) {
347 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
349 data
= CFDataGetBytePtr(interfacePrivate
->address
);
350 dataLen
= CFDataGetLength(interfacePrivate
->address
);
351 for (i
= 0; i
< dataLen
; i
++) {
352 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
357 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
358 if (interfacePrivate
->hidden
) {
359 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
362 if (interfacePrivate
->trustRequired
) {
363 CFStringAppendFormat(result
, NULL
, CFSTR(", trust required = TRUE"));
365 #endif // TARGET_OS_IPHONE
366 if (interfacePrivate
->location
!= NULL
) {
367 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
369 if (interfacePrivate
->path
!= NULL
) {
370 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
372 if (interfacePrivate
->entryID
!= 0) {
373 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
375 if (interfacePrivate
->type
!= NULL
) {
376 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
378 if (interfacePrivate
->unit
!= NULL
) {
379 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
381 if (interfacePrivate
->family
!= NULL
) {
382 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
384 if (interfacePrivate
->subfamily
!= NULL
) {
385 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
387 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
391 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
392 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
395 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
396 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
400 if (interfacePrivate
->usb
.name
!= NULL
) {
401 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
402 interfacePrivate
->usb
.name
);
405 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
409 if (interfacePrivate
->configurationAction
!= NULL
) {
410 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
412 if (interfacePrivate
->overrides
!= NULL
) {
415 str
= _SCCopyDescription(interfacePrivate
->overrides
, formatOptions
);
416 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %@"), str
);
419 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d (%s)"),
420 interfacePrivate
->sort_order
,
421 interfacePrivate
->sort_order
<= kSortUnknown
? sortOrderName
[interfacePrivate
->sort_order
] : "?");
422 if (interfacePrivate
->prefs
!= NULL
) {
423 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
425 if (interfacePrivate
->serviceID
!= NULL
) {
426 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
428 if (interfacePrivate
->interface
!= NULL
) {
429 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
431 if (interfacePrivate
->unsaved
!= NULL
) {
432 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
435 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
439 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
440 for (i
= 0; i
< n
; i
++) {
441 SCNetworkInterfaceRef member
;
443 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
444 CFStringAppendFormat(result
, NULL
,
446 (i
== 0) ? ", interfaces = " : ",",
447 SCNetworkInterfaceGetBSDName(member
));
450 if (interfacePrivate
->bond
.mode
!= NULL
) {
451 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
453 if (interfacePrivate
->bond
.options
!= NULL
) {
456 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
457 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
461 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
465 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
466 for (i
= 0; i
< n
; i
++) {
467 SCNetworkInterfaceRef member
;
469 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
470 CFStringAppendFormat(result
, NULL
,
472 (i
== 0) ? ", interfaces = " : ",",
473 SCNetworkInterfaceGetBSDName(member
));
476 if (interfacePrivate
->bridge
.options
!= NULL
) {
479 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
480 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
484 if (interfacePrivate
->vlan
.interface
!= NULL
) {
485 CFStringAppendFormat(result
, NULL
,
486 CFSTR(", interface = %@"),
487 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
489 if (interfacePrivate
->vlan
.tag
!= NULL
) {
490 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
492 if (interfacePrivate
->vlan
.options
!= NULL
) {
495 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
496 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
500 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
507 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
509 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
511 /* release resources */
513 if (interfacePrivate
->name
!= NULL
)
514 CFRelease(interfacePrivate
->name
);
516 if (interfacePrivate
->localized_name
!= NULL
)
517 CFRelease(interfacePrivate
->localized_name
);
519 if (interfacePrivate
->localized_arg1
!= NULL
)
520 CFRelease(interfacePrivate
->localized_arg1
);
522 if (interfacePrivate
->localized_arg2
!= NULL
)
523 CFRelease(interfacePrivate
->localized_arg2
);
525 if (interfacePrivate
->interface
!= NULL
)
526 CFRelease(interfacePrivate
->interface
);
528 if (interfacePrivate
->prefs
!= NULL
)
529 CFRelease(interfacePrivate
->prefs
);
531 if (interfacePrivate
->store
!= NULL
)
532 CFRelease(interfacePrivate
->store
);
534 if (interfacePrivate
->serviceID
!= NULL
)
535 CFRelease(interfacePrivate
->serviceID
);
537 if (interfacePrivate
->unsaved
!= NULL
)
538 CFRelease(interfacePrivate
->unsaved
);
540 if (interfacePrivate
->entity_device
!= NULL
)
541 CFRelease(interfacePrivate
->entity_device
);
543 if (interfacePrivate
->entity_device_unique
!= NULL
)
544 CFRelease(interfacePrivate
->entity_device_unique
);
546 if (interfacePrivate
->supported_interface_types
!= NULL
)
547 CFRelease(interfacePrivate
->supported_interface_types
);
549 if (interfacePrivate
->supported_protocol_types
!= NULL
)
550 CFRelease(interfacePrivate
->supported_protocol_types
);
552 if (interfacePrivate
->address
!= NULL
)
553 CFRelease(interfacePrivate
->address
);
555 if (interfacePrivate
->addressString
!= NULL
)
556 CFRelease(interfacePrivate
->addressString
);
558 if (interfacePrivate
->configurationAction
!= NULL
)
559 CFRelease(interfacePrivate
->configurationAction
);
561 if (interfacePrivate
->location
!= NULL
)
562 CFRelease(interfacePrivate
->location
);
564 if (interfacePrivate
->path
!= NULL
)
565 CFRelease(interfacePrivate
->path
);
567 if (interfacePrivate
->overrides
!= NULL
)
568 CFRelease(interfacePrivate
->overrides
);
570 if (interfacePrivate
->prefix
!= NULL
)
571 CFRelease(interfacePrivate
->prefix
);
573 if (interfacePrivate
->type
!= NULL
)
574 CFRelease(interfacePrivate
->type
);
576 if (interfacePrivate
->unit
!= NULL
)
577 CFRelease(interfacePrivate
->unit
);
579 if (interfacePrivate
->family
!= NULL
)
580 CFRelease(interfacePrivate
->family
);
582 if (interfacePrivate
->subfamily
!= NULL
)
583 CFRelease(interfacePrivate
->subfamily
);
585 if (interfacePrivate
->usb
.name
!= NULL
)
586 CFRelease(interfacePrivate
->usb
.name
);
588 if (interfacePrivate
->usb
.pid
!= NULL
)
589 CFRelease(interfacePrivate
->usb
.pid
);
591 if (interfacePrivate
->usb
.vid
!= NULL
)
592 CFRelease(interfacePrivate
->usb
.vid
);
594 if (interfacePrivate
->bond
.interfaces
!= NULL
)
595 CFRelease(interfacePrivate
->bond
.interfaces
);
597 if (interfacePrivate
->bond
.mode
!= NULL
)
598 CFRelease(interfacePrivate
->bond
.mode
);
600 if (interfacePrivate
->bond
.options
!= NULL
)
601 CFRelease(interfacePrivate
->bond
.options
);
603 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
604 CFRelease(interfacePrivate
->bridge
.interfaces
);
606 if (interfacePrivate
->bridge
.options
!= NULL
)
607 CFRelease(interfacePrivate
->bridge
.options
);
609 if (interfacePrivate
->vlan
.interface
!= NULL
)
610 CFRelease(interfacePrivate
->vlan
.interface
);
612 if (interfacePrivate
->vlan
.tag
!= NULL
)
613 CFRelease(interfacePrivate
->vlan
.tag
);
615 if (interfacePrivate
->vlan
.options
!= NULL
)
616 CFRelease(interfacePrivate
->vlan
.options
);
617 #if !TARGET_OS_SIMULATOR
618 if (interfacePrivate
->IPMonitorControl
!= NULL
)
619 CFRelease(interfacePrivate
->IPMonitorControl
);
620 #endif // !TARGET_OS_SIMULATOR
626 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
628 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
629 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
634 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
635 return FALSE
; // if not the same interface type
638 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
639 return FALSE
; // if not the same device
642 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
643 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
644 return FALSE
; // if not the same device unique identifier
646 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
650 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
651 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
652 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
653 return FALSE
; // if same device but not the same display name
657 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
658 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
659 return FALSE
; // if not the same interfaces
661 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
662 return FALSE
; // if not the same mode
666 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
667 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
668 return FALSE
; // if not the same interfaces
672 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
673 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
674 return FALSE
; // if not the same physical interface
676 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
677 return FALSE
; // if not the same tag
681 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
682 return FALSE
; // if not the same layering
690 __SCNetworkInterfaceHash(CFTypeRef cf
)
693 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
695 if (interfacePrivate
->entity_device
!= NULL
) {
696 if (interfacePrivate
->entity_device_unique
== NULL
) {
697 hash
= CFHash(interfacePrivate
->entity_device
);
701 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
702 interfacePrivate
->entity_device
,
703 interfacePrivate
->entity_device_unique
);
714 __SCNetworkInterfaceInitialize(void)
719 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
721 // initialize __kSCNetworkInterfaceIPv4
722 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
723 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
724 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
726 // initialize __kSCNetworkInterfaceLoopback
727 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
728 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
729 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
730 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
731 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
733 // get CFBundleRef for SystemConfiguration.framework
734 bundle
= _SC_CFBundleGet();
736 // get mach port used to communication with IOKit
737 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
738 if (kr
!= kIOReturnSuccess
) {
739 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
747 SCNetworkInterfacePrivateRef
748 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
749 SCNetworkInterfaceRef interface
,
750 SCPreferencesRef prefs
,
751 CFStringRef serviceID
)
753 SCNetworkInterfacePrivateRef interfacePrivate
;
756 /* initialize runtime */
757 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
759 /* allocate target */
760 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
761 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
762 __kSCNetworkInterfaceTypeID
,
765 if (interfacePrivate
== NULL
) {
769 /* initialize non-zero/NULL members */
770 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
771 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
772 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
773 interfacePrivate
->sort_order
= kSortUnknown
;
775 return interfacePrivate
;
781 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
785 struct if_msghdr
* ifm
;
786 char * if_name
= NULL
;
787 unsigned int if_index
;
789 Boolean vlanOK
= FALSE
;
791 // get the interface index
792 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
793 if (if_name
== NULL
) {
794 return FALSE
; // if conversion error
796 if_index
= if_nametoindex(if_name
);
798 goto done
; // if unknown interface
801 // get information for the specified interface
806 mib
[4] = NET_RT_IFLIST
;
807 mib
[5] = if_index
; /* ask for exactly one interface */
809 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
810 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
813 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
814 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
815 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
819 // check the link type and hwassist flags
820 // ALIGN: buf is aligned
821 ifm
= (struct if_msghdr
*)(void *)buf
;
822 switch (ifm
->ifm_type
) {
824 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
825 struct if_data
*if_data
= &ifm
->ifm_data
;
827 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
837 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
838 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
845 __SCCopyMacAddress(CFStringRef ifname
)
847 struct ifaddrs
*ifap
;
848 char ifname_c
[IFNAMSIZ
];
850 CFDataRef macAddress
= NULL
;
852 if(_SC_cfstring_to_cstring(ifname
,
855 kCFStringEncodingUTF8
) == NULL
) {
859 if (getifaddrs(&ifap
) == -1) {
861 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
865 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
866 struct sockaddr_dl
*sdl
;
868 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
872 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
873 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
874 if (sdl
->sdl_family
!= AF_LINK
) {
878 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
887 SCNetworkInterfacePrivateRef
888 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
891 SCNetworkInterfacePrivateRef interfacePrivate
;
893 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
894 if (interfacePrivate
== NULL
) {
898 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
899 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
900 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
901 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
902 interfacePrivate
->builtin
= TRUE
;
903 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
904 interfacePrivate
->sort_order
= kSortBond
;
906 interfacePrivate
->localized_key
= CFSTR("bond");
907 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
909 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
910 // interfacePrivate->bond.mode = NULL;
911 // interfacePrivate->bond.options = NULL;
913 return interfacePrivate
;
918 SCNetworkInterfacePrivateRef
919 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
920 CFStringRef bridge_if
)
922 SCNetworkInterfacePrivateRef interfacePrivate
;
924 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
925 if (interfacePrivate
== NULL
) {
929 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
930 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
931 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
932 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
933 interfacePrivate
->builtin
= TRUE
;
934 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
935 interfacePrivate
->sort_order
= kSortBridge
;
937 interfacePrivate
->localized_key
= CFSTR("bridge");
938 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
940 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
941 // interfacePrivate->bridge.options = NULL;
943 return interfacePrivate
;
948 SCNetworkInterfacePrivateRef
949 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
952 SCNetworkInterfacePrivateRef interfacePrivate
;
954 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
955 if (interfacePrivate
== NULL
) {
959 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
960 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
961 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
962 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
963 interfacePrivate
->builtin
= TRUE
;
964 interfacePrivate
->sort_order
= kSortVLAN
;
966 interfacePrivate
->localized_key
= CFSTR("vlan");
967 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
969 // interfacePrivate->vlan.interface = NULL;
970 // interfacePrivate->vlan.tag = NULL;
971 // interfacePrivate->vlan.options = NULL;
973 return interfacePrivate
;
978 #pragma mark Interface ordering
981 static CF_RETURNS_RETAINED CFArrayRef
982 split_path(CFStringRef path
)
984 CFArrayRef components
;
985 CFMutableStringRef nPath
;
987 // turn '@'s into '/'s
988 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
989 (void) CFStringFindAndReplace(nPath
,
992 CFRangeMake(0, CFStringGetLength(nPath
)),
995 // split path into components to be compared
996 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
1004 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
1006 #pragma unused(context)
1007 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
1008 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
1009 CFComparisonResult res
= kCFCompareEqualTo
;
1011 /* sort by interface type */
1012 if (dev1
->sort_order
!= dev2
->sort_order
) {
1013 if (dev1
->sort_order
< dev2
->sort_order
) {
1014 res
= kCFCompareLessThan
;
1016 res
= kCFCompareGreaterThan
;
1021 /* built-in interfaces sort first */
1022 if (dev1
->builtin
!= dev2
->builtin
) {
1023 if (dev1
->builtin
) {
1024 res
= kCFCompareLessThan
;
1026 res
= kCFCompareGreaterThan
;
1031 /* ... and then, sort built-in interfaces by "location" */
1032 if (dev1
->builtin
) {
1033 if (dev1
->location
!= dev2
->location
) {
1034 if (isA_CFString(dev1
->location
)) {
1035 if (isA_CFString(dev2
->location
)) {
1036 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1038 res
= kCFCompareLessThan
;
1041 res
= kCFCompareGreaterThan
;
1044 if (res
!= kCFCompareEqualTo
) {
1050 /* ... and, then sort by IOPathMatch */
1051 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1052 CFArrayRef elements1
;
1053 CFArrayRef elements2
;
1059 elements1
= split_path(dev1
->path
);
1060 n1
= CFArrayGetCount(elements1
);
1062 elements2
= split_path(dev2
->path
);
1063 n2
= CFArrayGetCount(elements2
);
1065 n
= (n1
<= n2
) ? n1
: n2
;
1066 for (i
= 0; i
< n
; i
++) {
1075 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1076 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1078 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1080 q1
= strtoq(str
, &end
, 16);
1081 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1082 CFAllocatorDeallocate(NULL
, str
);
1085 // if e1 is a valid numeric string
1086 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1088 q2
= strtoq(str
, &end
, 16);
1089 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1090 CFAllocatorDeallocate(NULL
, str
);
1093 // if e2 is also a valid numeric string
1096 res
= kCFCompareEqualTo
;
1098 } else if (q1
< q2
) {
1099 res
= kCFCompareLessThan
;
1101 res
= kCFCompareGreaterThan
;
1107 res
= CFStringCompare(e1
, e2
, 0);
1108 if (res
!= kCFCompareEqualTo
) {
1113 if (res
== kCFCompareEqualTo
) {
1115 res
= kCFCompareLessThan
;
1116 } else if (n1
< n2
) {
1117 res
= kCFCompareGreaterThan
;
1121 CFRelease(elements1
);
1122 CFRelease(elements2
);
1124 if (res
!= kCFCompareEqualTo
) {
1129 /* ... and, then sort by BSD interface name */
1130 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1131 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1132 if (res
!= kCFCompareEqualTo
) {
1137 /* ... and lastly, sort by BSD interface unique identifier */
1138 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1139 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1140 // if (res != kCFCompareEqualTo) {
1150 sort_interfaces(CFMutableArrayRef all_interfaces
)
1154 n
= CFArrayGetCount(all_interfaces
);
1159 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1166 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1168 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1170 return interfacePrivate
->sort_order
;
1175 #pragma mark Interface details
1179 IOCopyCFStringValue(CFTypeRef ioVal
)
1181 if (isA_CFString(ioVal
)) {
1182 return CFStringCreateCopy(NULL
, ioVal
);
1185 if (isA_CFData(ioVal
)) {
1186 return CFStringCreateWithCString(NULL
,
1187 (const char *)CFDataGetBytePtr(ioVal
),
1188 kCFStringEncodingUTF8
);
1196 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1198 CFStringRef if_bsdName
;
1199 CFStringRef if_prefix
;
1200 CFNumberRef if_unit
;
1202 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1203 if (if_bsdName
!= NULL
) {
1204 return IOCopyCFStringValue(if_bsdName
);
1207 // no BSD name, get interface prefix and unit
1208 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1209 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1210 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1211 // if both prefix and unit available, construct BSD name
1212 if_bsdName
= CFStringCreateWithFormat(NULL
,
1224 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1228 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1229 return IOCopyCFStringValue(ioVal
);
1234 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1236 Boolean match
= FALSE
;
1237 CFIndex prefixLen
= CFStringGetLength(prefix
);
1238 CFStringRef str
= NULL
;
1240 if (!isA_CFString(ioVal
)) {
1241 if (isA_CFData(ioVal
)) {
1242 str
= CFStringCreateWithCStringNoCopy(NULL
,
1243 (const char *)CFDataGetBytePtr(ioVal
),
1244 kCFStringEncodingUTF8
,
1252 if ((ioVal
!= NULL
) &&
1253 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1254 (CFStringCompareWithOptions(ioVal
,
1256 CFRangeMake(0, prefixLen
),
1257 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1261 if (str
!= NULL
) CFRelease(str
);
1266 static const struct {
1267 const CFStringRef name
;
1268 const CFStringRef slot
;
1269 } slot_mappings
[] = {
1271 { CFSTR("A1") , CFSTR("1") },
1272 { CFSTR("B1") , CFSTR("2") },
1273 { CFSTR("C1") , CFSTR("3") },
1275 // Blue&White G3, Yikes G4
1276 { CFSTR("J12"), CFSTR("1") },
1277 { CFSTR("J11"), CFSTR("2") },
1278 { CFSTR("J10"), CFSTR("3") },
1279 { CFSTR("J9"), CFSTR("4") },
1282 { CFSTR("A") , CFSTR("1") },
1283 { CFSTR("B") , CFSTR("2") },
1284 { CFSTR("C") , CFSTR("3") },
1285 { CFSTR("D") , CFSTR("4") },
1287 // Digital Audio G4 (and later models)
1288 { CFSTR("1") , CFSTR("1") },
1289 { CFSTR("2") , CFSTR("2") },
1290 { CFSTR("3") , CFSTR("3") },
1291 { CFSTR("4") , CFSTR("4") },
1292 { CFSTR("5") , CFSTR("5") }
1296 static const CFStringRef slot_prefixes
[] = {
1297 CFSTR("thunderbolt slot "),
1303 static CF_RETURNS_RETAINED CFStringRef
1304 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1307 io_registry_entry_t parent
;
1308 CFMutableStringRef slot
;
1309 CFTypeRef slot_name
;
1312 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1314 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1315 if (slot_name
!= NULL
) {
1316 slot
= CFStringCreateMutable(NULL
, 0);
1317 if (isA_CFString(slot_name
)) {
1318 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1319 CFStringAppend(slot
, slot_name
);
1320 } else if (isA_CFData(slot_name
)) {
1321 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1322 CFStringAppendCString(slot
,
1323 (const char *)CFDataGetBytePtr(slot_name
),
1324 kCFStringEncodingUTF8
);
1327 for (size_t i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1330 len
= CFStringGetLength(slot_prefixes
[i
]);
1331 if (CFStringGetLength(slot
) > len
) {
1332 (void) CFStringFindAndReplace(slot
,
1335 CFRangeMake(0, len
),
1336 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1340 for (size_t i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1341 if (CFStringCompare(slot
,
1342 slot_mappings
[i
].name
,
1343 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1345 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1350 CFRelease(slot_name
);
1353 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1355 case kIOReturnSuccess
: {
1356 CFTypeRef parent_pci_slot_name
= NULL
;
1357 CFStringRef parent_slot
;
1359 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1360 if (parent_slot
!= NULL
) {
1361 if (slot
!= NULL
) CFRelease(slot
);
1362 slot
= (CFMutableStringRef
)parent_slot
;
1364 if (pci_slot_name
!= NULL
) {
1365 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1366 *pci_slot_name
= parent_pci_slot_name
;
1368 if (parent_pci_slot_name
!= NULL
) CFRelease(parent_pci_slot_name
);
1372 IOObjectRelease(parent
);
1375 case kIOReturnNoDevice
:
1376 // if we have hit the root node
1379 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1387 static CFComparisonResult
1388 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1390 #pragma unused(context)
1391 CFStringRef bsd1
= (CFStringRef
)val1
;
1392 CFStringRef bsd2
= (CFStringRef
)val2
;
1394 return CFStringCompare(bsd1
, bsd2
, 0);
1398 static CF_RETURNS_RETAINED CFStringRef
1399 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1402 CFStringRef port_name
= NULL
;
1403 CFMutableArrayRef port_names
;
1406 CFStringRef match_keys
[2];
1407 CFTypeRef match_vals
[2];
1408 CFDictionaryRef match_dict
;
1409 CFDictionaryRef matching
;
1410 io_registry_entry_t slot
;
1411 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1413 match_keys
[0] = CFSTR("AAPL,slot-name");
1414 match_vals
[0] = slot_name
;
1416 match_dict
= CFDictionaryCreate(NULL
,
1417 (const void **)match_keys
,
1418 (const void **)match_vals
,
1420 &kCFTypeDictionaryKeyCallBacks
,
1421 &kCFTypeDictionaryValueCallBacks
);
1423 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1424 match_vals
[0] = CFSTR("IOPCIDevice");
1426 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1427 match_vals
[1] = match_dict
;
1429 // note: the "matching" dictionary will be consumed by the following
1430 matching
= CFDictionaryCreate(NULL
,
1431 (const void **)match_keys
,
1432 (const void **)match_vals
,
1433 sizeof(match_keys
)/sizeof(match_keys
[0]),
1434 &kCFTypeDictionaryKeyCallBacks
,
1435 &kCFTypeDictionaryValueCallBacks
);
1436 CFRelease(match_dict
);
1438 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1439 if (kr
!= kIOReturnSuccess
) {
1440 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1441 return MACH_PORT_NULL
;
1444 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1446 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1447 io_registry_entry_t child
;
1448 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1450 kr
= IORegistryEntryCreateIterator(slot
,
1452 kIORegistryIterateRecursively
,
1454 if (kr
!= kIOReturnSuccess
) {
1455 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1456 CFRelease(port_names
);
1457 return MACH_PORT_NULL
;
1460 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1461 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1462 CFMutableDictionaryRef interface_dict
= NULL
;
1464 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1465 if (interface_dict
!= NULL
) {
1466 CFNumberRef child_if_type
;
1467 int child_ift
= ift
;
1469 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1470 if (child_if_type
!= NULL
) {
1471 if (!isA_CFNumber(child_if_type
) ||
1472 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1473 // assume that it's a match
1478 if (ift
== child_ift
) {
1479 CFStringRef if_bsdName
;
1481 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1482 if (if_bsdName
!= NULL
) {
1483 CFArrayAppendValue(port_names
, if_bsdName
);
1484 CFRelease(if_bsdName
);
1488 CFRelease(interface_dict
);
1491 IOObjectRelease(child
);
1493 IOObjectRelease(child_iterator
);
1494 IOObjectRelease(slot
);
1496 IOObjectRelease(slot_iterator
);
1498 n
= CFArrayGetCount(port_names
);
1500 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1501 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1502 if (n
!= kCFNotFound
) {
1503 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1507 CFRelease(port_names
);
1513 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1515 CFStringRef bsd_name
= NULL
;
1516 CFMutableDictionaryRef interface_dict
= NULL
;
1518 CFTypeRef pci_slot_name
;
1523 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1524 if (interface_dict
!= NULL
) {
1525 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1526 CFRelease(interface_dict
);
1529 if (bsd_name
== NULL
) {
1533 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1534 if (*slot_name
!= NULL
) {
1535 if (pci_slot_name
!= NULL
) {
1536 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1537 CFRelease(pci_slot_name
);
1542 CFRelease(bsd_name
);
1548 isBuiltin(io_registry_entry_t interface
)
1552 slot
= pci_slot(interface
, NULL
);
1554 // interfaces which have a "slot" are not built-in
1564 isBluetoothBuiltin(Boolean
*haveController
)
1566 Boolean builtin
= FALSE
;
1567 io_object_t hciController
;
1568 io_iterator_t iter
= MACH_PORT_NULL
;
1571 kr
= IOServiceGetMatchingServices(masterPort
,
1572 IOServiceMatching("IOBluetoothHCIController"),
1574 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1575 if (kr
!= kIOReturnSuccess
) {
1576 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1578 *haveController
= FALSE
;
1581 *haveController
= TRUE
;
1583 hciController
= IOIteratorNext(iter
);
1584 IOObjectRelease(iter
);
1585 if(hciController
!= MACH_PORT_NULL
) {
1586 #if !TARGET_OS_SIMULATOR
1587 CFNumberRef idVendor
;
1589 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1590 if (idVendor
!= NULL
) {
1593 if (isA_CFNumber(idVendor
) &&
1594 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1595 (idVendorVal
== kIOUSBAppleVendorID
)) {
1599 CFRelease(idVendor
);
1601 #endif // !TARGET_OS_SIMULATOR
1603 IOObjectRelease(hciController
);
1611 isThunderbolt(io_registry_entry_t interface
)
1615 val
= IORegistryEntrySearchCFProperty(interface
,
1617 CFSTR(kPCIThunderboltString
),
1619 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1630 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1631 io_registry_entry_t interface
,
1632 CFDictionaryRef interface_dict
,
1633 io_registry_entry_t controller
,
1634 CFDictionaryRef controller_dict
,
1635 io_registry_entry_t bus
,
1636 CFDictionaryRef bus_dict
)
1638 #if TARGET_OS_SIMULATOR
1639 #pragma unused(interfacePrivate)
1640 #pragma unused(interface)
1641 #endif // TARGET_OS_SIMULATOR
1642 #pragma unused(interface_dict)
1643 #pragma unused(controller)
1644 #pragma unused(controller_dict)
1646 #pragma unused(bus_dict)
1647 #if !TARGET_OS_SIMULATOR
1649 if (interfacePrivate
->usb
.name
== NULL
) {
1650 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1652 CFSTR(kUSBProductString
),
1654 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1656 if (interfacePrivate
->usb
.vid
== NULL
) {
1657 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1659 CFSTR(kUSBVendorID
),
1661 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1663 if (interfacePrivate
->usb
.pid
== NULL
) {
1664 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1666 CFSTR(kUSBProductID
),
1668 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1670 #endif // !TARGET_OS_SIMULATOR
1677 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1678 io_registry_entry_t interface
,
1681 Boolean updated
= FALSE
;
1684 // check if a "Product Name" has been provided
1685 val
= IORegistryEntrySearchCFProperty(interface
,
1687 CFSTR(kIOPropertyProductNameKey
),
1689 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1690 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1691 // else, use "USB Product Name" if available
1692 val
= CFRetain(interfacePrivate
->usb
.name
);
1695 CFStringRef productName
;
1697 productName
= IOCopyCFStringValue(val
);
1700 if (productName
!= NULL
) {
1701 if (CFStringGetLength(productName
) > 0) {
1702 // if we have a [somewhat reasonable?] product name
1703 if (interfacePrivate
->name
!= NULL
) {
1704 CFRelease(interfacePrivate
->name
);
1706 interfacePrivate
->name
= CFRetain(productName
);
1707 if (interfacePrivate
->localized_name
!= NULL
) {
1708 CFRelease(interfacePrivate
->localized_name
);
1709 interfacePrivate
->localized_name
= NULL
;
1711 if (bundle
!= NULL
) {
1712 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1718 CFRelease(productName
);
1727 #pragma mark Interface enumeration
1730 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1731 io_registry_entry_t interface
,
1732 CFDictionaryRef interface_dict
,
1733 io_registry_entry_t controller
,
1734 CFDictionaryRef controller_dict
,
1735 io_registry_entry_t bus
,
1736 CFDictionaryRef bus_dict
);
1740 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1741 io_registry_entry_t interface
,
1742 CFStringRef override
)
1747 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1748 val
= IORegistryEntrySearchCFProperty(interface
,
1752 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1755 if (isA_CFDictionary(val
)) {
1756 if (interfacePrivate
->overrides
== NULL
) {
1757 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1759 &kCFTypeDictionaryKeyCallBacks
,
1760 &kCFTypeDictionaryValueCallBacks
);
1762 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1772 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1773 io_registry_entry_t interface
,
1774 CFDictionaryRef interface_dict
,
1775 io_registry_entry_t controller
,
1776 CFDictionaryRef controller_dict
,
1777 io_registry_entry_t bus
,
1778 CFDictionaryRef bus_dict
)
1788 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1789 if (isA_CFNumber(num
) &&
1790 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1791 interfacePrivate
->type
= CFRetain(num
);
1793 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1801 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1802 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1803 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1804 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1805 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1806 interfacePrivate
->sort_order
= kSortAirPort
;
1807 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1808 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1809 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1810 interfacePrivate
->sort_order
= kSortThunderbolt
;
1811 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1812 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1813 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1814 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1815 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1816 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1817 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1818 interfacePrivate
->sort_order
= kSortTethered
;
1819 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1820 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1821 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1822 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1825 if (interfacePrivate
->interface_type
== NULL
) {
1826 val
= IORegistryEntrySearchCFProperty(interface
,
1828 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1830 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1832 if (isA_CFString(val
)) {
1833 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1834 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1835 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1836 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1837 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1838 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1839 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1840 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1841 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1842 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1843 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1844 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1845 } else if (CFEqual(val
, CFSTR("CarPlay"))) {
1846 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1847 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1848 interfacePrivate
->sort_order
= kSortCarPlay
;
1857 if (interfacePrivate
->interface_type
== NULL
) {
1858 val
= IORegistryEntrySearchCFProperty(interface
,
1860 CFSTR(kUSBSupportsIPhoneOS
),
1862 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1864 if (isA_CFBoolean(val
) && CFBooleanGetValue(val
)) {
1865 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1866 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1867 interfacePrivate
->sort_order
= kSortTethered
;
1873 #endif // TARGET_OS_OSX
1875 if (interfacePrivate
->interface_type
== NULL
) {
1876 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1878 if (CFEqual(str
, CFSTR("radio"))) {
1879 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1880 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1881 interfacePrivate
->sort_order
= kSortOtherWireless
;
1888 if (interfacePrivate
->interface_type
== NULL
) {
1889 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1890 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1891 interfacePrivate
->sort_order
= kSortEthernet
;
1893 // BOND support only enabled for ethernet devices
1894 interfacePrivate
->supportsBond
= TRUE
;
1897 // enable Bridge support
1898 interfacePrivate
->supportsBridge
= TRUE
;
1901 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1903 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1906 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1908 interfacePrivate
->builtin
= isBuiltin(interface
);
1911 if (!interfacePrivate
->builtin
&&
1912 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1913 // always treat AirPort interfaces as built-in
1914 interfacePrivate
->builtin
= TRUE
;
1918 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1919 if ((interfacePrivate
->location
!= NULL
) &&
1920 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1921 CFRelease(interfacePrivate
->location
);
1922 interfacePrivate
->location
= NULL
;
1926 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1927 if (isA_CFNumber(num
) &&
1928 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1929 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1930 interfacePrivate
->supportsVLAN
= TRUE
;
1935 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1936 interfacePrivate
->localized_key
= CFSTR("airport");
1937 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1938 if ((interfacePrivate
->location
== NULL
) ||
1939 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1940 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1942 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1943 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1945 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1946 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1947 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1948 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1949 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1950 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1951 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1952 interfacePrivate
->localized_key
= CFSTR("wireless");
1953 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1954 } else if (interfacePrivate
->builtin
) {
1955 if ((interfacePrivate
->location
== NULL
) ||
1956 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1957 interfacePrivate
->localized_key
= CFSTR("ether");
1959 interfacePrivate
->localized_key
= CFSTR("multiether");
1960 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1963 CFStringRef provider
;
1965 // check provider class
1966 provider
= IORegistryEntrySearchCFProperty(interface
,
1968 CFSTR(kIOProviderClassKey
),
1970 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1971 if (provider
!= NULL
) {
1972 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1973 CFStringRef port_name
;
1974 CFStringRef slot_name
;
1976 // set interface "name"
1977 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1978 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1979 if (isThunderbolt(interface
)) {
1980 if (port_name
== NULL
) {
1981 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1982 interfacePrivate
->localized_arg1
= slot_name
;
1984 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1985 interfacePrivate
->localized_arg1
= slot_name
;
1986 interfacePrivate
->localized_arg2
= port_name
;
1990 if (port_name
== NULL
) {
1991 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1992 interfacePrivate
->localized_arg1
= slot_name
;
1994 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1995 interfacePrivate
->localized_arg1
= slot_name
;
1996 interfacePrivate
->localized_arg2
= port_name
;
2001 io_registry_entry_t node
= interface
;
2003 while (provider
!= NULL
) {
2004 #if !TARGET_OS_SIMULATOR
2005 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
2006 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
2007 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
)) ||
2008 (_SC_isAppleInternal() && IOObjectConformsTo(node
, "IOUserEthernetController"))) {
2009 // get USB info (if available)
2010 processUSBInterface(interfacePrivate
,
2018 // set interface "name"
2019 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2020 interfacePrivate
->localized_key
= CFSTR("usb-ether");
2021 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2025 #endif // !TARGET_OS_SIMULATOR
2027 if (node
== interface
) {
2029 } else if (node
== controller
) {
2035 CFRelease(provider
);
2036 provider
= IORegistryEntrySearchCFProperty(node
,
2038 CFSTR(kIOProviderClassKey
),
2040 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2043 if (interfacePrivate
->localized_key
== NULL
) {
2044 update_interface_name(interfacePrivate
, interface
, FALSE
);
2048 if (provider
!= NULL
) CFRelease(provider
);
2051 if (interfacePrivate
->localized_key
== NULL
) {
2052 // if no provider, not a PCI device, or no slot information
2053 interfacePrivate
->localized_key
= CFSTR("generic-ether");
2054 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2061 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2064 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2067 interfacePrivate
->builtin
= isBuiltin(interface
);
2070 interfacePrivate
->sort_order
= kSortFireWire
;
2073 if (interfacePrivate
->builtin
) {
2074 interfacePrivate
->localized_key
= CFSTR("firewire");
2076 CFStringRef port_name
;
2077 CFStringRef slot_name
;
2079 // set interface "name"
2080 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2081 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2082 if (isThunderbolt(interface
)) {
2083 if (port_name
== NULL
) {
2084 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2085 interfacePrivate
->localized_arg1
= slot_name
;
2087 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2088 interfacePrivate
->localized_arg1
= slot_name
;
2089 interfacePrivate
->localized_arg2
= port_name
;
2092 if (port_name
== NULL
) {
2093 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2094 interfacePrivate
->localized_arg1
= slot_name
;
2096 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2097 interfacePrivate
->localized_arg1
= slot_name
;
2098 interfacePrivate
->localized_arg2
= port_name
;
2106 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2111 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2113 // Hardware (MAC) address
2114 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2115 if (isA_CFData(data
)) {
2116 interfacePrivate
->address
= CFRetain(data
);
2120 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2121 if (isA_CFString(str
)) {
2122 interfacePrivate
->prefix
= CFRetain(str
);
2126 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2127 if (isA_CFNumber(num
) &&
2128 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2129 interfacePrivate
->unit
= CFRetain(num
);
2132 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2133 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2140 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2142 CFDictionaryRef dict
;
2143 CFMutableDictionaryRef newDict
;
2145 if (interfacePrivate
->overrides
== NULL
) {
2146 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2148 &kCFTypeDictionaryKeyCallBacks
,
2149 &kCFTypeDictionaryValueCallBacks
);
2152 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2154 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2156 newDict
= CFDictionaryCreateMutable(NULL
,
2158 &kCFTypeDictionaryKeyCallBacks
,
2159 &kCFTypeDictionaryValueCallBacks
);
2161 if (script
!= NULL
) {
2162 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2164 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2166 if (CFDictionaryGetCount(newDict
) > 0) {
2167 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2169 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2173 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2174 CFRelease(interfacePrivate
->overrides
);
2175 interfacePrivate
->overrides
= NULL
;
2182 is_valid_connection_script(CFStringRef script
)
2184 char ccl
[MAXPATHLEN
];
2185 char path
[MAXPATHLEN
];
2186 sysdir_search_path_enumeration_state state
;
2188 (void) _SC_cfstring_to_cstring(script
,
2191 kCFStringEncodingUTF8
);
2193 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2194 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2195 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2197 struct stat statBuf
;
2199 if (ccl
[0] == '/') {
2200 path
[0] = '\0'; // if modemCCL is a full path
2202 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2204 strlcat(path
, ccl
, sizeof(path
));
2206 if (stat(path
, &statBuf
) != 0) {
2207 if (errno
== ENOENT
) {
2211 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2214 if (S_ISREG(statBuf
.st_mode
)) {
2215 // if we have a valid CCL script
2219 #define BUNDLE_EXT ".ccl"
2220 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2225 if ((n
<= BUNDLE_EXT_LEN
) ||
2226 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2227 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2228 if (stat(path
, &statBuf
) != 0) {
2229 if (errno
== ENOENT
) {
2233 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2237 if (S_ISDIR(statBuf
.st_mode
)) {
2238 // if we have a valid CCL bundle
2248 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2249 io_registry_entry_t interface
,
2250 CFDictionaryRef interface_dict
,
2251 io_registry_entry_t controller
,
2252 CFDictionaryRef controller_dict
,
2253 io_registry_entry_t bus
,
2254 CFDictionaryRef bus_dict
)
2256 CFStringRef base
= NULL
;
2258 Boolean isModem
= FALSE
;
2259 Boolean isWWAN
= FALSE
;
2260 CFStringRef modemCCL
= NULL
;
2264 // check if initializing
2265 val
= IORegistryEntrySearchCFProperty(interface
,
2267 kSCNetworkInterfaceInitializingKey
,
2269 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2271 Boolean initializing
;
2273 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2276 return FALSE
; // if this interface is still initializing
2281 val
= IORegistryEntrySearchCFProperty(interface
,
2285 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2287 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2292 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2293 if (interfacePrivate
->entity_device
== NULL
) {
2297 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2299 base
= CFRetain(interfacePrivate
->entity_device
);
2305 * Exclude ports named "irda" because otherwise the IrDA ports on the
2306 * original iMac (rev's A through D) show up as serial ports. Given
2307 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2308 * even support it, these ports definitely shouldn't be listed.
2310 if (CFStringCompare(base
,
2312 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2316 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2317 Boolean haveController
= FALSE
;
2320 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2321 interfacePrivate
->sort_order
= kSortBluetooth
;
2322 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2323 if (!haveController
) {
2324 // if device with no controller present
2327 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2329 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2330 interfacePrivate
->sort_order
= kSortIrDA
;
2331 } else if (isWWAN
) {
2333 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2334 interfacePrivate
->sort_order
= kSortWWAN
;
2337 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2338 interfacePrivate
->sort_order
= kSortModem
;
2342 interfacePrivate
->entity_type
= kSCEntNetModem
;
2344 // Entity (Hardware)
2345 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2346 if (!isA_CFString(ift
)) {
2350 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2354 if (CFEqual(base
, CFSTR("modem"))) {
2355 interfacePrivate
->builtin
= TRUE
;
2356 interfacePrivate
->sort_order
= kSortInternalModem
;
2357 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2358 interfacePrivate
->sort_order
= kSortUSBModem
;
2360 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2362 interfacePrivate
->sort_order
= kSortSerialPort
;
2367 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2368 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2370 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2371 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2373 // look for modem CCL, unique identifier
2374 if (interfacePrivate
->overrides
!= NULL
) {
2375 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2377 CFStringRef uniqueID
;
2379 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2380 modemCCL
= isA_CFString(modemCCL
);
2382 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2383 uniqueID
= isA_CFString(uniqueID
);
2384 if (uniqueID
!= NULL
) {
2385 // retain the device's base name and the unique id
2386 CFRelease(interfacePrivate
->entity_device
);
2387 interfacePrivate
->entity_device
= CFRetain(base
);
2388 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2393 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2394 // a bit harder for the modem CCL
2395 if (modemCCL
== NULL
) {
2396 val
= IORegistryEntrySearchCFProperty(interface
,
2400 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2402 modemCCL
= IOCopyCFStringValue(val
);
2403 if (modemCCL
!= NULL
) {
2404 set_connection_script(interfacePrivate
, modemCCL
);
2405 CFRelease(modemCCL
);
2413 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2414 interfacePrivate
->localized_key
= CFSTR("irda");
2415 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2416 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2418 CFStringRef localized
= NULL
;
2419 CFStringRef name
= NULL
;
2420 CFMutableStringRef port
;
2422 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2423 CFStringLowercase(port
, NULL
);
2426 CFStringAppend(port
, CFSTR("-port"));
2429 // set non-localized name
2430 if (bundle
!= NULL
) {
2431 name
= copy_interface_string(bundle
, port
, FALSE
);
2434 if (!CFEqual(port
, name
)) {
2435 // if [English] localization available
2436 interfacePrivate
->name
= name
;
2438 // if no [English] localization available, use TTY base name
2440 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2443 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2446 // set localized name
2447 if (bundle
!= NULL
) {
2448 localized
= copy_interface_string(bundle
, port
, TRUE
);
2450 if (localized
!= NULL
) {
2451 if (!CFEqual(port
, localized
)) {
2452 // if localization available
2453 interfacePrivate
->localized_name
= localized
;
2455 // if no localization available, use TTY base name
2456 CFRelease(localized
);
2457 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2460 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2463 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2464 // get USB info (if available)
2465 processUSBInterface(interfacePrivate
,
2473 // set interface "name"
2474 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2475 // if "ModemCCL" not provided, also check if the product/interface
2476 // name matches a CCL script
2477 if ((modemCCL
== NULL
) &&
2478 is_valid_connection_script(interfacePrivate
->name
)) {
2479 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2491 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2492 CFRelease(interfacePrivate
->entity_device
);
2493 interfacePrivate
->entity_device
= NULL
;
2495 if (base
!= NULL
) CFRelease(base
);
2502 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2505 * Create a path for a registry entry.
2509 CFStringRef str
= NULL
;
2511 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2512 if (status
== kIOReturnSuccess
) {
2513 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2514 } else if (status
== kIOReturnBadArgument
) {
2515 io_registry_entry_t parent
;
2517 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2518 if (status
== kIOReturnSuccess
) {
2519 CFStringRef str_parent
;
2521 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2522 if (str_parent
!= NULL
) {
2525 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2526 if (status
== kIOReturnSuccess
) {
2529 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2530 if (status
== kIOReturnSuccess
) {
2531 str
= CFStringCreateWithFormat(NULL
,
2538 str
= CFStringCreateWithFormat(NULL
,
2546 CFRelease(str_parent
);
2549 IOObjectRelease(parent
);
2556 static CFMutableDictionaryRef
2557 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2560 CFMutableDictionaryRef reg_dict
= NULL
;
2561 CFTypeRef value
= NULL
;
2563 reg_dict
= CFDictionaryCreateMutable(NULL
,
2565 &kCFTypeDictionaryKeyCallBacks
,
2566 &kCFTypeDictionaryValueCallBacks
);
2568 for (; idx
< numKeys
; idx
++) {
2569 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2570 if (value
!= NULL
) {
2571 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2579 static SCNetworkInterfaceRef
2580 createInterface(io_registry_entry_t interface
, processInterface func
,
2581 CFStringRef hidden_key
)
2583 io_registry_entry_t bus
= MACH_PORT_NULL
;
2584 CFMutableDictionaryRef bus_dict
= NULL
;
2585 io_registry_entry_t controller
= MACH_PORT_NULL
;
2586 CFMutableDictionaryRef controller_dict
= NULL
;
2587 uint64_t entryID
= 0;
2588 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2589 CFMutableDictionaryRef interface_dict
= NULL
;
2594 const CFStringRef interface_dict_keys
[] = {
2595 CFSTR(kIOInterfaceType
),
2597 CFSTR(kIOBSDNameKey
),
2598 CFSTR(kIOPrimaryInterface
),
2599 CFSTR(kIOInterfaceNamePrefix
),
2600 CFSTR(kIOInterfaceUnit
),
2601 CFSTR(kIOTTYDeviceKey
),
2602 CFSTR(kIOTTYBaseNameKey
),
2603 CFSTR(kIOSerialBSDTypeKey
),
2607 const CFStringRef controller_dict_keys
[] = {
2609 CFSTR(kIOMACAddress
)
2612 const CFStringRef bus_dict_keys
[] = {
2616 if (hidden_key
!= NULL
) {
2618 val
= IORegistryEntrySearchCFProperty(interface
,
2622 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2625 goto done
; // if this interface should not be exposed
2629 interface_dict
= copyIORegistryProperties(interface
,
2630 interface_dict_keys
,
2631 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2633 // get the controller node
2634 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2635 if (kr
!= kIOReturnSuccess
) {
2636 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2640 controller_dict
= copyIORegistryProperties(controller
,
2641 controller_dict_keys
,
2642 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2645 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2646 if (kr
!= kIOReturnSuccess
) {
2647 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2651 bus_dict
= copyIORegistryProperties(bus
,
2653 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2655 // get the registry entry ID
2656 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2657 if (kr
!= kIOReturnSuccess
) {
2658 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2662 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2663 assert(interfacePrivate
!= NULL
);
2664 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2665 interfacePrivate
->entryID
= entryID
;
2667 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2668 val
= IORegistryEntrySearchCFProperty(interface
,
2670 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2672 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2674 if (isA_CFDictionary(val
)) {
2675 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2680 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2681 // get user-notification / auto-configuration preference
2682 val
= IORegistryEntrySearchCFProperty(interface
,
2684 kSCNetworkInterfaceConfigurationActionKey
,
2686 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2688 if (isA_CFString(val
)) {
2689 interfacePrivate
->configurationAction
= CFRetain(val
);
2694 // get HiddenConfiguration preference
2695 val
= IORegistryEntrySearchCFProperty(interface
,
2697 kSCNetworkInterfaceHiddenConfigurationKey
,
2699 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2701 interfacePrivate
->hidden
= TRUE
;
2705 #if TARGET_OS_IPHONE
2706 // get TrustRequired preference
2707 val
= IORegistryEntrySearchCFProperty(interface
,
2709 kSCNetworkInterfaceTrustRequiredKey
,
2711 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2713 if (isA_CFBoolean(val
)) {
2714 interfacePrivate
->trustRequired
= CFBooleanGetValue(val
);
2718 #endif // TARGET_OS_IPHONE
2720 CFRelease(interfacePrivate
);
2721 interfacePrivate
= NULL
;
2726 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2728 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2729 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2731 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2732 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2734 return (SCNetworkInterfaceRef
)interfacePrivate
;
2738 static CF_RETURNS_RETAINED CFArrayRef
2739 findMatchingInterfaces(CFDictionaryRef matching
,
2740 processInterface func
,
2741 CFStringRef hidden_key
,
2742 Boolean keep_pre_configured
)
2744 CFMutableArrayRef interfaces
;
2745 io_registry_entry_t interface
;
2747 io_iterator_t iterator
= MACH_PORT_NULL
;
2750 * A reference to the "matching" dictionary will be consumed by the
2751 * the call to IOServiceGetMatchingServices so we bump up the retain
2756 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2757 if (kr
!= kIOReturnSuccess
) {
2758 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2762 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2764 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2765 SCNetworkInterfaceRef match
;
2767 match
= createInterface(interface
, func
, hidden_key
);
2768 if (match
!= NULL
) {
2769 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2770 CFArrayAppendValue(interfaces
, match
);
2775 IOObjectRelease(interface
);
2778 IOObjectRelease(iterator
);
2785 #pragma mark helper functions
2789 findConfiguration(CFStringRef interface_type
)
2791 for (size_t i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2792 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2803 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2805 CFIndex interfaceIndex
;
2806 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2808 if (interfacePrivate
->serviceID
== NULL
) {
2809 // if not associated with a service (yet)
2810 _SCErrorSet(kSCStatusInvalidArgument
);
2814 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2815 if (interfaceIndex
== kCFNotFound
) {
2816 // unknown interface type, use per-service configuration preferences
2817 return interfacePrivate
->interface_type
; // entity
2820 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2821 // if configuration information can be associated with this interface type
2822 return *configurations
[interfaceIndex
].entity_hardware
;
2825 _SCErrorSet(kSCStatusInvalidArgument
);
2832 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2833 CFStringRef extendedType
,
2834 Boolean requirePerInterface
)
2836 CFStringRef defaultType
;
2837 CFIndex extendedIndex
;
2838 CFIndex interfaceIndex
;
2839 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2840 Boolean isL2TP
= FALSE
;
2843 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2844 if (defaultType
== NULL
) {
2848 if (CFEqual(extendedType
, defaultType
)) {
2849 // extended and default configuration types cannot conflict
2853 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2854 if (interfaceIndex
== kCFNotFound
) {
2855 // configuration information for unknown interface type's
2856 // are stored along with the service and we don't allow
2857 // per-service extended configurations
2861 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2862 CFStringRef interfaceType
;
2864 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2865 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2866 SCNetworkInterfaceRef child
;
2868 child
= SCNetworkInterfaceGetInterface(interface
);
2869 if (child
!= NULL
) {
2870 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2871 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2878 if (requirePerInterface
&&
2879 !configurations
[interfaceIndex
].per_interface_config
&&
2881 // we don't allow per-service extended configurations (except
2882 // that we do allow IPSec as an extended type for PPP->L2TP)
2886 extendedIndex
= findConfiguration(extendedType
);
2887 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2888 // extended type cannot match a known interface type (except
2889 // that we do allow IPSec as an extended type for PPP->L2TP)
2895 * Should we check/match and specifically allow known extended
2896 * configuration types (e.g. EAPOL)?
2898 * Should we check/match and specifically block known internal
2899 * configuration types (e.g. QoSMarking)?
2901 * Lastly, should we ensure that any non-standard extended configuration
2902 * types be of the form com.myCompany.myType?
2911 _SCErrorSet(kSCStatusInvalidArgument
);
2918 CFStringRef defaultType
;
2919 CFMutableArrayRef types
;
2920 } extendedConfiguration
, *extendedConfigurationRef
;
2924 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2926 #pragma unused(value)
2927 CFStringRef extendedType
= (CFStringRef
)key
;
2928 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2930 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2931 // do not include the default configuration type
2935 if (CFArrayContainsValue(myContextRef
->types
,
2936 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2938 // if extendedType already has already been added
2942 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2949 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2951 CFIndex interfaceIndex
;
2952 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2954 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2955 if (interfaceIndex
== kCFNotFound
) {
2956 // if per-service (not per interface) configuration
2960 if (!configurations
[interfaceIndex
].per_interface_config
) {
2961 // if per-interface configuration not allowed
2965 return interfaceIndex
;
2969 static CF_RETURNS_RETAINED CFArrayRef
2970 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2973 CFIndex interfaceIndex
;
2974 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2975 extendedConfiguration myContext
;
2976 SCNetworkServiceRef service
;
2980 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2981 if (myContext
.defaultType
== NULL
) {
2982 myContext
.types
= NULL
;
2986 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2988 if (interfacePrivate
->serviceID
== NULL
) {
2989 // if not associated with a service (yet)
2993 interfaceIndex
= findPerInterfaceConfiguration(interface
);
2994 if (interfaceIndex
== kCFNotFound
) {
2995 // if no per-interface configuration
2999 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3000 interfacePrivate
->prefs
,
3001 interfacePrivate
->serviceID
,
3004 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3005 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3007 for (i
= 0; i
< n
; i
++) {
3008 CFDictionaryRef configs
;
3011 CFArrayRef services
;
3012 SCNetworkSetRef set
;
3014 set
= CFArrayGetValueAtIndex(sets
, i
);
3015 services
= SCNetworkSetCopyServices(set
);
3016 found
= CFArrayContainsValue(services
,
3017 CFRangeMake(0, CFArrayGetCount(services
)),
3019 CFRelease(services
);
3025 // add stored extended configuration types
3026 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3027 SCNetworkSetGetSetID(set
), // set
3028 interfacePrivate
->entity_device
, // service
3030 configs
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
3032 if (isA_CFDictionary(configs
)) {
3033 CFDictionaryApplyFunction(configs
,
3034 __addExtendedConfigurationType
,
3038 // add not-yet-stored extended configuration types
3039 if (interfacePrivate
->unsaved
!= NULL
) {
3040 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
3041 __addExtendedConfigurationType
,
3049 if (sets
!= NULL
) CFRelease(sets
);
3053 return myContext
.types
;
3057 stringCreateArray(CFStringRef str
)
3059 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3063 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3064 CFStringRef extendedType
)
3066 CFMutableArrayRef array
= NULL
;
3070 SCNetworkServiceRef service
;
3073 // known interface type, per-interface configuration preferences
3075 // 1. look for all sets which contain the associated service
3076 // 2. add a per-set path for the interface configuration for
3079 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3080 interfacePrivate
->prefs
,
3081 interfacePrivate
->serviceID
,
3082 (SCNetworkInterfaceRef
)interfacePrivate
);
3084 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3085 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3087 for (i
= 0; i
< n
; i
++) {
3088 CFArrayRef services
;
3089 SCNetworkSetRef set
;
3091 set
= CFArrayGetValueAtIndex(sets
, i
);
3092 services
= SCNetworkSetCopyServices(set
);
3093 if (CFArrayContainsValue(services
,
3094 CFRangeMake(0, CFArrayGetCount(services
)),
3096 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3097 SCNetworkSetGetSetID(set
), // set
3098 interfacePrivate
->entity_device
, // service
3099 extendedType
); // entity
3100 if (array
== NULL
) {
3101 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3103 CFArrayAppendValue(array
, path
);
3106 CFRelease(services
);
3110 if (sets
!= NULL
) CFRelease(sets
);
3116 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3117 CFStringRef extendedType
)
3119 CFArrayRef array
= NULL
;
3120 CFIndex interfaceIndex
;
3123 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3124 if (interfaceIndex
== kCFNotFound
) {
3125 // unknown interface type, use per-service configuration preferences
3126 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3127 interfacePrivate
->serviceID
, // service
3128 extendedType
); // entity
3129 array
= stringCreateArray(path
);
3133 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3134 // known interface type, per-service configuration preferences
3135 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3136 interfacePrivate
->serviceID
, // service
3137 extendedType
); // entity
3138 array
= stringCreateArray(path
);
3142 else if (interfacePrivate
->serviceID
!= NULL
) {
3143 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3151 #pragma mark SCNetworkInterface <--> preferences entity
3156 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3158 CFMutableDictionaryRef entity
;
3159 CFIndex interfaceIndex
;
3160 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3162 entity
= CFDictionaryCreateMutable(NULL
,
3164 &kCFTypeDictionaryKeyCallBacks
,
3165 &kCFTypeDictionaryValueCallBacks
);
3166 if (interfacePrivate
->entity_type
!= NULL
) {
3167 CFDictionarySetValue(entity
,
3168 kSCPropNetInterfaceType
,
3169 interfacePrivate
->entity_type
);
3171 if (interfacePrivate
->entity_subtype
!= NULL
) {
3172 CFDictionarySetValue(entity
,
3173 kSCPropNetInterfaceSubType
,
3174 interfacePrivate
->entity_subtype
);
3176 if (interfacePrivate
->entity_device
!= NULL
) {
3177 CFDictionarySetValue(entity
,
3178 kSCPropNetInterfaceDeviceName
,
3179 interfacePrivate
->entity_device
);
3181 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3182 CFDictionarySetValue(entity
,
3183 CFSTR("DeviceUniqueIdentifier"),
3184 interfacePrivate
->entity_device_unique
);
3186 if (interfacePrivate
->hidden
) {
3187 CFDictionarySetValue(entity
,
3188 kSCNetworkInterfaceHiddenConfigurationKey
,
3191 #if TARGET_OS_IPHONE
3192 if (interfacePrivate
->trustRequired
) {
3193 CFDictionarySetValue(entity
,
3194 kSCNetworkInterfaceTrustRequiredKey
,
3197 #endif // TARGET_OS_IPHONE
3199 // match the "hardware" with the lowest layer
3201 SCNetworkInterfaceRef nextInterface
;
3203 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3204 if (nextInterface
== NULL
) {
3208 interface
= nextInterface
;
3210 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3212 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3216 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3217 if (interfaceIndex
!= kCFNotFound
) {
3218 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3219 CFDictionarySetValue(entity
,
3220 kSCPropNetInterfaceHardware
,
3221 *configurations
[interfaceIndex
].entity_hardware
);
3224 CFDictionarySetValue(entity
,
3225 kSCPropNetInterfaceHardware
,
3226 interfacePrivate
->interface_type
);
3229 // add the localized display name (which will only be used when/if the
3230 // interface is removed from the system)
3231 CFDictionarySetValue(entity
,
3232 kSCPropUserDefinedName
,
3233 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3239 static SCNetworkInterfaceRef
3240 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3245 n
= CFArrayGetCount(interfaces
);
3246 for (i
= 0; i
< n
; i
++) {
3247 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3248 CFStringRef interfaceName
;
3250 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3251 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3252 CFRetain(interface
);
3260 #if !TARGET_OS_IPHONE
3261 static SCNetworkInterfaceRef
3262 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3265 SCNetworkInterfaceRef interface
= NULL
;
3267 if (prefs
== NULL
) {
3271 // check if the interface is an Ethernet Bond
3272 bonds
= SCBondInterfaceCopyAll(prefs
);
3273 if (bonds
!= NULL
) {
3274 interface
= findInterface(bonds
, ifDevice
);
3279 #endif // !TARGET_OS_IPHONE
3281 static SCNetworkInterfaceRef
3282 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3285 SCNetworkInterfaceRef interface
= NULL
;
3287 if (prefs
== NULL
) {
3291 // check if the interface is an bridge
3292 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3293 if (bridges
!= NULL
) {
3294 interface
= findInterface(bridges
, ifDevice
);
3300 static SCNetworkInterfaceRef
3301 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3303 SCNetworkInterfaceRef interface
= NULL
;
3306 if (prefs
== NULL
) {
3310 // check if the interface is a VLAN
3311 vlans
= SCVLANInterfaceCopyAll(prefs
);
3312 if (vlans
!= NULL
) {
3313 interface
= findInterface(vlans
, ifDevice
);
3323 static CFMutableDictionaryRef
3324 copy_ppp_entity(CFStringRef bsdName
)
3326 CFMutableDictionaryRef entity
= NULL
;
3327 CFStringRef pattern
;
3328 CFMutableArrayRef patterns
;
3329 CFDictionaryRef dict
;
3331 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3332 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3333 CFArrayAppendValue(patterns
, pattern
);
3335 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3336 CFArrayAppendValue(patterns
, pattern
);
3338 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3339 CFRelease(patterns
);
3342 const void * keys_q
[N_QUICK
];
3343 const void ** keys
= keys_q
;
3345 const void * vals_q
[N_QUICK
];
3346 const void ** vals
= vals_q
;
3348 n
= CFDictionaryGetCount(dict
);
3349 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3350 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3351 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3353 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3354 for (i
= 0; i
< n
; i
++) {
3355 CFArrayRef components
;
3356 CFStringRef interfaceKey
;
3357 CFDictionaryRef interfaceVal
;
3359 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3360 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3361 CFStringRef serviceID
;
3363 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3364 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3365 !CFEqual(bsdName
, ifName
)) {
3366 // if not matching PPP interface
3370 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3371 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3372 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3373 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3374 CFRelease(interfaceKey
);
3375 CFRelease(components
);
3376 if (interfaceVal
!= NULL
) {
3377 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3381 if (keys
!= keys_q
) {
3382 CFAllocatorDeallocate(NULL
, keys
);
3383 CFAllocatorDeallocate(NULL
, vals
);
3393 SCNetworkInterfaceRef
3394 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3395 CFStringRef bsdName
,
3398 #pragma unused(allocator)
3399 CFMutableDictionaryRef entity
= NULL
;
3401 SCNetworkInterfaceRef interface
;
3403 memset(&ifr
, 0, sizeof(ifr
));
3404 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3407 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3409 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3415 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3417 entity
= copy_ppp_entity(bsdName
);
3421 if (entity
== NULL
) {
3422 entity
= CFDictionaryCreateMutable(NULL
,
3424 &kCFTypeDictionaryKeyCallBacks
,
3425 &kCFTypeDictionaryValueCallBacks
);
3426 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3429 #if !TARGET_OS_IPHONE
3430 if ((flags
& kIncludeBondInterfaces
) == 0) {
3431 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3433 #endif // !TARGET_OS_IPHONE
3435 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3436 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3439 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3440 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3443 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3451 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3453 CFMutableStringRef interfacePrefix
= NULL
;
3457 if (!isA_CFString(bsdName
)) {
3458 SC_log(LOG_DEBUG
, "no BSD name");
3462 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3463 length
= CFStringGetLength(interfacePrefix
);
3465 while (length
> 0) {
3466 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3467 if (lastChar
>= '0' && lastChar
<= '9') {
3468 CFStringDelete(interfacePrefix
,
3469 CFRangeMake(length
-1, 1));
3474 length
= CFStringGetLength(interfacePrefix
);
3477 return interfacePrefix
;
3482 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3483 CFStringRef prefix
);
3487 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3489 Boolean success
= FALSE
;
3490 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3492 if (!isA_SCNetworkInterface(interface
)) {
3493 SC_log(LOG_INFO
, "No interface");
3497 if (CFEqual(currentBSDName
, newBSDName
)) {
3502 if (interfacePrivate
->entity_device
!= NULL
) {
3503 CFRelease(interfacePrivate
->entity_device
);
3505 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3513 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3515 Boolean success
= FALSE
;
3516 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3517 CFStringRef oldPath
= NULL
;
3518 CFStringRef newPath
= NULL
;
3520 // Using the BSD Name update the path
3521 oldPath
= interfacePrivate
->path
;
3522 if (!isA_CFString(oldPath
)) {
3525 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3526 if (interfacePrivate
->path
!= NULL
) {
3527 CFRelease(interfacePrivate
->path
);
3529 interfacePrivate
->path
= CFRetain(newPath
);
3533 if (newPath
!= NULL
) {
3541 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3544 SCNetworkInterfacePrivateRef interfacePrivate
;
3546 if (!isA_CFString(prefix
)) {
3550 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3554 if (interfacePrivate
->prefix
!= NULL
) {
3555 CFRelease(interfacePrivate
->prefix
);
3558 interfacePrivate
->prefix
= prefix
;
3565 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3568 SCNetworkInterfacePrivateRef interfacePrivate
;
3569 CFStringRef newBSDName
= NULL
;
3570 CFStringRef oldBSDName
= NULL
;
3572 if (!isA_CFNumber(unit
)) {
3575 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3577 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3579 if (interfacePrivate
->prefix
== NULL
) {
3580 if (isA_CFString(interfacePrivate
->entity_device
)) {
3581 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3582 if (interfaceNamePrefix
== NULL
) {
3583 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3586 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3587 CFRelease(interfaceNamePrefix
);
3592 if (interfacePrivate
->prefix
!= NULL
) {
3593 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3596 // Update the BSD Name
3597 if ((newBSDName
== NULL
) ||
3598 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3599 SC_log(LOG_INFO
, "BSD name update failed");
3603 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3604 SC_log(LOG_INFO
, "IOPath update failed");
3608 if (interfacePrivate
->unit
!= NULL
) {
3609 CFRelease(interfacePrivate
->unit
);
3611 interfacePrivate
->unit
= unit
;
3614 if (newBSDName
!= NULL
) {
3615 CFRelease(newBSDName
);
3623 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3625 CFMutableDictionaryRef interface_entity
= NULL
;
3626 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3627 CFStringRef bsdName
;
3628 CFBooleanRef builtin
;
3629 CFStringRef interfaceNamePrefix
;
3630 CFNumberRef interfaceType
;
3631 CFNumberRef interfaceUnit
;
3632 CFDataRef macAddress
;
3633 CFStringRef pathMatch
;
3634 CFDictionaryRef info
= NULL
;
3637 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3638 if (!isA_CFString(bsdName
)) {
3642 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3644 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3645 if (!isA_CFString(interfaceNamePrefix
)) {
3649 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3650 if (!isA_CFNumber(interfaceType
)) {
3654 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3655 if (!isA_CFNumber(interfaceUnit
)) {
3659 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3660 if (!isA_CFData(macAddress
)) {
3664 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3665 if (!isA_CFString(pathMatch
)) {
3669 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3670 if (!isA_CFDictionary(info
)) {
3674 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3675 if (!isA_CFString(type
)) {
3679 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3680 &kCFTypeDictionaryKeyCallBacks
,
3681 &kCFTypeDictionaryValueCallBacks
);
3682 if (interfacePrivate
->active
) {
3683 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), kCFBooleanTrue
);
3685 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3686 if (interfacePrivate
->hidden
) {
3687 CFDictionaryAddValue(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
, kCFBooleanTrue
);
3689 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3690 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3691 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3692 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3693 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3694 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3695 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3696 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3697 if (isA_CFArray(interfacePrivate
->matchingMACs
)) {
3698 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceMatchingMACs
), interfacePrivate
->matchingMACs
);
3706 return interface_entity
;
3711 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3712 SCNetworkServiceRef service
)
3714 SCNetworkInterfacePrivateRef interfacePrivate
;
3715 SCNetworkServicePrivateRef servicePrivate
;
3717 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3718 if (interfacePrivate
->prefs
!= NULL
) {
3719 CFRelease(interfacePrivate
->prefs
);
3720 interfacePrivate
->prefs
= NULL
;
3722 if (interfacePrivate
->serviceID
!= NULL
) {
3723 CFRelease(interfacePrivate
->serviceID
);
3724 interfacePrivate
->serviceID
= NULL
;
3727 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3728 if (servicePrivate
->prefs
!= NULL
) {
3729 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3731 if (servicePrivate
->serviceID
!= NULL
) {
3732 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3741 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3746 if (bundle
== NULL
) {
3747 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3751 if (!isA_CFString(name
)) {
3752 // if no interface "name"
3756 // check non-localized name for a match
3757 str
= copy_interface_string(bundle
, key
, FALSE
);
3759 match
= CFEqual(name
, str
);
3766 // check localized name for a match
3767 str
= copy_interface_string(bundle
, key
, TRUE
);
3769 match
= CFEqual(name
, str
);
3780 #define kInterfaceTypeEthernetValue 6
3781 #define kInterfaceTypeFirewireValue 144
3784 static SCNetworkInterfaceRef
3785 __SCNetworkInterfaceCreateWithStorageEntity(CFDictionaryRef interface_entity
)
3787 CFIndex interfaceIndex
;
3788 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3789 CFBooleanRef active
;
3790 CFStringRef bsdName
;
3791 CFBooleanRef hidden
;
3792 CFDictionaryRef interfaceInfo
;
3793 CFBooleanRef ioBuiltin
;
3794 CFStringRef ioInterfaceNamePrefix
= NULL
;
3795 CFNumberRef ioInterfaceType
;
3796 int ioInterfaceTypeNum
;
3797 CFNumberRef ioInterfaceUnit
;
3798 CFDataRef ioMACAddress
;
3799 CFStringRef ioPathMatch
;
3800 CFArrayRef matchingMacs
;
3801 CFStringRef userDefinedName
;
3802 #if !TARGET_OS_SIMULATOR
3803 CFStringRef usbProductName
;
3804 CFNumberRef idProduct
;
3805 CFNumberRef idVendor
;
3806 #endif // !TARGET_OS_SIMULATOR
3809 /* initialize runtime */
3810 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3812 if (!isA_CFDictionary(interface_entity
)) {
3813 SC_log(LOG_INFO
, "No interface entity");
3816 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3817 if (!isA_CFBoolean(active
)) {
3818 active
= kCFBooleanFalse
;
3820 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3821 if (!isA_CFString(bsdName
)) {
3822 SC_log(LOG_INFO
, "No BSD name");
3825 hidden
= CFDictionaryGetValue(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
);
3826 if (!isA_CFBoolean(hidden
)) {
3827 hidden
= kCFBooleanFalse
;
3829 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3830 if (!isA_CFBoolean(ioBuiltin
)) {
3831 SC_log(LOG_INFO
, "No IOBuiltin property");
3834 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3835 if (!isA_CFString(ioInterfaceNamePrefix
)) {
3836 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3837 if (ioInterfaceNamePrefix
== NULL
) {
3838 SC_log(LOG_INFO
, "No BSD interface name prefix");
3842 CFRetain(ioInterfaceNamePrefix
);
3844 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3845 if (!isA_CFNumber(ioInterfaceType
)) {
3846 SC_log(LOG_INFO
, "No IOInterfaceType");
3849 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3850 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3852 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3853 if (!isA_CFNumber(ioInterfaceUnit
)) {
3854 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3857 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3858 if (!isA_CFData(ioMACAddress
)) {
3859 SC_log(LOG_INFO
, "No IOMACAddress");
3862 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3863 if (!isA_CFString(ioPathMatch
)) {
3864 SC_log(LOG_INFO
, "No IOPathMatch");
3867 // Check if Path contains the BSD Name in the end
3869 interfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3870 if (!isA_CFDictionary(interfaceInfo
)) {
3871 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3874 userDefinedName
= CFDictionaryGetValue(interfaceInfo
, kSCPropUserDefinedName
);
3875 #if !TARGET_OS_SIMULATOR
3876 usbProductName
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBProductString
));
3877 idProduct
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBProductID
));
3878 idVendor
= CFDictionaryGetValue(interfaceInfo
, CFSTR(kUSBVendorID
));
3879 #endif // !TARGET_OS_SIMULATOR
3880 matchingMacs
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceMatchingMACs
));
3882 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3883 if (!isA_CFString(type
)) {
3884 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3888 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3889 interfacePrivate
->active
= CFBooleanGetValue(active
);
3890 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3891 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3892 interfacePrivate
->hidden
= CFBooleanGetValue(hidden
);
3893 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3894 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3895 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3896 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3897 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3898 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3899 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3900 #if !TARGET_OS_SIMULATOR
3901 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3902 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3903 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3904 #endif // !TARGET_OS_SIMULATOR
3905 interfacePrivate
->matchingMACs
= ((matchingMacs
!= NULL
) ? CFRetain(matchingMacs
) : NULL
);
3907 // Handling interface types to be seen in NetworkInterfaces.plist
3908 interfaceIndex
= findConfiguration(type
);
3909 if (interfaceIndex
!= kCFNotFound
) {
3910 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3912 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3915 // Extracting entity type from value of interface type
3916 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3917 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3918 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3919 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3924 if (ioInterfaceNamePrefix
!= NULL
) {
3925 CFRelease(ioInterfaceNamePrefix
);
3928 return (SCNetworkInterfaceRef
)interfacePrivate
;
3934 _SCNetworkInterfaceCacheOpen(void)
3936 if (!__SCNetworkInterfaceCacheIsOpen()) {
3937 S_interface_cache
= CFDictionaryCreateMutable(NULL
,
3939 &kCFTypeDictionaryKeyCallBacks
,
3940 &kCFTypeDictionaryValueCallBacks
);
3941 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): open", S_interface_cache
);
3948 _SCNetworkInterfaceCacheClose(void)
3950 if (__SCNetworkInterfaceCacheIsOpen()) {
3951 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): close", S_interface_cache
);
3952 CFRelease(S_interface_cache
);
3953 S_interface_cache
= NULL
;
3959 __SCNetworkInterfaceCacheAdd(CFStringRef bsdName
, CFArrayRef matchingInterfaces
)
3961 if (__SCNetworkInterfaceCacheIsOpen() &&
3963 matchingInterfaces
!= NULL
) {
3964 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): add %@", S_interface_cache
, bsdName
);
3965 CFDictionaryAddValue(S_interface_cache
, bsdName
, matchingInterfaces
);
3970 static inline Boolean
3971 __SCNetworkInterfaceCacheIsOpen(void)
3973 return (S_interface_cache
!= NULL
);
3978 __SCNetworkInterfaceCacheCopy(CFStringRef bsdName
)
3980 if (__SCNetworkInterfaceCacheIsOpen() &&
3982 CFArrayRef matchingInterfaces
= CFDictionaryGetValue(S_interface_cache
, bsdName
);
3983 if (matchingInterfaces
) {
3984 CFRetain(matchingInterfaces
);
3985 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache
, bsdName
);
3987 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache
, bsdName
);
3990 return matchingInterfaces
;
3997 SCNetworkInterfaceRef
3998 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3999 CFDictionaryRef interface_entity
,
4000 SCNetworkServiceRef service
)
4002 #pragma unused(allocator)
4003 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
4004 CFStringRef ifDevice
;
4005 CFStringRef ifName
= NULL
;
4006 CFStringRef ifSubType
;
4008 CFStringRef ifUnique
;
4009 CFArrayRef matching_interfaces
= NULL
;
4010 SCPreferencesRef servicePref
= NULL
;
4011 Boolean useSystemInterfaces
= TRUE
;
4013 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4014 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4016 if (service
!= NULL
) {
4017 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
4018 useSystemInterfaces
= !_SCNetworkConfigurationBypassSystemInterfaces(servicePref
);
4021 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
4022 if (ifType
== NULL
) {
4024 * The interface "Type" was not specified. We'll make an
4025 * assumption that this is an "Ethernet" interface. If a
4026 * real interface exists with the provided interface name
4027 * then the actual type will be set accordingly. If not, we'll
4028 * end up crafting an "Ethernet" SCNetworkInterface that
4029 * will keep the rest of the configuration APIs happy.
4031 ifType
= kSCValNetInterfaceTypeEthernet
;
4034 if (!isA_CFString(ifType
)) {
4038 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
4039 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
4040 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4041 if (!isA_CFString(ifSubType
)) {
4046 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
4047 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
4049 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
4050 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
4051 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
4052 char bsdName
[IFNAMSIZ
];
4053 CFMutableDictionaryRef matching
;
4055 if (!isA_CFString(ifDevice
)) {
4059 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
4060 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4063 if (useSystemInterfaces
) {
4064 // Check to see if we already have the info in the cache
4065 matching_interfaces
= __SCNetworkInterfaceCacheCopy(ifDevice
);
4066 if (matching_interfaces
== NULL
) {
4067 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
4071 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
4072 if (matching
== NULL
) {
4075 matching_interfaces
= findMatchingInterfaces(matching
,
4076 processNetworkInterface
,
4077 kSCNetworkInterfaceHiddenInterfaceKey
,
4080 __SCNetworkInterfaceCacheAdd(ifDevice
, matching_interfaces
);
4081 CFRelease(matching
);
4084 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4085 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4086 CFDictionaryRef matching
;
4087 CFStringRef match_keys
[2];
4088 CFStringRef match_vals
[2];
4090 if (!isA_CFString(ifDevice
)) {
4094 if (useSystemInterfaces
) {
4095 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4096 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4098 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4099 match_vals
[1] = ifDevice
;
4101 matching
= CFDictionaryCreate(NULL
,
4102 (const void **)match_keys
,
4103 (const void **)match_vals
,
4104 sizeof(match_keys
)/sizeof(match_keys
[0]),
4105 &kCFTypeDictionaryKeyCallBacks
,
4106 &kCFTypeDictionaryValueCallBacks
);
4107 matching_interfaces
= findMatchingInterfaces(matching
,
4108 processSerialInterface
,
4109 kSCNetworkInterfaceHiddenPortKey
,
4111 CFRelease(matching
);
4113 if (ifUnique
== NULL
) {
4115 Boolean useDeviceName
= TRUE
;
4117 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4121 for (i
= 0; i
< n
; i
++) {
4122 SCNetworkInterfacePrivateRef scanPrivate
;
4124 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4125 if (scanPrivate
->entity_device_unique
!= NULL
) {
4126 useDeviceName
= FALSE
;
4132 if (useDeviceName
&& useSystemInterfaces
) {
4133 if (matching_interfaces
!= NULL
) {
4134 CFRelease(matching_interfaces
);
4137 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4138 matching
= CFDictionaryCreate(NULL
,
4139 (const void **)match_keys
,
4140 (const void **)match_vals
,
4141 sizeof(match_keys
)/sizeof(match_keys
[0]),
4142 &kCFTypeDictionaryKeyCallBacks
,
4143 &kCFTypeDictionaryValueCallBacks
);
4144 matching_interfaces
= findMatchingInterfaces(matching
,
4145 processSerialInterface
,
4146 kSCNetworkInterfaceHiddenPortKey
,
4148 CFRelease(matching
);
4151 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4152 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4153 kSCNetworkInterfaceTypeL2TP
);
4154 #pragma GCC diagnostic push
4155 #pragma GCC diagnostic ignored "-Wdeprecated"
4156 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4157 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4158 kSCNetworkInterfaceTypePPTP
);
4159 #pragma GCC diagnostic pop
4161 // XXX do we allow non-Apple variants of PPP??? XXX
4162 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4165 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4166 if (!isA_CFString(ifDevice
)) {
4170 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4171 kSCNetworkInterfaceType6to4
);
4172 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4173 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4174 kSCNetworkInterfaceTypeIPSec
);
4175 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4176 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4177 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4178 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4179 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4182 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4183 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4187 if (matching_interfaces
!= NULL
) {
4189 SCPreferencesRef prefs
;
4190 Boolean temp_preferences
= FALSE
;
4192 n
= CFArrayGetCount(matching_interfaces
);
4195 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4196 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4197 // if the unique ID's match
4198 CFRetain(interfacePrivate
);
4202 interfacePrivate
= NULL
;
4205 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4209 if (CFDictionaryGetValueIfPresent(interface_entity
,
4210 kSCPropUserDefinedName
,
4211 (const void **)&ifName
) &&
4212 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4216 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4217 if (prefs
== NULL
) {
4218 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4219 if (prefs
!= NULL
) {
4220 temp_preferences
= TRUE
;
4223 if (prefs
== NULL
) {
4226 #if !TARGET_OS_IPHONE
4227 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4228 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4230 #endif // !TARGET_OS_IPHONE
4231 if ((interfacePrivate
== NULL
)
4232 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4233 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4236 if ((interfacePrivate
== NULL
)
4237 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4238 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4240 if (temp_preferences
) CFRelease(prefs
);
4243 if (ifUnique
!= NULL
) {
4246 // we are looking for an interface with a unique ID
4247 // so let's try to focus our choices
4248 for (i
= 0; i
< n
; i
++) {
4249 SCNetworkInterfacePrivateRef scanPrivate
;
4251 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4252 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4253 if (interfacePrivate
!= NULL
) {
4254 // if we've matched more than one interface
4255 interfacePrivate
= NULL
;
4258 interfacePrivate
= scanPrivate
;
4261 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4262 kSCPropUserDefinedName
,
4263 (const void **)&ifName
)) {
4266 // we don't have a unique ID but do have an interface
4267 // name. If the matching interfaces do have IDs than
4268 // we can try to focus our choices using the name
4269 for (i
= 0; i
< n
; i
++) {
4270 SCNetworkInterfacePrivateRef scanPrivate
;
4272 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4273 if (scanPrivate
->entity_device_unique
!= NULL
) {
4274 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4275 CFStringRef scanName
;
4277 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4278 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4279 continue; // if not the same display name
4283 if (interfacePrivate
!= NULL
) {
4284 // if we've matched more than one interface
4285 interfacePrivate
= NULL
;
4288 interfacePrivate
= scanPrivate
;
4291 if (interfacePrivate
== NULL
) {
4292 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4293 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4295 CFRetain(interfacePrivate
);
4298 CFRelease(matching_interfaces
);
4303 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4305 * if device not present on this system
4307 if (!useSystemInterfaces
) {
4308 if (interfacePrivate
!= NULL
) {
4309 CFRelease(interfacePrivate
);
4313 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4314 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4315 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4316 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4317 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4319 // Using UserDefinedName to check the validity of preferences file
4320 // when useSystemInterfaces is FALSE
4321 if (!useSystemInterfaces
) {
4322 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4323 if (isA_CFString(userDefinedName
) != NULL
) {
4324 CFRetain(userDefinedName
);
4325 if (interfacePrivate
->name
!= NULL
) {
4326 CFRelease(interfacePrivate
->name
);
4328 interfacePrivate
->name
= userDefinedName
;
4330 CFRetain(userDefinedName
);
4331 if (interfacePrivate
->localized_name
!= NULL
) {
4332 CFRelease(interfacePrivate
->localized_name
);
4334 interfacePrivate
->localized_name
= userDefinedName
;
4338 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4339 CFStringRef entity_hardware
;
4340 SCNetworkInterfaceRef virtualInterface
;
4342 if (!useSystemInterfaces
&&
4343 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4344 #if !TARGET_OS_IPHONE
4345 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4346 #endif // !TARGET_OS_IPHONE
4347 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4348 CFRelease(interfacePrivate
);
4349 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4351 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4352 if (isA_CFString((entity_hardware
)) &&
4353 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4354 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4355 interfacePrivate
->localized_key
= CFSTR("airport");
4356 interfacePrivate
->sort_order
= kSortAirPort
;
4360 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4362 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4363 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4364 interfacePrivate
->localized_key
= CFSTR("iPhone");
4365 interfacePrivate
->sort_order
= kSortTethered
;
4366 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4367 interfacePrivate
->localized_key
= CFSTR("iPad");
4368 interfacePrivate
->sort_order
= kSortTethered
;
4369 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4370 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4371 interfacePrivate
->sort_order
= kSortThunderbolt
;
4372 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4373 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4374 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4375 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4376 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4377 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4378 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4379 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4380 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4382 interfacePrivate
->sort_order
= kSortEthernet
;
4386 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4387 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4388 interfacePrivate
->sort_order
= kSortFireWire
;
4389 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4390 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4391 CFStringRef entity_hardware
;
4393 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4394 if (isA_CFString((entity_hardware
)) &&
4395 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4396 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4397 interfacePrivate
->sort_order
= kSortAirPort
;
4399 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4400 interfacePrivate
->sort_order
= kSortEthernet
;
4402 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4403 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4404 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4405 interfacePrivate
->sort_order
= kSortBluetooth
;
4406 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4407 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4408 interfacePrivate
->sort_order
= kSortIrDA
;
4409 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4410 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4411 interfacePrivate
->sort_order
= kSortWWAN
;
4413 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4414 interfacePrivate
->sort_order
= kSortModem
;
4417 SCNetworkInterfaceRef child
;
4419 CFRelease(interfacePrivate
);
4420 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4421 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4422 if (interfacePrivate
== NULL
) {
4426 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4427 SCNetworkInterfaceRef child
;
4428 CFRelease(interfacePrivate
);
4429 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4430 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4431 if (interfacePrivate
== NULL
) {
4434 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4435 CFRelease(interfacePrivate
);
4436 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4437 kSCNetworkInterfaceTypeIPSec
);
4438 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4439 CFRelease(interfacePrivate
);
4440 if (!isA_CFString(ifDevice
)) {
4443 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4444 kSCNetworkInterfaceType6to4
);
4445 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4446 CFRelease(interfacePrivate
);
4447 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4448 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4449 // if vendor interface
4450 pthread_mutex_lock(&lock
);
4451 if (vendor_interface_types
== NULL
) {
4452 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4454 CFSetAddValue(vendor_interface_types
, ifType
);
4455 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4456 pthread_mutex_unlock(&lock
);
4458 // if unknown interface
4459 CFRelease(interfacePrivate
);
4460 interfacePrivate
= NULL
;
4464 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4465 interfacePrivate
->hidden
= TRUE
;
4467 #if TARGET_OS_IPHONE
4468 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceTrustRequiredKey
)) {
4469 interfacePrivate
->trustRequired
= TRUE
;
4471 #endif // TARGET_OS_IPHONE
4474 if (service
!= NULL
) {
4475 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4478 #if !TARGET_OS_IPHONE
4479 // set prefs & serviceID to Bond member interfaces
4480 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4485 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4486 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4487 for (i
= 0; i
< n
; i
++) {
4488 SCNetworkInterfaceRef member
;
4490 member
= CFArrayGetValueAtIndex(members
, i
);
4491 __SCNetworkInterfaceSetService(member
, service
);
4494 #endif // !TARGET_OS_IPHONE
4496 // set prefs & serviceID to Bridge member interfaces
4497 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4502 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4503 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4504 for (i
= 0; i
< n
; i
++) {
4505 SCNetworkInterfaceRef member
;
4507 member
= CFArrayGetValueAtIndex(members
, i
);
4508 __SCNetworkInterfaceSetService(member
, service
);
4511 // set prefs & serviceID to VLAN pyhsical interface
4512 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4513 SCNetworkInterfaceRef vlan_physical
;
4515 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4516 if (vlan_physical
!= NULL
) {
4517 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4522 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4523 SCNetworkInterfaceRef parent
;
4526 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4527 kSCNetworkInterfaceTypePPP
);
4528 CFRelease(interfacePrivate
);
4529 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4530 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4531 SCNetworkInterfaceRef parent
;
4534 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4535 kSCNetworkInterfaceTypeVPN
);
4536 CFRelease(interfacePrivate
);
4537 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4540 return (SCNetworkInterfaceRef
)interfacePrivate
;
4545 #pragma mark SCNetworkInterface APIs
4550 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4552 CFDictionaryRef matching
;
4553 CFArrayRef new_interfaces
;
4555 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4557 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4558 new_interfaces
= findMatchingInterfaces(matching
,
4559 processNetworkInterface
,
4560 kSCNetworkInterfaceHiddenInterfaceKey
,
4561 keep_pre_configured
);
4562 CFRelease(matching
);
4564 return new_interfaces
;
4570 __SCNetworkInterfaceCopyAll_Modem()
4572 CFDictionaryRef matching
;
4573 CFStringRef match_keys
[2];
4574 CFStringRef match_vals
[2];
4575 CFArrayRef new_interfaces
;
4577 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4578 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4580 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4581 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4583 matching
= CFDictionaryCreate(NULL
,
4584 (const void **)match_keys
,
4585 (const void **)match_vals
,
4586 sizeof(match_keys
)/sizeof(match_keys
[0]),
4587 &kCFTypeDictionaryKeyCallBacks
,
4588 &kCFTypeDictionaryValueCallBacks
);
4589 new_interfaces
= findMatchingInterfaces(matching
,
4590 processSerialInterface
,
4591 kSCNetworkInterfaceHiddenPortKey
,
4593 CFRelease(matching
);
4595 return new_interfaces
;
4601 __SCNetworkInterfaceCopyAll_RS232()
4603 CFDictionaryRef matching
;
4604 CFStringRef match_keys
[2];
4605 CFStringRef match_vals
[2];
4606 CFArrayRef new_interfaces
;
4608 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4609 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4611 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4612 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4614 matching
= CFDictionaryCreate(NULL
,
4615 (const void **)match_keys
,
4616 (const void **)match_vals
,
4617 sizeof(match_keys
)/sizeof(match_keys
[0]),
4618 &kCFTypeDictionaryKeyCallBacks
,
4619 &kCFTypeDictionaryValueCallBacks
);
4620 new_interfaces
= findMatchingInterfaces(matching
,
4621 processSerialInterface
,
4622 kSCNetworkInterfaceHiddenPortKey
,
4624 CFRelease(matching
);
4626 return new_interfaces
;
4630 #if !TARGET_OS_IPHONE
4632 addBTPANInterface(CFMutableArrayRef all_interfaces
)
4635 SCNetworkInterfaceRef interface
;
4638 n
= CFArrayGetCount(all_interfaces
);
4639 for (i
= 0; i
< n
; i
++) {
4640 SCNetworkInterfaceRef interface
;
4642 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4643 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4644 // if we already have a BT-PAN interface
4649 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4650 if (interface
!= NULL
) {
4651 // include BT-PAN interface
4652 CFArrayAppendValue(all_interfaces
, interface
);
4653 CFRelease(interface
);
4658 #endif // !TARGET_OS_IPHONE
4662 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4667 n
= CFArrayGetCount(new_interfaces
);
4668 for (i
= 0; i
< n
; i
++) {
4669 CFStringRef bsdName
;
4670 SCNetworkInterfaceRef interface
;
4672 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4673 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4674 if (bsdName
!= NULL
) {
4675 CFArrayAppendValue(all_interfaces
, interface
);
4684 __waitForInterfaces()
4686 CFStringRef key
= NULL
;
4689 SCDynamicStoreRef store
= NULL
;
4691 CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
4693 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4694 if (store
== NULL
) {
4698 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4699 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4700 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4703 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4708 CFArrayRef changedKeys
;
4709 CFDictionaryRef dict
;
4710 Boolean quiet
= FALSE
;
4713 dict
= SCDynamicStoreCopyValue(store
, key
);
4715 if (isA_CFDictionary(dict
) &&
4716 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4717 #if TARGET_OS_IPHONE
4718 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Complete
) ||
4719 #endif // TARGET_OS_IPHONE
4720 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4729 ok
= SCDynamicStoreNotifyWait(store
);
4731 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4735 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4736 if (changedKeys
!= NULL
) {
4737 CFRelease(changedKeys
);
4743 CRSetCrashLogMessage(NULL
);
4745 if (key
!= NULL
) CFRelease(key
);
4746 if (store
!= NULL
) CFRelease(store
);
4751 CFArrayRef
/* of SCNetworkInterfaceRef's */
4752 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4754 CFMutableArrayRef all_interfaces
;
4755 CFArrayRef new_interfaces
;
4756 Boolean temp_preferences
= FALSE
;
4758 /* initialize runtime */
4759 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4761 /* wait for IOKit to quiesce */
4762 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4764 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4766 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4767 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4768 if (new_interfaces
!= NULL
) {
4769 add_interfaces(all_interfaces
, new_interfaces
);
4770 CFRelease(new_interfaces
);
4773 // get Modem interfaces
4774 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4775 if (new_interfaces
!= NULL
) {
4776 add_interfaces(all_interfaces
, new_interfaces
);
4777 CFRelease(new_interfaces
);
4780 // get serial (RS232) interfaces
4781 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4782 if (new_interfaces
!= NULL
) {
4783 add_interfaces(all_interfaces
, new_interfaces
);
4784 CFRelease(new_interfaces
);
4787 // get virtual network interfaces (Bond, Bridge, VLAN)
4788 if (prefs
== NULL
) {
4789 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4790 if (prefs
!= NULL
) {
4791 temp_preferences
= TRUE
;
4794 if (prefs
!= NULL
) {
4795 #if !TARGET_OS_IPHONE
4796 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4797 if (new_interfaces
!= NULL
) {
4798 add_interfaces(all_interfaces
, new_interfaces
);
4799 CFRelease(new_interfaces
);
4801 #endif // !TARGET_OS_IPHONE
4803 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4804 if (new_interfaces
!= NULL
) {
4805 add_interfaces(all_interfaces
, new_interfaces
);
4806 CFRelease(new_interfaces
);
4809 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4810 if (new_interfaces
!= NULL
) {
4811 add_interfaces(all_interfaces
, new_interfaces
);
4812 CFRelease(new_interfaces
);
4815 #if !TARGET_OS_IPHONE
4816 // add BT-PAN interface
4817 addBTPANInterface(all_interfaces
);
4818 #endif // !TARGET_OS_IPHONE
4820 if (temp_preferences
) CFRelease(prefs
);
4823 // all interfaces have been identified, order and return
4824 sort_interfaces(all_interfaces
);
4826 return all_interfaces
;
4830 CFArrayRef
/* of SCNetworkInterfaceRef's */
4831 SCNetworkInterfaceCopyAll()
4833 CFArrayRef all_interfaces
;
4835 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4836 return all_interfaces
;
4840 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4841 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4844 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4846 if (!isA_SCNetworkInterface(interface
)) {
4847 _SCErrorSet(kSCStatusInvalidArgument
);
4851 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4855 i
= findConfiguration(interfacePrivate
->interface_type
);
4856 if (i
!= kCFNotFound
) {
4857 if (configurations
[i
].supported_interfaces
!= doNone
) {
4858 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4859 if (configurations
[i
].supported_interfaces
& do6to4
) {
4860 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4862 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4863 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4865 if (configurations
[i
].supported_interfaces
& doPPP
) {
4866 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4868 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4869 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4873 SCNetworkInterfaceRef child
;
4875 child
= SCNetworkInterfaceGetInterface(interface
);
4876 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4877 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4878 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4884 return interfacePrivate
->supported_interface_types
;
4888 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4889 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4892 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4894 if (!isA_SCNetworkInterface(interface
)) {
4895 _SCErrorSet(kSCStatusInvalidArgument
);
4899 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4903 i
= findConfiguration(interfacePrivate
->interface_type
);
4904 if (i
!= kCFNotFound
) {
4905 if (configurations
[i
].supported_protocols
!= doNone
) {
4906 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4907 if (configurations
[i
].supported_protocols
& doDNS
) {
4908 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4910 if (configurations
[i
].supported_protocols
& doIPv4
) {
4911 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4913 if (configurations
[i
].supported_protocols
& doIPv6
) {
4914 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4916 if (configurations
[i
].supported_protocols
& doProxies
) {
4917 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4919 #if !TARGET_OS_IPHONE
4920 if (configurations
[i
].supported_protocols
& doSMB
) {
4921 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4923 #endif // !TARGET_OS_IPHONE
4929 return interfacePrivate
->supported_protocol_types
;
4933 SCNetworkInterfaceRef
4934 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4936 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4938 SCNetworkInterfacePrivateRef parentPrivate
;
4940 if (!isA_SCNetworkInterface(child
)) {
4941 _SCErrorSet(kSCStatusInvalidArgument
);
4945 if (!isA_CFString(interfaceType
)) {
4946 _SCErrorSet(kSCStatusInvalidArgument
);
4950 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4951 // can't layer on top of loopback
4952 _SCErrorSet(kSCStatusInvalidArgument
);
4956 childIndex
= findConfiguration(childPrivate
->interface_type
);
4958 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4960 childPrivate
->prefs
,
4961 childPrivate
->serviceID
);
4962 if (parentPrivate
== NULL
) {
4963 _SCErrorSet(kSCStatusFailed
);
4967 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4968 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4969 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4972 if (childIndex
!= kCFNotFound
) {
4973 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4974 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4976 // sorry, the child interface does not support PPP
4980 // if the child's interface type not known, use the child entities "Type"
4981 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4984 if (childPrivate
->entity_device
!= NULL
) {
4985 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4988 if (childPrivate
->entity_device_unique
!= NULL
) {
4989 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4991 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4992 if ((childIndex
== kCFNotFound
) ||
4993 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4994 // if the child interface does not support L2TP
4997 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4998 parentPrivate
->localized_key
= CFSTR("l2tp");
4999 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
5000 #pragma GCC diagnostic push
5001 #pragma GCC diagnostic ignored "-Wdeprecated"
5002 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
5003 if ((childIndex
== kCFNotFound
) ||
5004 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
5005 // if the child interface does not support PPTP
5008 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
5009 parentPrivate
->localized_key
= CFSTR("pptp");
5010 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
5011 #pragma GCC diagnostic pop
5012 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
5013 if ((childIndex
== kCFNotFound
) ||
5014 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
5015 // if the child interface does not support 6to4
5019 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
5020 parentPrivate
->localized_key
= CFSTR("6to4");
5021 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
5022 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
5023 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5024 if ((childIndex
== kCFNotFound
) ||
5025 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
5026 // if the child interface does not support IPSec
5029 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
5030 parentPrivate
->localized_key
= CFSTR("ipsec");
5031 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
5032 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5033 if (childIndex
!= kCFNotFound
) {
5034 // if not a "vendor" child interface
5038 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
5039 parentPrivate
->localized_key
= CFSTR("vpn");
5040 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
5041 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
5042 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
5043 if (childPrivate
->entity_device
!= NULL
) {
5044 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
5046 if (parentPrivate
->entity_subtype
!= NULL
) {
5047 CFArrayRef components
;
5049 CFStringRef vpnType
;
5052 // the "default" interface name is derived from the VPN type
5055 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
5058 vpnType
= parentPrivate
->entity_subtype
;
5059 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
5060 n
= CFArrayGetCount(components
);
5062 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
5063 CFMutableStringRef str
;
5065 str
= CFStringCreateMutableCopy(NULL
,
5067 CFArrayGetValueAtIndex(components
, n
- 2));
5068 (void) CFStringFindAndReplace(str
,
5071 CFRangeMake(0, CFStringGetLength(str
)),
5073 parentPrivate
->localized_name
= str
;
5075 CFRelease(components
);
5077 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
5078 // if custom interface type
5079 pthread_mutex_lock(&lock
);
5080 if (vendor_interface_types
== NULL
) {
5081 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
5083 CFSetAddValue(vendor_interface_types
, interfaceType
);
5084 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
5085 pthread_mutex_unlock(&lock
);
5087 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
5088 // a dictionary with the same
5089 // name as the interfaceType
5091 // unknown interface type
5095 parentPrivate
->hidden
= childPrivate
->hidden
;
5097 #if TARGET_OS_IPHONE
5098 parentPrivate
->trustRequired
= childPrivate
->trustRequired
;
5099 #endif // TARGET_OS_IPHONE
5101 if (childPrivate
->overrides
!= NULL
) {
5102 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5105 // The following change handles the case where a user has both an Ethernet and
5106 // PPPoE network service. Because a PPPoE service is typically associated with
5107 // an ISP we want it to be sorted higher in the service order.
5108 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5109 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5110 if ((childPrivate
->interface_type
!= NULL
) &&
5111 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5112 parentPrivate
->sort_order
= kSortAirportPPP
;
5114 parentPrivate
->sort_order
= kSortEthernetPPP
;
5117 // set sort order of the parent to match the child interface
5118 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5121 return (SCNetworkInterfaceRef
)parentPrivate
;
5125 CFRelease(parentPrivate
);
5126 _SCErrorSet(kSCStatusInvalidArgument
);
5133 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5135 CFDictionaryRef config
= NULL
;
5136 CFStringRef defaultType
;
5137 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5139 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5140 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5142 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5143 if (defaultType
!= NULL
) {
5147 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5148 SCNetworkSetGetSetID(set
), // set
5149 interfacePrivate
->entity_device
, // interface
5150 defaultType
); // entity
5152 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5155 if (config
== NULL
) {
5156 // if the "set" does not have a saved configuration, use
5157 // the [template] "interface" configuration
5158 if (interfacePrivate
->unsaved
!= NULL
) {
5159 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5160 if (config
== (CFDictionaryRef
)kCFNull
) {
5165 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5176 static CFDictionaryRef
5177 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5178 CFStringRef extendedType
)
5180 CFDictionaryRef config
= NULL
;
5181 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5184 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5185 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5187 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5188 if (paths
!= NULL
) {
5191 path
= CFArrayGetValueAtIndex(paths
, 0);
5192 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5196 if (interfacePrivate
->unsaved
!= NULL
) {
5197 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5198 if (config
== (CFDictionaryRef
)kCFNull
) {
5204 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5213 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5215 CFDictionaryRef config
;
5216 CFStringRef defaultType
;
5218 if (!isA_SCNetworkInterface(interface
)) {
5219 _SCErrorSet(kSCStatusInvalidArgument
);
5223 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5224 if (defaultType
== NULL
) {
5228 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5229 if (config
== NULL
) {
5230 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5231 SCNetworkInterfacePrivateRef interfacePrivate
;
5234 // if AirPort interface, check for a per-service config
5235 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5236 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5237 interfacePrivate
->serviceID
, // service
5238 kSCEntNetAirPort
); // entity
5239 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
5243 if (config
== NULL
) {
5244 _SCErrorSet(kSCStatusOK
);
5252 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5253 CFStringRef extendedType
)
5255 CFDictionaryRef config
;
5257 if (!isA_SCNetworkInterface(interface
)) {
5258 _SCErrorSet(kSCStatusInvalidArgument
);
5262 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5263 _SCErrorSet(kSCStatusInvalidArgument
);
5267 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5268 if (config
== NULL
) {
5269 _SCErrorSet(kSCStatusOK
);
5278 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5280 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5282 return interfacePrivate
->entity_type
;
5288 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5290 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5292 return interfacePrivate
->entity_subtype
;
5297 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5299 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5301 if (!isA_SCNetworkInterface(interface
)) {
5302 _SCErrorSet(kSCStatusInvalidArgument
);
5306 if ((interfacePrivate
->interface
!= NULL
) &&
5307 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5308 _SCErrorSet(kSCStatusOK
);
5312 return interfacePrivate
->entity_device
;
5317 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5319 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5321 if (!isA_SCNetworkInterface(interface
)) {
5322 _SCErrorSet(kSCStatusInvalidArgument
);
5326 if ((interfacePrivate
->address
!= NULL
) &&
5327 (interfacePrivate
->addressString
== NULL
)) {
5331 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5334 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5335 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5337 if (n
> sizeof(mac
)) {
5338 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5341 for (cp
= mac_p
; n
> 0; n
-= 3) {
5342 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5345 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5346 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5349 return interfacePrivate
->addressString
;
5353 SCNetworkInterfaceRef
5354 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5356 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5358 if (!isA_SCNetworkInterface(interface
)) {
5359 _SCErrorSet(kSCStatusInvalidArgument
);
5363 return interfacePrivate
->interface
;
5368 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5370 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5372 if (!isA_SCNetworkInterface(interface
)) {
5373 _SCErrorSet(kSCStatusInvalidArgument
);
5377 return interfacePrivate
->interface_type
;
5382 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5384 CFStringRef str
= NULL
;
5387 str
= CFBundleCopyLocalizedString(bundle
,
5390 NETWORKINTERFACE_LOCALIZATIONS
);
5392 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5395 NETWORKINTERFACE_LOCALIZATIONS
);
5403 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5405 static Boolean reported
= FALSE
;
5406 CFStringRef str
= NULL
;
5408 str
= copy_string_from_bundle(bundle
, key
, localized
);
5411 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5417 if (CFEqual(str
, key
) && !reported
) {
5418 const CFStringRef knownStrKey
= CFSTR("airport");
5419 CFStringRef knownStrValue
= NULL
;
5421 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5422 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5423 /* We are here because we requested for a localized/non-localized string
5424 based on the localization key, but we were given the same key/NULL back,
5425 implying a bad...bad thing!
5427 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5431 #if TARGET_OS_IPHONE
5432 /* ...and we want to know about it! */
5433 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5434 #endif //TARGET_OS_IPHONE
5438 if (knownStrValue
!= NULL
) {
5439 CFRelease(knownStrValue
);
5449 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5451 CFMutableStringRef local
;
5454 local
= CFStringCreateMutable(NULL
, 0);
5456 while (interface
!= NULL
) {
5457 Boolean added
= FALSE
;
5458 SCNetworkInterfaceRef child
= NULL
;
5459 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5461 if ((interfacePrivate
->interface
!= NULL
) &&
5462 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5463 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5464 child
= interfacePrivate
->interface
;
5467 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5469 CFStringRef key
= interfacePrivate
->localized_key
;
5471 if (oldLocalization
) {
5472 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5473 interfacePrivate
->localized_key
);
5475 fmt
= copy_interface_string(bundle
, key
, localized
);
5477 CFStringAppendFormat(local
,
5480 interfacePrivate
->localized_arg1
,
5481 interfacePrivate
->localized_arg2
);
5485 if (oldLocalization
) {
5491 (interfacePrivate
->prefs
!= NULL
) &&
5492 (interfacePrivate
->serviceID
!= NULL
) &&
5494 CFDictionaryRef entity
;
5497 // check for (and use) the name of the interface when it
5498 // was last available
5499 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5500 interfacePrivate
->serviceID
,
5501 kSCEntNetInterface
);
5502 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5504 if (isA_CFDictionary(entity
)) {
5507 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5508 if (isA_CFString(name
)) {
5509 CFStringAppend(local
, name
);
5516 // create (non-)localized name based on the interface type
5517 CFStringAppend(local
, interfacePrivate
->interface_type
);
5519 // ... and, if this is a leaf node, the interface device
5520 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5521 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5525 if (child
!= NULL
) {
5526 // if this interface is layered over another
5527 CFStringAppend(local
, CFSTR(" --> "));
5533 name
= CFStringCreateCopy(NULL
, local
);
5540 #if !TARGET_OS_IPHONE
5543 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5547 if (!isA_SCNetworkInterface(interface
)) {
5548 _SCErrorSet(kSCStatusInvalidArgument
);
5552 name
= copy_display_name(interface
, TRUE
, TRUE
);
5559 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5561 CFStringRef localized_name
;
5563 if (!isA_SCNetworkInterface(interface
)) {
5564 _SCErrorSet(kSCStatusInvalidArgument
);
5568 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5569 return localized_name
;
5571 #endif // !TARGET_OS_IPHONE
5575 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5577 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5579 if (!isA_SCNetworkInterface(interface
)) {
5585 if (interfacePrivate
->name
!= NULL
) {
5586 CFRelease(interfacePrivate
->name
);
5588 interfacePrivate
->name
= name
;
5593 if (interfacePrivate
->localized_name
!= NULL
) {
5594 CFRelease(interfacePrivate
->localized_name
);
5596 interfacePrivate
->localized_name
= name
;
5601 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5603 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5605 if (!isA_SCNetworkInterface(interface
)) {
5609 return interfacePrivate
->name
;
5615 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5617 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5619 if (!isA_SCNetworkInterface(interface
)) {
5620 _SCErrorSet(kSCStatusInvalidArgument
);
5624 if (interfacePrivate
->name
== NULL
) {
5625 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5628 return interfacePrivate
->name
;
5633 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5635 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5637 if (!isA_SCNetworkInterface(interface
)) {
5638 _SCErrorSet(kSCStatusInvalidArgument
);
5642 if (interfacePrivate
->localized_name
== NULL
) {
5643 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5646 return interfacePrivate
->localized_name
;
5652 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5654 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5655 CFPropertyListRef overrides
= NULL
;
5657 if (interfacePrivate
->overrides
!= NULL
) {
5658 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5666 SCNetworkInterfaceGetTypeID(void)
5668 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5669 return __kSCNetworkInterfaceTypeID
;
5675 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5676 SCNetworkInterfaceRef interface
,
5677 CFStringRef defaultType
,
5678 CFDictionaryRef config
,
5681 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5684 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5685 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5687 if (defaultType
== NULL
) {
5688 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5689 if (defaultType
== NULL
) {
5694 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5701 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5702 SCNetworkSetGetSetID(set
), // set
5703 interfacePrivate
->entity_device
, // interface
5704 defaultType
); // entity
5706 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
, path
, config
, FALSE
);
5709 // if configuration has been saved
5710 if (interfacePrivate
->unsaved
!= NULL
) {
5711 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5712 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5713 CFRelease(interfacePrivate
->unsaved
);
5714 interfacePrivate
->unsaved
= NULL
;
5720 if (config
== NULL
) {
5721 // remember that we are clearing the configuration
5722 config
= (CFDictionaryRef
)kCFNull
;
5725 if (interfacePrivate
->unsaved
== NULL
) {
5726 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5728 &kCFTypeDictionaryKeyCallBacks
,
5729 &kCFTypeDictionaryValueCallBacks
);
5731 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5734 _SCErrorSet(kSCStatusNoKey
);
5745 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5746 CFStringRef extendedType
,
5747 CFDictionaryRef config
,
5750 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5754 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5755 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5757 if (extendedType
== NULL
) {
5758 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5759 if (extendedType
== NULL
) {
5764 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5768 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5769 if (paths
!= NULL
) {
5773 n
= CFArrayGetCount(paths
);
5774 for (i
= 0; i
< n
; i
++) {
5777 path
= CFArrayGetValueAtIndex(paths
, i
);
5778 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
, path
, config
, FALSE
);
5785 // if configuration has been saved
5786 if (interfacePrivate
->unsaved
!= NULL
) {
5787 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5788 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5789 CFRelease(interfacePrivate
->unsaved
);
5790 interfacePrivate
->unsaved
= NULL
;
5798 if (config
== NULL
) {
5799 // remember that we are clearing the configuration
5800 config
= (CFDictionaryRef
)kCFNull
;
5803 if (interfacePrivate
->unsaved
== NULL
) {
5804 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5806 &kCFTypeDictionaryKeyCallBacks
,
5807 &kCFTypeDictionaryValueCallBacks
);
5809 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5812 _SCErrorSet(kSCStatusNoKey
);
5821 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5823 CFStringRef defaultType
;
5826 if (!isA_SCNetworkInterface(interface
)) {
5827 _SCErrorSet(kSCStatusInvalidArgument
);
5831 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5832 if (defaultType
== NULL
) {
5836 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5838 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5840 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5848 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5849 CFStringRef extendedType
,
5850 CFDictionaryRef config
)
5854 if (!isA_SCNetworkInterface(interface
)) {
5855 _SCErrorSet(kSCStatusInvalidArgument
);
5859 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5863 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5865 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5867 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5875 #pragma mark SCNetworkInterface [Refresh Configuration] API
5879 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5884 if (!isA_CFString(ifName
)) {
5885 _SCErrorSet(kSCStatusInvalidArgument
);
5889 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5890 kSCDynamicStoreDomainState
,
5892 kSCEntNetRefreshConfiguration
);
5893 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5900 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5902 CFDataRef data
= NULL
;
5904 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5905 uint32_t status
= kSCStatusOK
;
5906 CFDataRef reply
= NULL
;
5908 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5909 ok
= __SCPreferencesCreate_helper(prefs
);
5915 // serialize the interface name
5916 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5921 // have the helper "refresh" the configuration
5922 status
= kSCStatusOK
;
5924 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5925 SCHELPER_MSG_INTERFACE_REFRESH
,
5929 if (data
!= NULL
) CFRelease(data
);
5934 if (status
!= kSCStatusOK
) {
5943 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5944 _SCHelperClose(&prefsPrivate
->helper_port
);
5947 status
= kSCStatusAccessError
;
5952 _SCErrorSet(status
);
5958 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5961 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5963 if (!isA_SCNetworkInterface(interface
)) {
5964 _SCErrorSet(kSCStatusInvalidArgument
);
5968 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5969 if (ifName
== NULL
) {
5970 _SCErrorSet(kSCStatusInvalidArgument
);
5974 if (interfacePrivate
->prefs
!= NULL
) {
5975 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5976 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5978 if (prefsPrivate
->authorizationData
!= NULL
) {
5979 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5983 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5987 #if !TARGET_OS_IPHONE
5989 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5991 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5993 #endif // !TARGET_OS_IPHONE
5997 #pragma mark SCNetworkInterface Password APIs
6001 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
6003 CFStringRef unique_id
= NULL
;
6005 if (config
!= NULL
) {
6006 CFStringRef encryption
;
6008 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
6009 if (isA_CFString(encryption
) &&
6010 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
6011 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
6014 if (unique_id
== NULL
) {
6015 unique_id
= serviceID
;
6023 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
6025 CFMutableStringRef shared_id
= NULL
;
6027 if (config
!= NULL
) {
6028 CFStringRef encryption
;
6030 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
6031 if (isA_CFString(encryption
) &&
6032 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
6033 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
6034 if (shared_id
!= NULL
) {
6035 CFRetain(shared_id
);
6040 if (shared_id
== NULL
) {
6041 CFStringRef unique_id
;
6043 unique_id
= getPasswordID(config
, serviceID
);
6044 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6045 CFStringAppend(shared_id
, CFSTR(".SS"));
6053 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
6055 CFMutableStringRef xauth_id
= NULL
;
6057 if (config
!= NULL
) {
6058 CFStringRef encryption
;
6060 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
6061 if (isA_CFString(encryption
) &&
6062 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
6063 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
6064 if (xauth_id
!= NULL
) {
6070 if (xauth_id
== NULL
) {
6071 CFStringRef unique_id
;
6073 unique_id
= getPasswordID(config
, serviceID
);
6074 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6075 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
6083 checkInterfacePassword(SCNetworkInterfaceRef interface
,
6084 SCNetworkInterfacePasswordType passwordType
,
6085 SCPreferencesRef
*prefs
,
6086 CFStringRef
*serviceID
)
6088 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6090 if (!isA_SCNetworkInterface(interface
)) {
6094 *serviceID
= interfacePrivate
->serviceID
;
6095 if (*serviceID
== NULL
) {
6099 *prefs
= interfacePrivate
->prefs
;
6100 if (*prefs
== NULL
) {
6104 switch (passwordType
) {
6105 case kSCNetworkInterfacePasswordTypePPP
: {
6106 CFStringRef interfaceType
;
6108 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6109 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6117 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6118 CFStringRef interfaceType
;
6120 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6121 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6122 interface
= SCNetworkInterfaceGetInterface(interface
);
6123 if (interface
!= NULL
) {
6124 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6125 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6126 // if PPP->L2TP interface
6130 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6131 // if IPSec interface
6138 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6142 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6143 CFStringRef interfaceType
;
6145 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6146 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6147 // if IPSec interface
6154 case kSCNetworkInterfacePasswordTypeVPN
: {
6155 CFStringRef interfaceType
;
6157 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6158 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6174 _SCErrorSet(kSCStatusInvalidArgument
);
6180 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6181 SCNetworkInterfacePasswordType passwordType
)
6183 Boolean exists
= FALSE
;
6184 SCPreferencesRef prefs
= NULL
;
6185 CFStringRef serviceID
= NULL
;
6187 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6191 switch (passwordType
) {
6192 case kSCNetworkInterfacePasswordTypePPP
: {
6193 CFDictionaryRef config
;
6194 CFStringRef unique_id
;
6196 // get configuration
6197 config
= SCNetworkInterfaceGetConfiguration(interface
);
6200 unique_id
= getPasswordID(config
, serviceID
);
6203 exists
= __extract_password(prefs
,
6205 kSCPropNetPPPAuthPassword
,
6206 kSCPropNetPPPAuthPasswordEncryption
,
6207 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6213 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6214 CFDictionaryRef config
;
6216 CFStringRef shared_id
;
6218 // get configuration
6219 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6221 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6223 config
= SCNetworkInterfaceGetConfiguration(interface
);
6226 // get sharedSecret ID
6227 shared_id
= copySharedSecretID(config
, serviceID
);
6230 exists
= __extract_password(prefs
,
6232 kSCPropNetIPSecSharedSecret
,
6233 kSCPropNetIPSecSharedSecretEncryption
,
6234 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6237 CFRelease(shared_id
);
6241 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6242 CFDictionaryRef config
;
6243 CFStringRef unique_id
= NULL
;
6245 // get configuration
6246 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6248 // get 802.1X identifier
6249 if (config
!= NULL
) {
6250 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6252 if (!isA_CFString(unique_id
)) {
6257 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6261 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6262 CFDictionaryRef config
;
6263 CFStringRef xauth_id
;
6265 // get configuration
6266 config
= SCNetworkInterfaceGetConfiguration(interface
);
6269 xauth_id
= copyXAuthID(config
, serviceID
);
6272 exists
= __extract_password(prefs
,
6274 kSCPropNetIPSecXAuthPassword
,
6275 kSCPropNetIPSecXAuthPasswordEncryption
,
6276 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6279 CFRelease(xauth_id
);
6283 case kSCNetworkInterfacePasswordTypeVPN
: {
6284 CFDictionaryRef config
;
6287 // get configuration
6288 config
= SCNetworkInterfaceGetConfiguration(interface
);
6291 vpn_id
= getPasswordID(config
, serviceID
);
6294 exists
= __extract_password(prefs
,
6296 kSCPropNetVPNAuthPassword
,
6297 kSCPropNetVPNAuthPasswordEncryption
,
6298 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6305 _SCErrorSet(kSCStatusInvalidArgument
);
6314 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6315 SCNetworkInterfacePasswordType passwordType
)
6317 CFDataRef password
= NULL
;
6318 SCPreferencesRef prefs
= NULL
;
6319 CFStringRef serviceID
= NULL
;
6321 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6325 switch (passwordType
) {
6326 case kSCNetworkInterfacePasswordTypePPP
: {
6327 CFDictionaryRef config
;
6328 CFStringRef unique_id
;
6330 // get configuration
6331 config
= SCNetworkInterfaceGetConfiguration(interface
);
6334 unique_id
= getPasswordID(config
, serviceID
);
6337 (void) __extract_password(prefs
,
6339 kSCPropNetPPPAuthPassword
,
6340 kSCPropNetPPPAuthPasswordEncryption
,
6341 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6347 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6348 CFDictionaryRef config
;
6350 CFStringRef shared_id
;
6352 // get configuration
6353 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6355 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6357 config
= SCNetworkInterfaceGetConfiguration(interface
);
6360 // get sharedSecret ID
6361 shared_id
= copySharedSecretID(config
, serviceID
);
6364 (void) __extract_password(prefs
,
6366 kSCPropNetIPSecSharedSecret
,
6367 kSCPropNetIPSecSharedSecretEncryption
,
6368 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6372 CFRelease(shared_id
);
6376 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6377 CFDictionaryRef config
;
6378 CFStringRef unique_id
= NULL
;
6380 // get configuration
6381 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6383 // get 802.1X identifier
6384 if (config
!= NULL
) {
6385 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6387 if (!isA_CFString(unique_id
)) {
6388 _SCErrorSet(kSCStatusFailed
);
6393 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6397 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6398 CFDictionaryRef config
;
6399 CFStringRef xauth_id
;
6401 // get configuration
6402 config
= SCNetworkInterfaceGetConfiguration(interface
);
6405 xauth_id
= copyXAuthID(config
, serviceID
);
6408 (void) __extract_password(prefs
,
6410 kSCPropNetIPSecXAuthPassword
,
6411 kSCPropNetIPSecXAuthPasswordEncryption
,
6412 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6415 CFRelease(xauth_id
);
6419 case kSCNetworkInterfacePasswordTypeVPN
: {
6420 CFDictionaryRef config
;
6423 // get configuration
6424 config
= SCNetworkInterfaceGetConfiguration(interface
);
6427 vpn_id
= getPasswordID(config
, serviceID
);
6430 (void) __extract_password(prefs
,
6432 kSCPropNetVPNAuthPassword
,
6433 kSCPropNetVPNAuthPasswordEncryption
,
6434 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6441 _SCErrorSet(kSCStatusInvalidArgument
);
6450 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6451 SCNetworkInterfacePasswordType passwordType
)
6454 SCPreferencesRef prefs
= NULL
;
6455 CFStringRef serviceID
= NULL
;
6457 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6461 switch (passwordType
) {
6462 case kSCNetworkInterfacePasswordTypePPP
: {
6463 CFDictionaryRef config
;
6464 CFDictionaryRef newConfig
= NULL
;
6465 CFStringRef unique_id
;
6467 // get configuration
6468 config
= SCNetworkInterfaceGetConfiguration(interface
);
6471 unique_id
= getPasswordID(config
, serviceID
);
6474 ok
= __remove_password(prefs
,
6476 kSCPropNetPPPAuthPassword
,
6477 kSCPropNetPPPAuthPasswordEncryption
,
6478 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6482 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6483 if (newConfig
!= NULL
) CFRelease(newConfig
);
6489 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6490 CFDictionaryRef config
;
6492 CFDictionaryRef newConfig
= NULL
;
6493 CFStringRef shared_id
;
6495 // get configuration
6496 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6498 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6500 config
= SCNetworkInterfaceGetConfiguration(interface
);
6503 // get sharedSecret ID
6504 shared_id
= copySharedSecretID(config
, serviceID
);
6507 ok
= __remove_password(prefs
,
6509 kSCPropNetIPSecSharedSecret
,
6510 kSCPropNetIPSecSharedSecretEncryption
,
6511 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6516 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6520 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6523 if (newConfig
!= NULL
) CFRelease(newConfig
);
6526 CFRelease(shared_id
);
6530 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6531 CFDictionaryRef config
;
6532 CFStringRef unique_id
= NULL
;
6534 // get configuration
6535 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6537 // get 802.1X identifier
6538 if (config
!= NULL
) {
6539 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6541 if (!isA_CFString(unique_id
)) {
6542 _SCErrorSet(kSCStatusFailed
);
6547 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6551 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6552 CFDictionaryRef config
;
6553 CFDictionaryRef newConfig
= NULL
;
6554 CFStringRef xauth_id
;
6556 // get configuration
6557 config
= SCNetworkInterfaceGetConfiguration(interface
);
6560 xauth_id
= copyXAuthID(config
, serviceID
);
6563 ok
= __remove_password(prefs
,
6565 kSCPropNetIPSecXAuthPassword
,
6566 kSCPropNetIPSecXAuthPasswordEncryption
,
6567 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6571 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6572 if (newConfig
!= NULL
) CFRelease(newConfig
);
6575 CFRelease(xauth_id
);
6579 case kSCNetworkInterfacePasswordTypeVPN
: {
6580 CFDictionaryRef config
;
6581 CFDictionaryRef newConfig
= NULL
;
6584 // get configuration
6585 config
= SCNetworkInterfaceGetConfiguration(interface
);
6588 vpn_id
= getPasswordID(config
, serviceID
);
6591 ok
= __remove_password(prefs
,
6593 kSCPropNetVPNAuthPassword
,
6594 kSCPropNetVPNAuthPasswordEncryption
,
6595 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6599 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6600 if (newConfig
!= NULL
) CFRelease(newConfig
);
6606 _SCErrorSet(kSCStatusInvalidArgument
);
6615 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6616 SCNetworkInterfacePasswordType passwordType
,
6618 CFDictionaryRef options
)
6620 CFStringRef account
= NULL
;
6621 CFDictionaryRef config
;
6622 CFStringRef description
= NULL
;
6623 CFStringRef label
= NULL
;
6625 SCPreferencesRef prefs
= NULL
;
6626 CFStringRef serviceID
= NULL
;
6628 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6632 switch (passwordType
) {
6633 case kSCNetworkInterfacePasswordTypePPP
: {
6634 SCNetworkServiceRef service
= NULL
;
6635 CFStringRef unique_id
;
6637 // get configuration
6638 config
= SCNetworkInterfaceGetConfiguration(interface
);
6641 unique_id
= getPasswordID(config
, serviceID
);
6643 // get "Account", "Name", "Kind"
6644 if (config
!= NULL
) {
6645 // auth name --> keychain "Account"
6646 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6648 // PPP [user defined] "name" --> keychain "Name"
6649 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6652 if (label
== NULL
) {
6653 // service name --> keychain "Name"
6654 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6659 label
= SCNetworkServiceGetName(service
);
6660 if (label
== NULL
) {
6661 // interface name --> keychain "Name"
6662 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6666 if (bundle
!= NULL
) {
6667 // "PPP Password" --> keychain "Kind"
6668 description
= CFBundleCopyLocalizedString(bundle
,
6669 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6670 CFSTR("PPP Password"),
6675 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6677 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6678 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6683 CFMutableDictionaryRef newConfig
;
6685 if (config
!= NULL
) {
6686 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6688 newConfig
= CFDictionaryCreateMutable(NULL
,
6690 &kCFTypeDictionaryKeyCallBacks
,
6691 &kCFTypeDictionaryValueCallBacks
);
6693 CFDictionarySetValue(newConfig
,
6694 kSCPropNetPPPAuthPassword
,
6696 CFDictionarySetValue(newConfig
,
6697 kSCPropNetPPPAuthPasswordEncryption
,
6698 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6699 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6700 CFRelease(newConfig
);
6703 if (description
!= NULL
) CFRelease(description
);
6704 if (service
!= NULL
) CFRelease(service
);
6708 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6709 CFDictionaryRef baseConfig
= NULL
;
6711 SCNetworkServiceRef service
= NULL
;
6712 CFStringRef shared_id
;
6714 // get configuration
6715 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6716 config
= SCNetworkInterfaceGetConfiguration(interface
);
6718 baseConfig
= config
;
6719 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6722 // get sharedSecret ID
6723 shared_id
= copySharedSecretID(config
, serviceID
);
6725 // get "Account", "Name", "Kind"
6726 if (config
!= NULL
) {
6727 CFStringRef localIdentifier
;
6728 CFStringRef localIdentifierType
;
6730 if (CFDictionaryGetValueIfPresent(config
,
6731 kSCPropNetIPSecLocalIdentifierType
,
6732 (const void **)&localIdentifierType
)
6733 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6734 && CFDictionaryGetValueIfPresent(config
,
6735 kSCPropNetIPSecLocalIdentifier
,
6736 (const void **)&localIdentifier
)
6737 && isA_CFString(localIdentifier
)) {
6738 // local identifier --> keychain "Account"
6739 account
= localIdentifier
;
6742 // PPP [user defined] "name" --> keychain "Name"
6744 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6746 if (baseConfig
!= NULL
) {
6747 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6752 if (label
== NULL
) {
6753 // service name --> keychain "Name"
6754 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6759 label
= SCNetworkServiceGetName(service
);
6760 if (label
== NULL
) {
6761 // interface name --> keychain "Name"
6762 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6766 if (bundle
!= NULL
) {
6767 // "IPSec Shared Secret" --> keychain "Kind"
6768 description
= CFBundleCopyLocalizedString(bundle
,
6769 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6770 CFSTR("IPSec Shared Secret"),
6775 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6777 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6778 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6783 CFMutableDictionaryRef newConfig
= NULL
;
6785 if (config
!= NULL
) {
6786 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6788 newConfig
= CFDictionaryCreateMutable(NULL
,
6790 &kCFTypeDictionaryKeyCallBacks
,
6791 &kCFTypeDictionaryValueCallBacks
);
6793 CFDictionarySetValue(newConfig
,
6794 kSCPropNetIPSecSharedSecret
,
6796 CFDictionarySetValue(newConfig
,
6797 kSCPropNetIPSecSharedSecretEncryption
,
6798 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6800 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6804 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6806 CFRelease(newConfig
);
6809 if (description
!= NULL
) CFRelease(description
);
6810 if (service
!= NULL
) CFRelease(service
);
6811 CFRelease(shared_id
);
6815 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6816 CFStringRef account
= NULL
;
6817 CFStringRef unique_id
= NULL
;
6819 // get configuration
6820 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6822 // get 802.1X identifier
6823 if (config
!= NULL
) {
6824 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6825 unique_id
= isA_CFString(unique_id
);
6827 if (unique_id
!= NULL
) {
6828 CFRetain(unique_id
);
6832 uuid
= CFUUIDCreate(NULL
);
6833 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6837 // 802.1x UserName --> keychain "Account"
6838 if (config
!= NULL
) {
6839 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6842 // get "Name", "Kind"
6843 if (bundle
!= NULL
) {
6844 CFStringRef interface_name
;
6846 // "Network Connection (%@)" --> keychain "Name"
6847 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6848 if (interface_name
!= NULL
) {
6849 CFStringRef label_fmt
;
6851 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6852 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6853 CFSTR("Network Connection (%@)"),
6855 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6856 CFRelease(label_fmt
);
6858 label
= CFBundleCopyLocalizedString(bundle
,
6859 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6860 CFSTR("Network Connection"),
6864 // "802.1X Password" --> keychain "Kind"
6865 description
= CFBundleCopyLocalizedString(bundle
,
6866 CFSTR("KEYCHAIN_KIND_EAPOL"),
6867 CFSTR("802.1X Password"),
6872 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6874 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6875 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6880 CFMutableDictionaryRef newConfig
= NULL
;
6882 if (config
!= NULL
) {
6883 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6885 newConfig
= CFDictionaryCreateMutable(NULL
,
6887 &kCFTypeDictionaryKeyCallBacks
,
6888 &kCFTypeDictionaryValueCallBacks
);
6890 CFDictionarySetValue(newConfig
,
6891 kEAPClientPropUserPasswordKeychainItemID
,
6893 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6896 CFRelease(newConfig
);
6899 CFRelease(unique_id
);
6900 if (label
!= NULL
) CFRelease(label
);
6901 if (description
!= NULL
) CFRelease(description
);
6905 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6906 SCNetworkServiceRef service
= NULL
;
6907 CFStringRef xauth_id
;
6909 // get configuration
6910 config
= SCNetworkInterfaceGetConfiguration(interface
);
6913 xauth_id
= copyXAuthID(config
, serviceID
);
6915 // get "Account", "Name", "Kind"
6916 if (config
!= NULL
) {
6917 // auth name --> keychain "Account"
6918 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6920 // IPSec [user defined] "name" --> keychain "Name"
6921 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6924 if (label
== NULL
) {
6925 // service name --> keychain "Name"
6926 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6931 label
= SCNetworkServiceGetName(service
);
6932 if (label
== NULL
) {
6933 // interface name --> keychain "Name"
6934 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6938 if (bundle
!= NULL
) {
6939 // "IPSec XAuth Password" --> keychain "Kind"
6940 description
= CFBundleCopyLocalizedString(bundle
,
6941 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6942 CFSTR("IPSec XAuth Password"),
6947 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6949 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6950 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6955 CFMutableDictionaryRef newConfig
;
6957 if (config
!= NULL
) {
6958 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6960 newConfig
= CFDictionaryCreateMutable(NULL
,
6962 &kCFTypeDictionaryKeyCallBacks
,
6963 &kCFTypeDictionaryValueCallBacks
);
6965 CFDictionarySetValue(newConfig
,
6966 kSCPropNetIPSecXAuthPassword
,
6968 CFDictionarySetValue(newConfig
,
6969 kSCPropNetIPSecXAuthPasswordEncryption
,
6970 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6971 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6972 CFRelease(newConfig
);
6975 CFRelease(xauth_id
);
6976 if (description
!= NULL
) CFRelease(description
);
6977 if (service
!= NULL
) CFRelease(service
);
6981 case kSCNetworkInterfacePasswordTypeVPN
: {
6982 SCNetworkServiceRef service
= NULL
;
6985 // get configuration
6986 config
= SCNetworkInterfaceGetConfiguration(interface
);
6989 vpn_id
= getPasswordID(config
, serviceID
);
6991 // get "Account", "Name", "Kind"
6992 if (config
!= NULL
) {
6993 // auth name --> keychain "Account"
6994 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6996 // VPN [user defined] "name" --> keychain "Name"
6997 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
7000 if (label
== NULL
) {
7001 // service name --> keychain "Name"
7002 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
7007 label
= SCNetworkServiceGetName(service
);
7008 if (label
== NULL
) {
7009 // interface name --> keychain "Name"
7010 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
7014 if (bundle
!= NULL
) {
7015 // "VPN Password" --> keychain "Kind"
7016 description
= CFBundleCopyLocalizedString(bundle
,
7017 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
7018 CFSTR("VPN Password"),
7023 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
7025 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
7026 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
7031 CFMutableDictionaryRef newConfig
;
7033 if (config
!= NULL
) {
7034 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7036 newConfig
= CFDictionaryCreateMutable(NULL
,
7038 &kCFTypeDictionaryKeyCallBacks
,
7039 &kCFTypeDictionaryValueCallBacks
);
7041 CFDictionarySetValue(newConfig
,
7042 kSCPropNetVPNAuthPassword
,
7044 CFDictionarySetValue(newConfig
,
7045 kSCPropNetVPNAuthPasswordEncryption
,
7046 kSCValNetVPNAuthPasswordEncryptionKeychain
);
7047 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
7048 CFRelease(newConfig
);
7051 if (description
!= NULL
) CFRelease(description
);
7052 if (service
!= NULL
) CFRelease(service
);
7057 _SCErrorSet(kSCStatusInvalidArgument
);
7065 #pragma mark SCNetworkInterface [Advisory] SPIs
7066 #if TARGET_OS_SIMULATOR
7068 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7069 SCNetworkInterfaceAdvisory advisory
,
7072 #pragma unused(interface)
7073 #pragma unused(advisory)
7074 #pragma unused(reason)
7079 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7081 #pragma unused(interface)
7086 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7088 #pragma unused(interface)
7092 #else /* TARGET_OS_SIMULATOR */
7094 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7095 SCNetworkInterfaceAdvisory advisory
,
7098 IPMonitorControlRef control
;
7099 SCNetworkInterfacePrivateRef interfacePrivate
=
7100 (SCNetworkInterfacePrivateRef
)interface
;
7103 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7104 if (ifName
== NULL
) {
7105 _SCErrorSet(kSCStatusInvalidArgument
);
7108 control
= interfacePrivate
->IPMonitorControl
;
7109 if (control
== NULL
) {
7110 control
= IPMonitorControlCreate();
7111 if (control
== NULL
) {
7112 _SCErrorSet(kSCStatusFailed
);
7115 interfacePrivate
->IPMonitorControl
= control
;
7117 return IPMonitorControlSetInterfaceAdvisory(control
,
7124 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7126 IPMonitorControlRef control
;
7127 SCNetworkInterfacePrivateRef interfacePrivate
=
7128 (SCNetworkInterfacePrivateRef
)interface
;
7131 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7132 if (ifName
== NULL
) {
7133 _SCErrorSet(kSCStatusInvalidArgument
);
7136 control
= interfacePrivate
->IPMonitorControl
;
7137 if (control
== NULL
) {
7138 control
= IPMonitorControlCreate();
7139 if (control
== NULL
) {
7140 _SCErrorSet(kSCStatusFailed
);
7143 interfacePrivate
->IPMonitorControl
= control
;
7145 return IPMonitorControlInterfaceAdvisoryIsSet(control
, ifName
);
7149 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7153 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7154 if (ifName
== NULL
) {
7155 _SCErrorSet(kSCStatusInvalidArgument
);
7158 return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName
);
7160 #endif /* TARGET_OS_SIMULATOR */
7163 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
7167 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
7169 CFMutableDictionaryRef info
;
7170 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7173 if (interface
== NULL
) {
7177 info
= CFDictionaryCreateMutable(NULL
,
7179 &kCFTypeDictionaryKeyCallBacks
,
7180 &kCFTypeDictionaryValueCallBacks
);
7182 // add non-localized interface name
7183 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
7185 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
7189 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
7190 #if !TARGET_OS_SIMULATOR
7191 if (interfacePrivate
->usb
.name
!= NULL
) {
7192 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
7194 if (interfacePrivate
->usb
.vid
!= NULL
) {
7195 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
7197 if (interfacePrivate
->usb
.pid
!= NULL
) {
7198 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
7200 #endif // !TARGET_OS_SIMULATOR
7203 if (CFDictionaryGetCount(info
) == 0) {
7204 // do not return an empty dictionary
7213 SCNetworkInterfaceRef
7214 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7216 SCNetworkInterfaceRef interface
= NULL
;
7218 /* initialize runtime */
7219 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7221 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7222 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
7223 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7224 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
7232 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7234 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7236 return interfacePrivate
->configurationAction
;
7241 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7243 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7245 return interfacePrivate
->address
;
7250 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7252 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7254 return interfacePrivate
->prefix
;
7259 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7261 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7263 return interfacePrivate
->type
;
7268 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7270 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7272 return interfacePrivate
->unit
;
7277 update_ift_family(SCNetworkInterfaceRef interface
)
7279 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7281 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7283 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7284 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7287 memset(&ifr
, 0, sizeof(ifr
));
7288 if ((bsdName
!= NULL
) &&
7289 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7292 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7294 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7295 ifr
.ifr_type
.ift_family
= 0;
7296 ifr
.ifr_type
.ift_subfamily
= 0;
7302 interfacePrivate
->family
= CFNumberCreate(NULL
,
7303 kCFNumberSInt32Type
,
7304 &ifr
.ifr_type
.ift_family
);
7305 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7306 kCFNumberSInt32Type
,
7307 &ifr
.ifr_type
.ift_subfamily
);
7313 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7315 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7317 // note: family not in IORegistry, fetch with ioctl()
7319 if (interfacePrivate
->family
== NULL
) {
7320 update_ift_family(interface
);
7323 return interfacePrivate
->family
;
7328 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7330 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7332 // note: subfamily not in IORegistry, fetch with ioctl()
7334 if (interfacePrivate
->subfamily
== NULL
) {
7335 update_ift_family(interface
);
7338 return interfacePrivate
->subfamily
;
7343 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7345 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7347 return interfacePrivate
->path
;
7352 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7354 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7356 return interfacePrivate
->entryID
;
7362 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7364 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7366 return interfacePrivate
->active
;
7371 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7373 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7375 return interfacePrivate
->builtin
;
7380 _SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface
)
7382 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7384 return interfacePrivate
->trustRequired
;
7389 #pragma mark SCNetworkInterface SPIs
7394 SCNetworkInterfaceRef
7395 _SCNetworkInterfaceCopyBTPANInterface(void)
7397 CFDictionaryRef dict
;
7398 SCNetworkInterfaceRef interface
= NULL
;
7401 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7402 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7406 CFStringRef if_name
;
7407 SCNetworkInterfacePrivateRef interfacePrivate
;
7409 if (isA_CFDictionary(dict
) &&
7410 CFDictionaryGetValueIfPresent(dict
,
7411 kInterfaceNamerKey_BT_PAN_Name
,
7412 (const void **)&if_name
) &&
7413 isA_CFString(if_name
)) {
7414 CFMutableDictionaryRef entity
;
7416 entity
= CFDictionaryCreateMutable(NULL
,
7418 &kCFTypeDictionaryKeyCallBacks
,
7419 &kCFTypeDictionaryValueCallBacks
);
7420 CFDictionarySetValue(entity
,
7421 kSCPropNetInterfaceType
,
7422 kSCValNetInterfaceTypeEthernet
);
7423 CFDictionarySetValue(entity
,
7424 kSCPropNetInterfaceDeviceName
,
7426 CFDictionarySetValue(entity
,
7427 kSCPropUserDefinedName
,
7428 CFSTR(BT_PAN_NAME
));
7429 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7433 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7435 if ((interfacePrivate
!= NULL
) &&
7436 (interfacePrivate
->address
== NULL
) &&
7437 CFDictionaryGetValueIfPresent(dict
,
7438 kInterfaceNamerKey_BT_PAN_Mac
,
7439 (const void **)&addr
) &&
7441 interfacePrivate
->address
= CFRetain(addr
);
7449 #endif // TARGET_OS_OSX
7453 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7455 io_registry_entry_t device
;
7456 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7457 CFStringRef device_path
= NULL
;
7458 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7460 CFStringRef match_keys
[2];
7461 CFTypeRef match_vals
[2];
7462 CFDictionaryRef match_dict
;
7463 CFDictionaryRef matching
;
7465 if (interfacePrivate
->entity_device
== NULL
) {
7469 if (interfacePrivate
->entity_device_unique
== NULL
) {
7473 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7474 match_vals
[0] = interfacePrivate
->entity_device
;
7475 match_dict
= CFDictionaryCreate(NULL
,
7476 (const void **)match_keys
,
7477 (const void **)match_vals
,
7479 &kCFTypeDictionaryKeyCallBacks
,
7480 &kCFTypeDictionaryValueCallBacks
);
7482 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7483 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7484 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7485 match_vals
[1] = match_dict
;
7486 matching
= CFDictionaryCreate(NULL
,
7487 (const void **)match_keys
,
7488 (const void **)match_vals
,
7489 sizeof(match_keys
)/sizeof(match_keys
[0]),
7490 &kCFTypeDictionaryKeyCallBacks
,
7491 &kCFTypeDictionaryValueCallBacks
);
7492 CFRelease(match_dict
);
7494 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7495 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7496 if (kr
!= kIOReturnSuccess
) {
7497 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7501 while ((device_path
== NULL
) &&
7502 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7503 CFDictionaryRef overrides
;
7505 overrides
= IORegistryEntrySearchCFProperty(device
,
7507 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7509 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7510 if (overrides
!= NULL
) {
7511 CFDictionaryRef modemOverrides
;
7513 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7514 if (modemOverrides
!= NULL
) {
7515 CFRetain(modemOverrides
);
7517 CFRelease(overrides
);
7518 overrides
= modemOverrides
;
7520 if (overrides
== NULL
) {
7521 overrides
= IORegistryEntrySearchCFProperty(device
,
7523 CFSTR("DeviceModemOverrides"),
7525 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7527 if (overrides
!= NULL
) {
7528 if (isA_CFDictionary(overrides
)) {
7529 CFStringRef matchIdentifier
;
7531 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7532 if (isA_CFString(matchIdentifier
) &&
7533 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7534 device_path
= IORegistryEntryCreateCFProperty(device
,
7535 CFSTR(kIOTTYDeviceKey
),
7540 CFRelease(overrides
);
7542 IOObjectRelease(device
);
7545 IOObjectRelease(device_iterator
);
7549 if (device_path
== NULL
) {
7550 // if we haven't found an exact match to our UniqueIdentifier
7551 // so we simply return the base name.
7552 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7553 if (device_path
!= NULL
) {
7554 CFRetain(device_path
);
7566 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7568 #if TARGET_OS_SIMULATOR
7569 #pragma unused(interface)
7570 #else // TARGET_OS_SIMULATOR
7571 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7573 if (!_SCNetworkInterfaceIsHiddenConfiguration(interface
)) {
7574 // if not HiddenConfiguration
7578 if (_SCNetworkInterfaceIsBuiltin(interface
)) {
7583 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7586 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7587 (vid
== kIOUSBAppleVendorID
)) {
7588 // if Apple interface
7593 if (_SCNetworkInterfaceIsCarPlay(interface
)) {
7595 if ((interfacePrivate
->overrides
!= NULL
) &&
7596 (CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) ||
7597 CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7598 // and overrides are present
7602 #endif // TARGET_OS_SIMULATOR
7609 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7611 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7613 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7618 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7620 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7622 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7627 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7629 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7631 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7636 _SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface
)
7638 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7640 return (interfacePrivate
->sort_order
== kSortCarPlay
);
7645 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7647 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7649 return interfacePrivate
->hidden
;
7654 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7656 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7658 return (interfacePrivate
->sort_order
== kSortTethered
);
7663 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7665 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7666 CFStringRef interfaceType
;
7668 if (!isA_SCNetworkInterface(interface
)) {
7672 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7673 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7678 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7679 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7681 // if an empty bridge
7685 for (i
= 0; i
< n
; i
++) {
7686 SCNetworkInterfaceRef member
;
7687 SCNetworkInterfacePrivateRef memberPrivate
;
7689 member
= CFArrayGetValueAtIndex(members
, i
);
7690 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7691 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7696 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7700 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7708 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7710 CFDictionaryRef policy
;
7712 if (!isA_SCNetworkInterface(interface
)) {
7713 _SCErrorSet(kSCStatusInvalidArgument
);
7717 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7718 if (policy
== NULL
) {
7719 _SCErrorSet(kSCStatusOK
);
7726 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7730 if (!isA_SCNetworkInterface(interface
)) {
7731 _SCErrorSet(kSCStatusInvalidArgument
);
7735 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7737 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7739 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7747 #pragma mark SCNetworkInterface [internal] SPIs
7751 SCNetworkInterfacePrivateRef
7752 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7753 SCNetworkInterfaceRef interface
,
7754 SCPreferencesRef prefs
,
7755 CFStringRef serviceID
)
7757 #pragma unused(allocator)
7758 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7759 SCNetworkInterfacePrivateRef newPrivate
;
7761 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7762 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7764 if (interface
== kSCNetworkInterfaceIPv4
) {
7765 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7768 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7769 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7770 if (oldPrivate
->interface
!= NULL
) {
7771 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7772 oldPrivate
->interface
, // interface
7773 prefs
, // [new] prefs
7774 serviceID
); // [new] serviceID
7776 if (oldPrivate
->name
!= NULL
) {
7777 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7779 if (oldPrivate
->prefix
!= NULL
) {
7780 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7782 if (oldPrivate
->localized_name
!= NULL
) {
7783 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7785 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7786 if (oldPrivate
->localized_arg1
!= NULL
) {
7787 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7789 if (oldPrivate
->localized_arg2
!= NULL
) {
7790 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7792 if (oldPrivate
->unsaved
!= NULL
) {
7793 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7795 if (oldPrivate
->entity_device
!= NULL
) {
7796 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7798 if (oldPrivate
->entity_device_unique
!= NULL
) {
7799 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7801 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7802 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7803 if (oldPrivate
->supported_interface_types
!= NULL
) {
7804 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7806 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7807 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7809 if (oldPrivate
->address
!= NULL
) {
7810 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7812 newPrivate
->builtin
= oldPrivate
->builtin
;
7813 if (oldPrivate
->configurationAction
!= NULL
) {
7814 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7816 newPrivate
->hidden
= oldPrivate
->hidden
;
7817 #if TARGET_OS_IPHONE
7818 newPrivate
->trustRequired
= oldPrivate
->trustRequired
;
7819 #endif // TARGET_OS_IPHONE
7820 if (oldPrivate
->location
!= NULL
) {
7821 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7823 if (oldPrivate
->path
!= NULL
) {
7824 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7826 newPrivate
->entryID
= oldPrivate
->entryID
;
7827 if (oldPrivate
->overrides
!= NULL
) {
7828 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7830 if (oldPrivate
->type
!= NULL
) {
7831 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7833 if (oldPrivate
->unit
!= NULL
) {
7834 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7836 if (oldPrivate
->family
!= NULL
) {
7837 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7839 if (oldPrivate
->subfamily
!= NULL
) {
7840 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7842 if (oldPrivate
->usb
.name
!= NULL
) {
7843 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7845 if (oldPrivate
->usb
.vid
!= NULL
) {
7846 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7848 if (oldPrivate
->usb
.pid
!= NULL
) {
7849 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7851 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7853 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7854 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7855 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7857 if (oldPrivate
->bond
.mode
!= NULL
) {
7858 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7860 if (oldPrivate
->bond
.options
!= NULL
) {
7861 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7864 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7865 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7866 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7868 if (oldPrivate
->bridge
.options
!= NULL
) {
7869 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7872 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7873 if (oldPrivate
->vlan
.interface
!= NULL
) {
7874 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7876 if (oldPrivate
->vlan
.tag
!= NULL
) {
7877 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7879 if (oldPrivate
->vlan
.options
!= NULL
) {
7880 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7889 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7891 CFMutableArrayRef configs
;
7893 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7895 while (interface
!= NULL
) {
7896 CFStringRef defaultType
;
7897 CFMutableDictionaryRef interfaceConfiguration
;
7899 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7901 &kCFTypeDictionaryKeyCallBacks
,
7902 &kCFTypeDictionaryValueCallBacks
);
7904 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7905 if (defaultType
!= NULL
) {
7906 CFDictionaryRef config
;
7907 CFArrayRef extendedTypes
;
7910 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7912 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7914 if (config
== NULL
) {
7915 config
= (CFDictionaryRef
)kCFNull
;
7917 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7919 extendedTypes
= extendedConfigurationTypes(interface
);
7920 if (extendedTypes
!= NULL
) {
7924 n
= CFArrayGetCount(extendedTypes
);
7925 for (i
= 0; i
< n
; i
++) {
7926 CFStringRef extendedType
;
7928 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7929 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7930 if (config
== NULL
) {
7931 config
= (CFDictionaryRef
)kCFNull
;
7933 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7936 CFRelease(extendedTypes
);
7940 CFArrayAppendValue(configs
, interfaceConfiguration
);
7941 CFRelease(interfaceConfiguration
);
7943 interface
= SCNetworkInterfaceGetInterface(interface
);
7950 __private_extern__ Boolean
7951 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7953 CFArrayRef interfaces
;
7954 Boolean match
= FALSE
;
7955 CFMutableSetRef members
;
7957 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7959 #if !TARGET_OS_IPHONE
7960 // add Bond [member] interfaces
7961 interfaces
= SCBondInterfaceCopyAll(prefs
);
7962 if (interfaces
!= NULL
) {
7963 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7964 CFRelease(interfaces
);
7966 #endif // !TARGET_OS_IPHONE
7968 // add Bridge [member] interfaces
7969 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7970 if (interfaces
!= NULL
) {
7971 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7972 CFRelease(interfaces
);
7975 if (CFSetGetCount(members
) == 0) {
7979 while (interface
!= NULL
) {
7980 match
= CFSetContainsValue(members
, interface
);
7982 // if the interface is a member of an
7983 // Ethernet Bond or Bridge
7987 interface
= SCNetworkInterfaceGetInterface(interface
);
7999 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
,
8000 SCNetworkInterfaceRef interface
,
8005 for (i
= 0; interface
!= NULL
; i
++) {
8006 CFStringRef defaultType
;
8007 CFDictionaryRef interfaceConfiguration
;
8010 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
8012 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
8013 if (defaultType
!= NULL
) {
8014 CFDictionaryRef config
;
8015 CFArrayRef extendedTypes
;
8017 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
8019 if (config
== (CFDictionaryRef
)kCFNull
) {
8023 // if service is not associated with the set
8024 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
8026 // apply default configuration to this set
8027 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
8030 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8033 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8035 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8040 extendedTypes
= extendedConfigurationTypes(interface
);
8041 if (extendedTypes
!= NULL
) {
8045 n
= CFArrayGetCount(extendedTypes
);
8046 for (j
= 0; j
< n
; j
++) {
8047 CFStringRef extendedType
;
8049 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
8050 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
8052 if (config
== (CFDictionaryRef
)kCFNull
) {
8055 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
8057 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8060 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8062 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8068 CFRelease(extendedTypes
);
8072 interface
= SCNetworkInterfaceGetInterface(interface
);
8079 SCNetworkInterfaceRef
8080 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
8082 SCNetworkInterfaceRef interface
;
8084 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
8085 if (interface
== NULL
) {
8089 if (store
!= NULL
) {
8090 SCNetworkInterfacePrivateRef interfacePrivate
=
8091 (SCNetworkInterfacePrivateRef
)interface
;
8094 interfacePrivate
->store
= store
;
8101 #if !TARGET_OS_SIMULATOR
8102 SCNetworkServicePrimaryRank
8103 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8105 IPMonitorControlRef control
;
8106 SCNetworkInterfacePrivateRef interfacePrivate
=
8107 (SCNetworkInterfacePrivateRef
)interface
;
8108 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
8110 control
= interfacePrivate
->IPMonitorControl
;
8111 if (control
!= NULL
) {
8114 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8115 if (ifName
!= NULL
) {
8116 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
8120 _SCErrorSet(kSCStatusInvalidArgument
);
8127 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8128 SCNetworkServicePrimaryRank newRank
)
8130 IPMonitorControlRef control
;
8131 SCNetworkInterfacePrivateRef interfacePrivate
=
8132 (SCNetworkInterfacePrivateRef
)interface
;
8135 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8136 if (ifName
== NULL
) {
8137 _SCErrorSet(kSCStatusInvalidArgument
);
8140 control
= interfacePrivate
->IPMonitorControl
;
8141 if (control
== NULL
) {
8142 control
= IPMonitorControlCreate();
8143 if (control
== NULL
) {
8144 _SCErrorSet(kSCStatusFailed
);
8147 interfacePrivate
->IPMonitorControl
= control
;
8149 return IPMonitorControlSetInterfacePrimaryRank(control
,
8155 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8157 Boolean disable_until_needed
= FALSE
;
8158 CFNumberRef disable_prop
= NULL
;
8159 CFIndex interfaceIndex
;
8160 SCNetworkInterfacePrivateRef interfacePrivate
8161 = (SCNetworkInterfacePrivateRef
)interface
;
8162 CFArrayRef path_list
;
8164 if (interfacePrivate
->prefs
== NULL
) {
8165 _SCErrorSet(kSCStatusInvalidArgument
);
8168 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8169 if (interfaceIndex
== kCFNotFound
) {
8170 _SCErrorSet(kSCStatusInvalidArgument
);
8173 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8174 if (path_list
!= NULL
) {
8175 CFDictionaryRef config
;
8176 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
8178 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
8179 CFRelease(path_list
);
8180 if (config
!= NULL
) {
8183 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
8184 disable_prop
= isA_CFNumber(disable_prop
);
8185 if (disable_prop
!= NULL
) {
8186 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
8187 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
8190 /* invalid property, ignore it */
8191 disable_prop
= NULL
;
8196 if (disable_prop
== NULL
) {
8197 disable_until_needed
8198 = _SCNetworkInterfaceIsTethered(interface
);
8200 _SCErrorSet(kSCStatusOK
);
8201 return (disable_until_needed
);
8205 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8209 CFIndex interfaceIndex
;
8210 SCNetworkInterfacePrivateRef interfacePrivate
8211 = (SCNetworkInterfacePrivateRef
)interface
;
8213 CFArrayRef path_list
;
8215 if (interfacePrivate
->prefs
== NULL
) {
8216 _SCErrorSet(kSCStatusInvalidArgument
);
8219 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
8220 _SCErrorSet(kSCStatusInvalidArgument
);
8223 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8224 if (interfaceIndex
== kCFNotFound
) {
8225 _SCErrorSet(kSCStatusInvalidArgument
);
8228 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8229 if (path_list
== NULL
) {
8230 _SCErrorSet(kSCStatusInvalidArgument
);
8233 count
= CFArrayGetCount(path_list
);
8234 for (i
= 0; i
< count
; i
++) {
8235 CFDictionaryRef config
;
8236 CFMutableDictionaryRef new_config
;
8237 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
8239 config
= __SCNetworkConfigurationGetValue(interfacePrivate
->prefs
, path
);
8240 if (config
!= NULL
) {
8242 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
8245 = CFDictionaryCreateMutable(NULL
, 0,
8246 &kCFTypeDictionaryKeyCallBacks
,
8247 &kCFTypeDictionaryValueCallBacks
);
8249 if (disable
!= NULL
) {
8250 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
8252 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
8254 ok
= __SCNetworkConfigurationSetValue(interfacePrivate
->prefs
,
8256 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
8258 CFRelease(new_config
);
8263 CFRelease(path_list
);
8268 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8275 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8276 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8282 #else // !TARGET_OS_SIMULATOR
8284 SCNetworkServicePrimaryRank
8285 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8287 #pragma unused(interface)
8288 return (kSCNetworkServicePrimaryRankDefault
);
8292 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8293 SCNetworkServicePrimaryRank newRank
)
8295 #pragma unused(interface)
8296 #pragma unused(newRank)
8297 _SCErrorSet(kSCStatusInvalidArgument
);
8302 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8304 #pragma unused(interface)
8309 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8311 #pragma unused(interface)
8312 #pragma unused(disable)
8317 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8319 #pragma unused(interface)
8320 #pragma unused(disable)
8321 _SCErrorSet(kSCStatusInvalidArgument
);
8325 #endif // !TARGET_OS_SIMULATOR
8329 CFArrayRef
// SCNetworkInterfaceRef
8330 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs
)
8333 CFMutableArrayRef interfaceList
= NULL
;
8335 /* initialize runtime */
8336 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8338 if (ni_prefs
!= NULL
) {
8341 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8345 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8346 if (isA_CFArray(if_list
)) {
8347 CFIndex n
= CFArrayGetCount(if_list
);
8349 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8350 for (CFIndex i
= 0; i
< n
; i
++) {
8351 CFDictionaryRef dict
;
8353 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8354 if (isA_CFDictionary(dict
) != NULL
) {
8355 SCNetworkInterfaceRef interface
;
8357 interface
= __SCNetworkInterfaceCreateWithStorageEntity(dict
);
8358 if (interface
!= NULL
) {
8359 CFArrayAppendValue(interfaceList
, interface
);
8360 CFRelease(interface
);
8366 CFRelease(ni_prefs
);
8367 return interfaceList
;
8373 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef ni_prefs
, CFArrayRef interfacesToSave
)
8377 if (!isA_CFArray(interfacesToSave
)) {
8381 if (ni_prefs
!= NULL
) {
8384 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8388 ok
= SCPreferencesSetValue(ni_prefs
, INTERFACES
, interfacesToSave
);
8389 CFRelease(ni_prefs
);
8394 SCNetworkInterfaceRef
8395 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8397 #pragma unused(allocator)
8399 SCNetworkInterfaceRef interface
= NULL
;
8401 /* initialize runtime */
8402 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8404 if (ni_prefs
!= NULL
) {
8407 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), INTERFACES_DEFAULT_CONFIG
);
8411 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8412 if (isA_CFArray(if_list
)) {
8413 CFIndex n
= CFArrayGetCount(if_list
);
8415 for (CFIndex i
= 0; i
< n
; i
++) {
8416 CFDictionaryRef dict
;
8417 CFStringRef tmp_bsdName
;
8419 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8420 if (!isA_CFDictionary(dict
)) {
8424 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8425 if (!isA_CFString(tmp_bsdName
)) {
8429 if (CFEqual(bsdName
, tmp_bsdName
)) {
8430 interface
= __SCNetworkInterfaceCreateWithStorageEntity(dict
);
8436 CFRelease(ni_prefs
);
8442 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8444 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8445 CFStringRef bsdName
= NULL
;
8446 SCNetworkInterfaceRef interface
= NULL
;
8449 count
= CFArrayGetCount(interfaces
);
8451 SC_log(LOG_INFO
, "No interfaces");
8454 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8456 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8457 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8459 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8460 if (!isA_CFString(bsdName
)) {
8461 SC_log(LOG_INFO
, "No BSD name");
8464 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8466 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8467 CFRelease(mappingBSDToInterface
);
8468 mappingBSDToInterface
= NULL
;
8469 SC_log(LOG_INFO
, "No mappings");
8472 return mappingBSDToInterface
;
8475 __private_extern__ Boolean
8476 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8478 CFStringRef intfSubtype
;
8480 if (entity
== NULL
) {
8484 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8485 #pragma GCC diagnostic push
8486 #pragma GCC diagnostic ignored "-Wdeprecated"
8487 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8490 #pragma GCC diagnostic pop