2 * Copyright (c) 2004-2017 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 <Availability.h>
37 #include <TargetConditionals.h>
38 #include <CoreFoundation/CoreFoundation.h>
39 #include <CoreFoundation/CFRuntime.h>
40 #include "SCNetworkConfigurationInternal.h"
41 #include "SCPreferencesInternal.h"
42 #include "SCHelper_client.h"
43 #include "plugin_shared.h"
46 #include <EAP8021X/EAPClientProperties.h>
47 #else // !TARGET_OS_IPHONE
48 #ifndef kEAPClientPropUserName
49 #define kEAPClientPropUserName CFSTR("UserName")
51 #ifndef kEAPClientPropUserPasswordKeychainItemID
52 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
54 #endif // !TARGET_OS_IPHONE
56 #include <IOKit/IOKitLib.h>
57 #include <IOKit/IOCFBundle.h>
58 #include <IOKit/IOBSD.h>
59 #include <IOKit/network/IONetworkController.h>
60 #include <IOKit/network/IONetworkInterface.h>
61 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
62 #include <IOKit/serial/IOSerialKeys.h>
63 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
64 #if !TARGET_OS_SIMULATOR
65 #include <IOKit/usb/IOUSBLib.h>
66 #endif // !TARGET_OS_SIMULATOR
68 #include "dy_framework.h"
70 #ifndef kPCIThunderboltString
71 #define kPCIThunderboltString "PCI-Thunderbolt"
74 #ifndef kIOUserEthernetInterfaceRoleKey
75 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
78 #ifndef kIOUSBHostInterfaceClassName
79 #define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
84 #include <mach/mach.h>
86 #include <net/if_types.h>
87 #include <net/if_dl.h>
88 #include <net/route.h>
89 #include <sys/ioctl.h>
90 #include <sys/param.h>
91 #include <sys/types.h>
92 #include <sys/socket.h>
94 #include <sys/sysctl.h>
99 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
100 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
101 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
102 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
103 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
104 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
105 static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName
, CFArrayRef matchingInterfaces
);
106 static Boolean
__SCNetworkInterfaceCacheIsOpen ();
107 static CFArrayRef
__SCNetworkInterfaceCacheCopy (CFStringRef bsdName
);
126 kSortBluetoothPAN_GN
,
127 kSortBluetoothPAN_NAP
,
137 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
138 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
139 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
140 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
141 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
142 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
143 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
144 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
145 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
146 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
147 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
148 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
149 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
150 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
151 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
152 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
153 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
154 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
156 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
158 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
159 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
160 .sort_order
= kSortUnknown
, // sort_order
163 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
165 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
166 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
167 .sort_order
= kSortUnknown
, // sort_order
170 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
172 static CFMutableSetRef vendor_interface_types
= NULL
;
174 // A thread-specific convenience cache of all interfaces matching a bsd name
175 // Key: CFStringRef (BSD name)
176 // Value: CFArrayRef (matching interfaces)
177 static __thread CFMutableDictionaryRef S_interface_cache
= NULL
;
180 #pragma mark SCNetworkInterface configuration details
189 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
194 #define doProxies 1<<4
195 #if !TARGET_OS_IPHONE
197 #else // !TARGET_OS_IPHONE
199 #endif // !TARGET_OS_IPHONE
201 static const struct {
202 const CFStringRef
*interface_type
;
203 const CFStringRef
*entity_hardware
;
204 Boolean per_interface_config
;
205 uint32_t supported_interfaces
;
206 const CFStringRef
*ppp_subtype
;
207 uint32_t supported_protocols
;
208 } configurations
[] = {
209 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
210 // ===================================== ==================== ========== =============== ======================================= =========================================
211 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
212 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
213 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
214 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
215 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
216 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
217 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
218 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
219 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
220 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
221 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
222 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
223 #pragma GCC diagnostic push
224 #pragma GCC diagnostic ignored "-Wdeprecated"
225 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
226 #pragma GCC diagnostic pop
227 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
228 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
229 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
230 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
231 // ===================================== =================== ========== =============== ======================================= =========================================
232 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
233 // ===================================== =================== ========== =============== ======================================= =========================================
234 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
238 #define kSCNetworkInterfaceActive "Active"
239 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
240 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
241 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
242 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
243 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
244 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
245 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
246 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
247 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
250 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
251 static CFBundleRef bundle
= NULL
;
254 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
257 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
259 "SCNetworkInterface", // className
262 __SCNetworkInterfaceDeallocate
, // dealloc
263 __SCNetworkInterfaceEqual
, // equal
264 __SCNetworkInterfaceHash
, // hash
265 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
266 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
270 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
271 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
272 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
275 static mach_port_t masterPort
= MACH_PORT_NULL
;
278 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
280 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
284 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
286 CFAllocatorRef allocator
= CFGetAllocator(cf
);
287 CFMutableStringRef result
;
288 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
290 result
= CFStringCreateMutable(allocator
, 0);
291 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
292 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
293 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
294 if (interfacePrivate
->entity_device_unique
!= NULL
) {
295 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
297 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
298 if (interfacePrivate
->entity_subtype
!= NULL
) {
299 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
301 if (interfacePrivate
->name
!= NULL
) {
302 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
304 if (interfacePrivate
->localized_name
!= NULL
) {
305 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
307 if (interfacePrivate
->localized_key
!= NULL
) {
308 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
309 if (interfacePrivate
->localized_arg1
!= NULL
) {
310 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
312 if (interfacePrivate
->localized_arg2
!= NULL
) {
313 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
317 if (interfacePrivate
->address
!= NULL
) {
322 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
324 data
= CFDataGetBytePtr(interfacePrivate
->address
);
325 dataLen
= CFDataGetLength(interfacePrivate
->address
);
326 for (i
= 0; i
< dataLen
; i
++) {
327 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
332 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
333 if (interfacePrivate
->hidden
) {
334 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
336 if (interfacePrivate
->location
!= NULL
) {
337 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
339 if (interfacePrivate
->path
!= NULL
) {
340 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
342 if (interfacePrivate
->entryID
!= 0) {
343 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
345 if (interfacePrivate
->type
!= NULL
) {
346 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
348 if (interfacePrivate
->unit
!= NULL
) {
349 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
351 if (interfacePrivate
->family
!= NULL
) {
352 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
354 if (interfacePrivate
->subfamily
!= NULL
) {
355 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
357 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
361 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
362 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
365 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
366 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
370 if (interfacePrivate
->usb
.name
!= NULL
) {
371 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
372 interfacePrivate
->usb
.name
);
375 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
379 if (interfacePrivate
->configurationAction
!= NULL
) {
380 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
382 if (interfacePrivate
->overrides
!= NULL
) {
383 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
385 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
386 if (interfacePrivate
->prefs
!= NULL
) {
387 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
389 if (interfacePrivate
->serviceID
!= NULL
) {
390 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
392 if (interfacePrivate
->interface
!= NULL
) {
393 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
395 if (interfacePrivate
->unsaved
!= NULL
) {
396 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
399 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
403 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
404 for (i
= 0; i
< n
; i
++) {
405 SCNetworkInterfaceRef member
;
407 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
408 CFStringAppendFormat(result
, NULL
,
410 (i
== 0) ? ", interfaces = " : ",",
411 SCNetworkInterfaceGetBSDName(member
));
414 if (interfacePrivate
->bond
.mode
!= NULL
) {
415 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
417 if (interfacePrivate
->bond
.options
!= NULL
) {
420 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
421 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
425 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
429 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
430 for (i
= 0; i
< n
; i
++) {
431 SCNetworkInterfaceRef member
;
433 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
434 CFStringAppendFormat(result
, NULL
,
436 (i
== 0) ? ", interfaces = " : ",",
437 SCNetworkInterfaceGetBSDName(member
));
440 if (interfacePrivate
->bridge
.options
!= NULL
) {
443 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
444 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
448 if (interfacePrivate
->vlan
.interface
!= NULL
) {
449 CFStringAppendFormat(result
, NULL
,
450 CFSTR(", interface = %@"),
451 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
453 if (interfacePrivate
->vlan
.tag
!= NULL
) {
454 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
456 if (interfacePrivate
->vlan
.options
!= NULL
) {
459 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
460 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
464 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
471 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
473 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
475 /* release resources */
477 if (interfacePrivate
->name
!= NULL
)
478 CFRelease(interfacePrivate
->name
);
480 if (interfacePrivate
->localized_name
!= NULL
)
481 CFRelease(interfacePrivate
->localized_name
);
483 if (interfacePrivate
->localized_arg1
!= NULL
)
484 CFRelease(interfacePrivate
->localized_arg1
);
486 if (interfacePrivate
->localized_arg2
!= NULL
)
487 CFRelease(interfacePrivate
->localized_arg2
);
489 if (interfacePrivate
->interface
!= NULL
)
490 CFRelease(interfacePrivate
->interface
);
492 if (interfacePrivate
->prefs
!= NULL
)
493 CFRelease(interfacePrivate
->prefs
);
495 if (interfacePrivate
->store
!= NULL
)
496 CFRelease(interfacePrivate
->store
);
498 if (interfacePrivate
->serviceID
!= NULL
)
499 CFRelease(interfacePrivate
->serviceID
);
501 if (interfacePrivate
->unsaved
!= NULL
)
502 CFRelease(interfacePrivate
->unsaved
);
504 if (interfacePrivate
->entity_device
!= NULL
)
505 CFRelease(interfacePrivate
->entity_device
);
507 if (interfacePrivate
->entity_device_unique
!= NULL
)
508 CFRelease(interfacePrivate
->entity_device_unique
);
510 if (interfacePrivate
->supported_interface_types
!= NULL
)
511 CFRelease(interfacePrivate
->supported_interface_types
);
513 if (interfacePrivate
->supported_protocol_types
!= NULL
)
514 CFRelease(interfacePrivate
->supported_protocol_types
);
516 if (interfacePrivate
->address
!= NULL
)
517 CFRelease(interfacePrivate
->address
);
519 if (interfacePrivate
->addressString
!= NULL
)
520 CFRelease(interfacePrivate
->addressString
);
522 if (interfacePrivate
->configurationAction
!= NULL
)
523 CFRelease(interfacePrivate
->configurationAction
);
525 if (interfacePrivate
->location
!= NULL
)
526 CFRelease(interfacePrivate
->location
);
528 if (interfacePrivate
->path
!= NULL
)
529 CFRelease(interfacePrivate
->path
);
531 if (interfacePrivate
->overrides
!= NULL
)
532 CFRelease(interfacePrivate
->overrides
);
534 if (interfacePrivate
->prefix
!= NULL
)
535 CFRelease(interfacePrivate
->prefix
);
537 if (interfacePrivate
->type
!= NULL
)
538 CFRelease(interfacePrivate
->type
);
540 if (interfacePrivate
->unit
!= NULL
)
541 CFRelease(interfacePrivate
->unit
);
543 if (interfacePrivate
->family
!= NULL
)
544 CFRelease(interfacePrivate
->family
);
546 if (interfacePrivate
->subfamily
!= NULL
)
547 CFRelease(interfacePrivate
->subfamily
);
549 if (interfacePrivate
->usb
.name
!= NULL
)
550 CFRelease(interfacePrivate
->usb
.name
);
552 if (interfacePrivate
->usb
.pid
!= NULL
)
553 CFRelease(interfacePrivate
->usb
.pid
);
555 if (interfacePrivate
->usb
.vid
!= NULL
)
556 CFRelease(interfacePrivate
->usb
.vid
);
558 if (interfacePrivate
->bond
.interfaces
!= NULL
)
559 CFRelease(interfacePrivate
->bond
.interfaces
);
561 if (interfacePrivate
->bond
.mode
!= NULL
)
562 CFRelease(interfacePrivate
->bond
.mode
);
564 if (interfacePrivate
->bond
.options
!= NULL
)
565 CFRelease(interfacePrivate
->bond
.options
);
567 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
568 CFRelease(interfacePrivate
->bridge
.interfaces
);
570 if (interfacePrivate
->bridge
.options
!= NULL
)
571 CFRelease(interfacePrivate
->bridge
.options
);
573 if (interfacePrivate
->vlan
.interface
!= NULL
)
574 CFRelease(interfacePrivate
->vlan
.interface
);
576 if (interfacePrivate
->vlan
.tag
!= NULL
)
577 CFRelease(interfacePrivate
->vlan
.tag
);
579 if (interfacePrivate
->vlan
.options
!= NULL
)
580 CFRelease(interfacePrivate
->vlan
.options
);
581 #if !TARGET_OS_SIMULATOR
582 if (interfacePrivate
->IPMonitorControl
!= NULL
)
583 CFRelease(interfacePrivate
->IPMonitorControl
);
584 #endif // !TARGET_OS_SIMULATOR
590 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
592 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
593 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
598 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
599 return FALSE
; // if not the same interface type
602 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
603 return FALSE
; // if not the same device
606 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
607 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
608 return FALSE
; // if not the same device unique identifier
610 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
614 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
615 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
616 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
617 return FALSE
; // if same device but not the same display name
621 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
622 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
623 return FALSE
; // if not the same interfaces
625 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
626 return FALSE
; // if not the same mode
630 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
631 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
632 return FALSE
; // if not the same interfaces
636 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
637 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
638 return FALSE
; // if not the same physical interface
640 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
641 return FALSE
; // if not the same tag
645 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
646 return FALSE
; // if not the same layering
654 __SCNetworkInterfaceHash(CFTypeRef cf
)
657 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
659 if (interfacePrivate
->entity_device
!= NULL
) {
660 if (interfacePrivate
->entity_device_unique
== NULL
) {
661 hash
= CFHash(interfacePrivate
->entity_device
);
665 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
666 interfacePrivate
->entity_device
,
667 interfacePrivate
->entity_device_unique
);
678 __SCNetworkInterfaceInitialize(void)
683 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
685 // initialize __kSCNetworkInterfaceIPv4
686 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
687 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
688 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
690 // initialize __kSCNetworkInterfaceLoopback
691 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
692 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
693 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
694 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
695 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
697 // get CFBundleRef for SystemConfiguration.framework
698 bundle
= _SC_CFBundleGet();
700 // get mach port used to communication with IOKit
701 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
702 if (kr
!= kIOReturnSuccess
) {
703 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
711 SCNetworkInterfacePrivateRef
712 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
713 SCNetworkInterfaceRef interface
,
714 SCPreferencesRef prefs
,
715 CFStringRef serviceID
)
717 SCNetworkInterfacePrivateRef interfacePrivate
;
720 /* initialize runtime */
721 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
723 /* allocate target */
724 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
725 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
726 __kSCNetworkInterfaceTypeID
,
729 if (interfacePrivate
== NULL
) {
733 /* initialize non-zero/NULL members */
734 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
735 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
736 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
737 interfacePrivate
->sort_order
= kSortUnknown
;
739 return interfacePrivate
;
745 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
749 struct if_msghdr
* ifm
;
750 char * if_name
= NULL
;
751 unsigned int if_index
;
753 Boolean vlanOK
= FALSE
;
755 // get the interface index
756 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
757 if (if_name
== NULL
) {
758 return FALSE
; // if conversion error
760 if_index
= if_nametoindex(if_name
);
762 goto done
; // if unknown interface
765 // get information for the specified interface
770 mib
[4] = NET_RT_IFLIST
;
771 mib
[5] = if_index
; /* ask for exactly one interface */
773 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
774 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
777 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
778 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
779 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
783 // check the link type and hwassist flags
784 // ALIGN: buf is aligned
785 ifm
= (struct if_msghdr
*)(void *)buf
;
786 switch (ifm
->ifm_type
) {
788 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
789 struct if_data
*if_data
= &ifm
->ifm_data
;
791 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
801 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
802 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
809 __SCCopyMacAddress(CFStringRef ifname
)
811 struct ifaddrs
*ifap
;
812 char ifname_c
[IFNAMSIZ
];
814 CFDataRef macAddress
= NULL
;
816 if(_SC_cfstring_to_cstring(ifname
,
819 kCFStringEncodingUTF8
) == NULL
) {
823 if (getifaddrs(&ifap
) == -1) {
825 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
829 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
830 struct sockaddr_dl
*sdl
;
832 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
836 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
837 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
838 if (sdl
->sdl_family
!= AF_LINK
) {
842 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
851 SCNetworkInterfacePrivateRef
852 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
855 SCNetworkInterfacePrivateRef interfacePrivate
;
857 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
858 if (interfacePrivate
== NULL
) {
862 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
863 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
864 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
865 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
866 interfacePrivate
->builtin
= TRUE
;
867 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
868 interfacePrivate
->sort_order
= kSortBond
;
870 interfacePrivate
->localized_key
= CFSTR("bond");
871 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
873 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
874 // interfacePrivate->bond.mode = NULL;
875 // interfacePrivate->bond.options = NULL;
877 return interfacePrivate
;
882 SCNetworkInterfacePrivateRef
883 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
884 CFStringRef bridge_if
)
886 SCNetworkInterfacePrivateRef interfacePrivate
;
888 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
889 if (interfacePrivate
== NULL
) {
893 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
894 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
895 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
896 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
897 interfacePrivate
->builtin
= TRUE
;
898 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
899 interfacePrivate
->sort_order
= kSortBridge
;
901 interfacePrivate
->localized_key
= CFSTR("bridge");
902 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
904 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
905 // interfacePrivate->bridge.options = NULL;
907 return interfacePrivate
;
912 SCNetworkInterfacePrivateRef
913 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
916 SCNetworkInterfacePrivateRef interfacePrivate
;
918 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
919 if (interfacePrivate
== NULL
) {
923 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
924 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
925 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
926 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
927 interfacePrivate
->builtin
= TRUE
;
928 interfacePrivate
->sort_order
= kSortVLAN
;
930 interfacePrivate
->localized_key
= CFSTR("vlan");
931 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
933 // interfacePrivate->vlan.interface = NULL;
934 // interfacePrivate->vlan.tag = NULL;
935 // interfacePrivate->vlan.options = NULL;
937 return interfacePrivate
;
942 #pragma mark Interface ordering
945 static CF_RETURNS_RETAINED CFArrayRef
946 split_path(CFStringRef path
)
948 CFArrayRef components
;
949 CFMutableStringRef nPath
;
951 // turn '@'s into '/'s
952 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
953 (void) CFStringFindAndReplace(nPath
,
956 CFRangeMake(0, CFStringGetLength(nPath
)),
959 // split path into components to be compared
960 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
968 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
970 #pragma unused(context)
971 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
972 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
973 CFComparisonResult res
= kCFCompareEqualTo
;
975 /* sort by interface type */
976 if (dev1
->sort_order
!= dev2
->sort_order
) {
977 if (dev1
->sort_order
< dev2
->sort_order
) {
978 res
= kCFCompareLessThan
;
980 res
= kCFCompareGreaterThan
;
985 /* built-in interfaces sort first */
986 if (dev1
->builtin
!= dev2
->builtin
) {
988 res
= kCFCompareLessThan
;
990 res
= kCFCompareGreaterThan
;
995 /* ... and then, sort built-in interfaces by "location" */
997 if (dev1
->location
!= dev2
->location
) {
998 if (isA_CFString(dev1
->location
)) {
999 if (isA_CFString(dev2
->location
)) {
1000 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1002 res
= kCFCompareLessThan
;
1005 res
= kCFCompareGreaterThan
;
1008 if (res
!= kCFCompareEqualTo
) {
1014 /* ... and, then sort by IOPathMatch */
1015 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1016 CFArrayRef elements1
;
1017 CFArrayRef elements2
;
1023 elements1
= split_path(dev1
->path
);
1024 n1
= CFArrayGetCount(elements1
);
1026 elements2
= split_path(dev2
->path
);
1027 n2
= CFArrayGetCount(elements2
);
1029 n
= (n1
<= n2
) ? n1
: n2
;
1030 for (i
= 0; i
< n
; i
++) {
1039 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1040 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1042 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1044 q1
= strtoq(str
, &end
, 16);
1045 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1046 CFAllocatorDeallocate(NULL
, str
);
1049 // if e1 is a valid numeric string
1050 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1052 q2
= strtoq(str
, &end
, 16);
1053 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1054 CFAllocatorDeallocate(NULL
, str
);
1057 // if e2 is also a valid numeric string
1060 res
= kCFCompareEqualTo
;
1062 } else if (q1
< q2
) {
1063 res
= kCFCompareLessThan
;
1065 res
= kCFCompareGreaterThan
;
1071 res
= CFStringCompare(e1
, e2
, 0);
1072 if (res
!= kCFCompareEqualTo
) {
1077 if (res
== kCFCompareEqualTo
) {
1079 res
= kCFCompareLessThan
;
1080 } else if (n1
< n2
) {
1081 res
= kCFCompareGreaterThan
;
1085 CFRelease(elements1
);
1086 CFRelease(elements2
);
1088 if (res
!= kCFCompareEqualTo
) {
1093 /* ... and, then sort by BSD interface name */
1094 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1095 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1096 if (res
!= kCFCompareEqualTo
) {
1101 /* ... and lastly, sort by BSD interface unique identifier */
1102 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1103 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1104 // if (res != kCFCompareEqualTo) {
1114 sort_interfaces(CFMutableArrayRef all_interfaces
)
1118 n
= CFArrayGetCount(all_interfaces
);
1123 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1130 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1132 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1134 return interfacePrivate
->sort_order
;
1139 #pragma mark Interface details
1143 IOCopyCFStringValue(CFTypeRef ioVal
)
1145 if (isA_CFString(ioVal
)) {
1146 return CFStringCreateCopy(NULL
, ioVal
);
1149 if (isA_CFData(ioVal
)) {
1150 return CFStringCreateWithCString(NULL
,
1151 (const char *)CFDataGetBytePtr(ioVal
),
1152 kCFStringEncodingUTF8
);
1160 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1162 CFStringRef if_bsdName
;
1163 CFStringRef if_prefix
;
1164 CFNumberRef if_unit
;
1166 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1167 if (if_bsdName
!= NULL
) {
1168 return IOCopyCFStringValue(if_bsdName
);
1171 // no BSD name, get interface prefix and unit
1172 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1173 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1174 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1175 // if both prefix and unit available, construct BSD name
1176 if_bsdName
= CFStringCreateWithFormat(NULL
,
1188 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1192 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1193 return IOCopyCFStringValue(ioVal
);
1198 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1200 Boolean match
= FALSE
;
1201 CFIndex prefixLen
= CFStringGetLength(prefix
);
1202 CFStringRef str
= NULL
;
1204 if (!isA_CFString(ioVal
)) {
1205 if (isA_CFData(ioVal
)) {
1206 str
= CFStringCreateWithCStringNoCopy(NULL
,
1207 (const char *)CFDataGetBytePtr(ioVal
),
1208 kCFStringEncodingUTF8
,
1216 if ((ioVal
!= NULL
) &&
1217 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1218 (CFStringCompareWithOptions(ioVal
,
1220 CFRangeMake(0, prefixLen
),
1221 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1225 if (str
!= NULL
) CFRelease(str
);
1230 static const struct {
1231 const CFStringRef name
;
1232 const CFStringRef slot
;
1233 } slot_mappings
[] = {
1235 { CFSTR("A1") , CFSTR("1") },
1236 { CFSTR("B1") , CFSTR("2") },
1237 { CFSTR("C1") , CFSTR("3") },
1239 // Blue&White G3, Yikes G4
1240 { CFSTR("J12"), CFSTR("1") },
1241 { CFSTR("J11"), CFSTR("2") },
1242 { CFSTR("J10"), CFSTR("3") },
1243 { CFSTR("J9"), CFSTR("4") },
1246 { CFSTR("A") , CFSTR("1") },
1247 { CFSTR("B") , CFSTR("2") },
1248 { CFSTR("C") , CFSTR("3") },
1249 { CFSTR("D") , CFSTR("4") },
1251 // Digital Audio G4 (and later models)
1252 { CFSTR("1") , CFSTR("1") },
1253 { CFSTR("2") , CFSTR("2") },
1254 { CFSTR("3") , CFSTR("3") },
1255 { CFSTR("4") , CFSTR("4") },
1256 { CFSTR("5") , CFSTR("5") }
1260 static const CFStringRef slot_prefixes
[] = {
1261 CFSTR("thunderbolt slot "),
1267 static CF_RETURNS_RETAINED CFStringRef
1268 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1271 io_registry_entry_t parent
;
1272 CFMutableStringRef slot
;
1273 CFTypeRef slot_name
;
1276 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1278 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1279 if (slot_name
!= NULL
) {
1280 slot
= CFStringCreateMutable(NULL
, 0);
1281 if (isA_CFString(slot_name
)) {
1282 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1283 CFStringAppend(slot
, slot_name
);
1284 } else if (isA_CFData(slot_name
)) {
1285 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1286 CFStringAppendCString(slot
,
1287 (const char *)CFDataGetBytePtr(slot_name
),
1288 kCFStringEncodingUTF8
);
1291 for (size_t i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1294 len
= CFStringGetLength(slot_prefixes
[i
]);
1295 if (CFStringGetLength(slot
) > len
) {
1296 (void) CFStringFindAndReplace(slot
,
1299 CFRangeMake(0, len
),
1300 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1304 for (size_t i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1305 if (CFStringCompare(slot
,
1306 slot_mappings
[i
].name
,
1307 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1309 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1314 CFRelease(slot_name
);
1317 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1319 case kIOReturnSuccess
: {
1320 CFTypeRef parent_pci_slot_name
= NULL
;
1321 CFStringRef parent_slot
;
1323 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1324 if (parent_slot
!= NULL
) {
1325 if (slot
!= NULL
) CFRelease(slot
);
1326 slot
= (CFMutableStringRef
)parent_slot
;
1328 if (pci_slot_name
!= NULL
) {
1329 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1330 *pci_slot_name
= parent_pci_slot_name
;
1332 CFRelease(parent_pci_slot_name
);
1336 IOObjectRelease(parent
);
1339 case kIOReturnNoDevice
:
1340 // if we have hit the root node
1343 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1351 static CFComparisonResult
1352 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1354 #pragma unused(context)
1355 CFStringRef bsd1
= (CFStringRef
)val1
;
1356 CFStringRef bsd2
= (CFStringRef
)val2
;
1358 return CFStringCompare(bsd1
, bsd2
, 0);
1362 static CF_RETURNS_RETAINED CFStringRef
1363 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1366 CFStringRef port_name
= NULL
;
1367 CFMutableArrayRef port_names
;
1370 CFStringRef match_keys
[2];
1371 CFTypeRef match_vals
[2];
1372 CFDictionaryRef match_dict
;
1373 CFDictionaryRef matching
;
1374 io_registry_entry_t slot
;
1375 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1377 match_keys
[0] = CFSTR("AAPL,slot-name");
1378 match_vals
[0] = slot_name
;
1380 match_dict
= CFDictionaryCreate(NULL
,
1381 (const void **)match_keys
,
1382 (const void **)match_vals
,
1384 &kCFTypeDictionaryKeyCallBacks
,
1385 &kCFTypeDictionaryValueCallBacks
);
1387 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1388 match_vals
[0] = CFSTR("IOPCIDevice");
1390 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1391 match_vals
[1] = match_dict
;
1393 // note: the "matching" dictionary will be consumed by the following
1394 matching
= CFDictionaryCreate(NULL
,
1395 (const void **)match_keys
,
1396 (const void **)match_vals
,
1397 sizeof(match_keys
)/sizeof(match_keys
[0]),
1398 &kCFTypeDictionaryKeyCallBacks
,
1399 &kCFTypeDictionaryValueCallBacks
);
1400 CFRelease(match_dict
);
1402 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1403 if (kr
!= kIOReturnSuccess
) {
1404 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1405 return MACH_PORT_NULL
;
1408 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1410 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1411 io_registry_entry_t child
;
1412 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1414 kr
= IORegistryEntryCreateIterator(slot
,
1416 kIORegistryIterateRecursively
,
1418 if (kr
!= kIOReturnSuccess
) {
1419 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1420 CFRelease(port_names
);
1421 return MACH_PORT_NULL
;
1424 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1425 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1426 CFMutableDictionaryRef interface_dict
= NULL
;
1428 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1429 if (interface_dict
!= NULL
) {
1430 CFNumberRef child_if_type
;
1431 int child_ift
= ift
;
1433 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1434 if (child_if_type
!= NULL
) {
1435 if (!isA_CFNumber(child_if_type
) ||
1436 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1437 // assume that it's a match
1442 if (ift
== child_ift
) {
1443 CFStringRef if_bsdName
;
1445 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1446 if (if_bsdName
!= NULL
) {
1447 CFArrayAppendValue(port_names
, if_bsdName
);
1448 CFRelease(if_bsdName
);
1452 CFRelease(interface_dict
);
1455 IOObjectRelease(child
);
1457 IOObjectRelease(child_iterator
);
1458 IOObjectRelease(slot
);
1460 IOObjectRelease(slot_iterator
);
1462 n
= CFArrayGetCount(port_names
);
1464 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1465 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1466 if (n
!= kCFNotFound
) {
1467 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1471 CFRelease(port_names
);
1477 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1479 CFStringRef bsd_name
= NULL
;
1480 CFMutableDictionaryRef interface_dict
= NULL
;
1482 CFTypeRef pci_slot_name
;
1487 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1488 if (interface_dict
!= NULL
) {
1489 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1490 CFRelease(interface_dict
);
1493 if (bsd_name
== NULL
) {
1497 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1498 if (*slot_name
!= NULL
) {
1499 if (pci_slot_name
!= NULL
) {
1500 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1501 CFRelease(pci_slot_name
);
1506 CFRelease(bsd_name
);
1512 isBuiltin(io_registry_entry_t interface
)
1516 slot
= pci_slot(interface
, NULL
);
1518 // interfaces which have a "slot" are not built-in
1528 isBluetoothBuiltin(Boolean
*haveController
)
1530 Boolean builtin
= FALSE
;
1531 io_object_t hciController
;
1532 io_iterator_t iter
= MACH_PORT_NULL
;
1535 kr
= IOServiceGetMatchingServices(masterPort
,
1536 IOServiceMatching("IOBluetoothHCIController"),
1538 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1539 if (kr
!= kIOReturnSuccess
) {
1540 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1542 *haveController
= FALSE
;
1545 *haveController
= TRUE
;
1547 hciController
= IOIteratorNext(iter
);
1548 IOObjectRelease(iter
);
1549 if(hciController
!= MACH_PORT_NULL
) {
1550 #if !TARGET_OS_SIMULATOR
1551 CFNumberRef idVendor
;
1553 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1554 if (idVendor
!= NULL
) {
1557 if (isA_CFNumber(idVendor
) &&
1558 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1559 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1563 CFRelease(idVendor
);
1565 #endif // !TARGET_OS_SIMULATOR
1567 IOObjectRelease(hciController
);
1575 isThunderbolt(io_registry_entry_t interface
)
1579 val
= IORegistryEntrySearchCFProperty(interface
,
1581 CFSTR(kPCIThunderboltString
),
1583 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1594 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1595 io_registry_entry_t interface
,
1596 CFDictionaryRef interface_dict
,
1597 io_registry_entry_t controller
,
1598 CFDictionaryRef controller_dict
,
1599 io_registry_entry_t bus
,
1600 CFDictionaryRef bus_dict
)
1602 #if TARGET_OS_SIMULATOR
1603 #pragma unused(interfacePrivate)
1604 #pragma unused(interface)
1605 #endif // TARGET_OS_SIMULATOR
1606 #pragma unused(interface_dict)
1607 #pragma unused(controller)
1608 #pragma unused(controller_dict)
1610 #pragma unused(bus_dict)
1611 #if !TARGET_OS_SIMULATOR
1613 if (interfacePrivate
->usb
.name
== NULL
) {
1614 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1616 CFSTR(kUSBProductString
),
1618 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1620 if (interfacePrivate
->usb
.vid
== NULL
) {
1621 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1623 CFSTR(kUSBVendorID
),
1625 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1627 if (interfacePrivate
->usb
.pid
== NULL
) {
1628 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1630 CFSTR(kUSBProductID
),
1632 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1634 #endif // !TARGET_OS_SIMULATOR
1641 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1642 io_registry_entry_t interface
,
1645 Boolean updated
= FALSE
;
1648 // check if a "Product Name" has been provided
1649 val
= IORegistryEntrySearchCFProperty(interface
,
1651 CFSTR(kIOPropertyProductNameKey
),
1653 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1654 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1655 // else, use "USB Product Name" if available
1656 val
= CFRetain(interfacePrivate
->usb
.name
);
1659 CFStringRef productName
;
1661 productName
= IOCopyCFStringValue(val
);
1664 if (productName
!= NULL
) {
1665 if (CFStringGetLength(productName
) > 0) {
1666 // if we have a [somewhat reasonable?] product name
1667 if (interfacePrivate
->name
!= NULL
) {
1668 CFRelease(interfacePrivate
->name
);
1670 interfacePrivate
->name
= CFRetain(productName
);
1671 if (interfacePrivate
->localized_name
!= NULL
) {
1672 CFRelease(interfacePrivate
->localized_name
);
1673 interfacePrivate
->localized_name
= NULL
;
1675 if (bundle
!= NULL
) {
1676 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1682 CFRelease(productName
);
1691 #pragma mark Interface enumeration
1694 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1695 io_registry_entry_t interface
,
1696 CFDictionaryRef interface_dict
,
1697 io_registry_entry_t controller
,
1698 CFDictionaryRef controller_dict
,
1699 io_registry_entry_t bus
,
1700 CFDictionaryRef bus_dict
);
1704 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1705 io_registry_entry_t interface
,
1706 CFStringRef override
)
1711 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1712 val
= IORegistryEntrySearchCFProperty(interface
,
1716 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1719 if (isA_CFDictionary(val
)) {
1720 if (interfacePrivate
->overrides
== NULL
) {
1721 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1723 &kCFTypeDictionaryKeyCallBacks
,
1724 &kCFTypeDictionaryValueCallBacks
);
1726 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1736 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1737 io_registry_entry_t interface
,
1738 CFDictionaryRef interface_dict
,
1739 io_registry_entry_t controller
,
1740 CFDictionaryRef controller_dict
,
1741 io_registry_entry_t bus
,
1742 CFDictionaryRef bus_dict
)
1752 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1753 if (isA_CFNumber(num
) &&
1754 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1755 interfacePrivate
->type
= CFRetain(num
);
1757 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1765 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1766 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1767 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1768 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1769 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1770 interfacePrivate
->sort_order
= kSortAirPort
;
1771 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1772 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1773 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1774 interfacePrivate
->sort_order
= kSortThunderbolt
;
1775 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1776 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1777 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1778 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1779 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1780 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1781 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1782 interfacePrivate
->sort_order
= kSortTethered
;
1783 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1784 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1785 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1786 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1789 if (interfacePrivate
->interface_type
== NULL
) {
1790 val
= IORegistryEntrySearchCFProperty(interface
,
1792 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1794 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1796 if (isA_CFString(val
)) {
1797 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1798 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1799 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1800 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1801 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1802 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1803 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1804 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1805 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1806 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1807 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1808 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1816 if (interfacePrivate
->interface_type
== NULL
) {
1817 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1819 if (CFEqual(str
, CFSTR("radio"))) {
1820 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1821 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1822 interfacePrivate
->sort_order
= kSortOtherWireless
;
1829 if (interfacePrivate
->interface_type
== NULL
) {
1830 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1831 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1832 interfacePrivate
->sort_order
= kSortEthernet
;
1834 // BOND support only enabled for ethernet devices
1835 interfacePrivate
->supportsBond
= TRUE
;
1838 // enable Bridge support
1839 interfacePrivate
->supportsBridge
= TRUE
;
1842 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1844 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1847 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1849 interfacePrivate
->builtin
= isBuiltin(interface
);
1852 if (!interfacePrivate
->builtin
&&
1853 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1854 // always treat AirPort interfaces as built-in
1855 interfacePrivate
->builtin
= TRUE
;
1859 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1860 if ((interfacePrivate
->location
!= NULL
) &&
1861 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1862 CFRelease(interfacePrivate
->location
);
1863 interfacePrivate
->location
= NULL
;
1867 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1868 if (isA_CFNumber(num
) &&
1869 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1870 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1871 interfacePrivate
->supportsVLAN
= TRUE
;
1876 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1877 interfacePrivate
->localized_key
= CFSTR("airport");
1878 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1879 if ((interfacePrivate
->location
== NULL
) ||
1880 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1881 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1883 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1884 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1886 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1887 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1888 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1889 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1890 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1891 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1892 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1893 interfacePrivate
->localized_key
= CFSTR("wireless");
1894 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1895 } else if (interfacePrivate
->builtin
) {
1896 if ((interfacePrivate
->location
== NULL
) ||
1897 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1898 interfacePrivate
->localized_key
= CFSTR("ether");
1900 interfacePrivate
->localized_key
= CFSTR("multiether");
1901 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1904 CFStringRef provider
;
1906 // check provider class
1907 provider
= IORegistryEntrySearchCFProperty(interface
,
1909 CFSTR(kIOProviderClassKey
),
1911 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1912 if (provider
!= NULL
) {
1913 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1914 CFStringRef port_name
;
1915 CFStringRef slot_name
;
1917 // set interface "name"
1918 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1919 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1920 if (isThunderbolt(interface
)) {
1921 if (port_name
== NULL
) {
1922 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1923 interfacePrivate
->localized_arg1
= slot_name
;
1925 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1926 interfacePrivate
->localized_arg1
= slot_name
;
1927 interfacePrivate
->localized_arg2
= port_name
;
1931 if (port_name
== NULL
) {
1932 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1933 interfacePrivate
->localized_arg1
= slot_name
;
1935 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1936 interfacePrivate
->localized_arg1
= slot_name
;
1937 interfacePrivate
->localized_arg2
= port_name
;
1942 io_registry_entry_t node
= interface
;
1944 while (provider
!= NULL
) {
1945 #if !TARGET_OS_SIMULATOR
1946 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
1947 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
1948 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
))) {
1949 // get USB info (if available)
1950 processUSBInterface(interfacePrivate
,
1958 // set interface "name"
1959 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1960 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1961 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1965 #endif // !TARGET_OS_SIMULATOR
1967 if (node
== interface
) {
1969 } else if (node
== controller
) {
1975 CFRelease(provider
);
1976 provider
= IORegistryEntrySearchCFProperty(node
,
1978 CFSTR(kIOProviderClassKey
),
1980 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1983 if (interfacePrivate
->localized_key
== NULL
) {
1984 update_interface_name(interfacePrivate
, interface
, FALSE
);
1988 if (provider
!= NULL
) CFRelease(provider
);
1991 if (interfacePrivate
->localized_key
== NULL
) {
1992 // if no provider, not a PCI device, or no slot information
1993 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1994 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2001 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2004 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2007 interfacePrivate
->builtin
= isBuiltin(interface
);
2010 interfacePrivate
->sort_order
= kSortFireWire
;
2013 if (interfacePrivate
->builtin
) {
2014 interfacePrivate
->localized_key
= CFSTR("firewire");
2016 CFStringRef port_name
;
2017 CFStringRef slot_name
;
2019 // set interface "name"
2020 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2021 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2022 if (isThunderbolt(interface
)) {
2023 if (port_name
== NULL
) {
2024 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2025 interfacePrivate
->localized_arg1
= slot_name
;
2027 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2028 interfacePrivate
->localized_arg1
= slot_name
;
2029 interfacePrivate
->localized_arg2
= port_name
;
2032 if (port_name
== NULL
) {
2033 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2034 interfacePrivate
->localized_arg1
= slot_name
;
2036 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2037 interfacePrivate
->localized_arg1
= slot_name
;
2038 interfacePrivate
->localized_arg2
= port_name
;
2046 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2051 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2053 // Hardware (MAC) address
2054 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2055 if (isA_CFData(data
)) {
2056 interfacePrivate
->address
= CFRetain(data
);
2060 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2061 if (isA_CFString(str
)) {
2062 interfacePrivate
->prefix
= CFRetain(str
);
2066 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2067 if (isA_CFNumber(num
) &&
2068 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2069 interfacePrivate
->unit
= CFRetain(num
);
2072 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2073 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2080 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2082 CFDictionaryRef dict
;
2083 CFMutableDictionaryRef newDict
;
2085 if (interfacePrivate
->overrides
== NULL
) {
2086 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2088 &kCFTypeDictionaryKeyCallBacks
,
2089 &kCFTypeDictionaryValueCallBacks
);
2092 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2094 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2096 newDict
= CFDictionaryCreateMutable(NULL
,
2098 &kCFTypeDictionaryKeyCallBacks
,
2099 &kCFTypeDictionaryValueCallBacks
);
2101 if (script
!= NULL
) {
2102 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2104 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2106 if (CFDictionaryGetCount(newDict
) > 0) {
2107 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2109 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2113 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2114 CFRelease(interfacePrivate
->overrides
);
2115 interfacePrivate
->overrides
= NULL
;
2122 is_valid_connection_script(CFStringRef script
)
2124 char ccl
[MAXPATHLEN
];
2125 char path
[MAXPATHLEN
];
2126 sysdir_search_path_enumeration_state state
;
2128 (void) _SC_cfstring_to_cstring(script
,
2131 kCFStringEncodingUTF8
);
2133 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2134 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2135 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2137 struct stat statBuf
;
2139 if (ccl
[0] == '/') {
2140 path
[0] = '\0'; // if modemCCL is a full path
2142 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2144 strlcat(path
, ccl
, sizeof(path
));
2146 if (stat(path
, &statBuf
) != 0) {
2147 if (errno
== ENOENT
) {
2151 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2154 if (S_ISREG(statBuf
.st_mode
)) {
2155 // if we have a valid CCL script
2159 #define BUNDLE_EXT ".ccl"
2160 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2165 if ((n
<= BUNDLE_EXT_LEN
) ||
2166 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2167 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2168 if (stat(path
, &statBuf
) != 0) {
2169 if (errno
== ENOENT
) {
2173 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2177 if (S_ISDIR(statBuf
.st_mode
)) {
2178 // if we have a valid CCL bundle
2188 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2189 io_registry_entry_t interface
,
2190 CFDictionaryRef interface_dict
,
2191 io_registry_entry_t controller
,
2192 CFDictionaryRef controller_dict
,
2193 io_registry_entry_t bus
,
2194 CFDictionaryRef bus_dict
)
2196 CFStringRef base
= NULL
;
2198 Boolean isModem
= FALSE
;
2199 Boolean isWWAN
= FALSE
;
2200 CFStringRef modemCCL
= NULL
;
2204 // check if initializing
2205 val
= IORegistryEntrySearchCFProperty(interface
,
2207 kSCNetworkInterfaceInitializingKey
,
2209 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2211 Boolean initializing
;
2213 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2216 return FALSE
; // if this interface is still initializing
2221 val
= IORegistryEntrySearchCFProperty(interface
,
2225 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2227 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2232 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2233 if (interfacePrivate
->entity_device
== NULL
) {
2237 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2239 base
= CFRetain(interfacePrivate
->entity_device
);
2245 * Exclude ports named "irda" because otherwise the IrDA ports on the
2246 * original iMac (rev's A through D) show up as serial ports. Given
2247 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2248 * even support it, these ports definitely shouldn't be listed.
2250 if (CFStringCompare(base
,
2252 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2256 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2257 Boolean haveController
= FALSE
;
2260 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2261 interfacePrivate
->sort_order
= kSortBluetooth
;
2262 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2263 if (!haveController
) {
2264 // if device with no controller present
2267 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2269 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2270 interfacePrivate
->sort_order
= kSortIrDA
;
2271 } else if (isWWAN
) {
2273 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2274 interfacePrivate
->sort_order
= kSortWWAN
;
2277 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2278 interfacePrivate
->sort_order
= kSortModem
;
2282 interfacePrivate
->entity_type
= kSCEntNetModem
;
2284 // Entity (Hardware)
2285 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2286 if (!isA_CFString(ift
)) {
2290 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2294 if (CFEqual(base
, CFSTR("modem"))) {
2295 interfacePrivate
->builtin
= TRUE
;
2296 interfacePrivate
->sort_order
= kSortInternalModem
;
2297 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2298 interfacePrivate
->sort_order
= kSortUSBModem
;
2300 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2302 interfacePrivate
->sort_order
= kSortSerialPort
;
2307 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2308 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2310 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2311 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2313 // look for modem CCL, unique identifier
2314 if (interfacePrivate
->overrides
!= NULL
) {
2315 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2317 CFStringRef uniqueID
;
2319 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2320 modemCCL
= isA_CFString(modemCCL
);
2322 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2323 uniqueID
= isA_CFString(uniqueID
);
2324 if (uniqueID
!= NULL
) {
2325 // retain the device's base name and the unique id
2326 CFRelease(interfacePrivate
->entity_device
);
2327 interfacePrivate
->entity_device
= CFRetain(base
);
2328 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2333 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2334 // a bit harder for the modem CCL
2335 if (modemCCL
== NULL
) {
2336 val
= IORegistryEntrySearchCFProperty(interface
,
2340 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2342 modemCCL
= IOCopyCFStringValue(val
);
2343 if (modemCCL
!= NULL
) {
2344 set_connection_script(interfacePrivate
, modemCCL
);
2345 CFRelease(modemCCL
);
2353 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2354 interfacePrivate
->localized_key
= CFSTR("irda");
2355 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2356 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2358 CFStringRef localized
= NULL
;
2359 CFStringRef name
= NULL
;
2360 CFMutableStringRef port
;
2362 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2363 CFStringLowercase(port
, NULL
);
2366 CFStringAppend(port
, CFSTR("-port"));
2369 // set non-localized name
2370 if (bundle
!= NULL
) {
2371 name
= copy_interface_string(bundle
, port
, FALSE
);
2374 if (!CFEqual(port
, name
)) {
2375 // if [English] localization available
2376 interfacePrivate
->name
= name
;
2378 // if no [English] localization available, use TTY base name
2380 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2383 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2386 // set localized name
2387 if (bundle
!= NULL
) {
2388 localized
= copy_interface_string(bundle
, port
, TRUE
);
2390 if (localized
!= NULL
) {
2391 if (!CFEqual(port
, localized
)) {
2392 // if localization available
2393 interfacePrivate
->localized_name
= localized
;
2395 // if no localization available, use TTY base name
2396 CFRelease(localized
);
2397 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2400 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2403 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2404 // get USB info (if available)
2405 processUSBInterface(interfacePrivate
,
2413 // set interface "name"
2414 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2415 // if "ModemCCL" not provided, also check if the product/interface
2416 // name matches a CCL script
2417 if ((modemCCL
== NULL
) &&
2418 is_valid_connection_script(interfacePrivate
->name
)) {
2419 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2431 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2432 CFRelease(interfacePrivate
->entity_device
);
2433 interfacePrivate
->entity_device
= NULL
;
2435 if (base
!= NULL
) CFRelease(base
);
2442 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2445 * Create a path for a registry entry.
2449 CFStringRef str
= NULL
;
2451 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2452 if (status
== kIOReturnSuccess
) {
2453 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2454 } else if (status
== kIOReturnBadArgument
) {
2455 io_registry_entry_t parent
;
2457 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2458 if (status
== kIOReturnSuccess
) {
2459 CFStringRef str_parent
;
2461 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2462 if (str_parent
!= NULL
) {
2465 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2466 if (status
== kIOReturnSuccess
) {
2469 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2470 if (status
== kIOReturnSuccess
) {
2471 str
= CFStringCreateWithFormat(NULL
,
2478 str
= CFStringCreateWithFormat(NULL
,
2486 CFRelease(str_parent
);
2489 IOObjectRelease(parent
);
2496 static CFMutableDictionaryRef
2497 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2500 CFMutableDictionaryRef reg_dict
= NULL
;
2501 CFTypeRef value
= NULL
;
2503 reg_dict
= CFDictionaryCreateMutable(NULL
,
2505 &kCFTypeDictionaryKeyCallBacks
,
2506 &kCFTypeDictionaryValueCallBacks
);
2508 for (; idx
< numKeys
; idx
++) {
2509 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2510 if (value
!= NULL
) {
2511 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2519 static SCNetworkInterfaceRef
2520 createInterface(io_registry_entry_t interface
, processInterface func
,
2521 CFStringRef hidden_key
)
2523 io_registry_entry_t bus
= MACH_PORT_NULL
;
2524 CFMutableDictionaryRef bus_dict
= NULL
;
2525 io_registry_entry_t controller
= MACH_PORT_NULL
;
2526 CFMutableDictionaryRef controller_dict
= NULL
;
2527 uint64_t entryID
= 0;
2528 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2529 CFMutableDictionaryRef interface_dict
= NULL
;
2534 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2536 const CFStringRef interface_dict_keys
[] = {
2537 CFSTR(kIOInterfaceType
),
2539 CFSTR(kIOBSDNameKey
),
2540 CFSTR(kIOPrimaryInterface
),
2541 CFSTR(kIOInterfaceNamePrefix
),
2542 CFSTR(kIOInterfaceUnit
),
2543 CFSTR(kIOTTYDeviceKey
),
2544 CFSTR(kIOTTYBaseNameKey
),
2545 CFSTR(kIOSerialBSDTypeKey
),
2548 #endif // !TARGET_OS_SIMULATOR
2550 const CFStringRef controller_dict_keys
[] = {
2552 CFSTR(kIOMACAddress
)
2555 const CFStringRef bus_dict_keys
[] = {
2559 if (hidden_key
!= NULL
) {
2561 val
= IORegistryEntrySearchCFProperty(interface
,
2565 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2568 goto done
; // if this interface should not be exposed
2572 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2573 // get the dictionary associated with the [interface] node
2574 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2575 if (kr
!= kIOReturnSuccess
) {
2576 SC_log(LOG_INFO
, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr
);
2580 interface_dict
= copyIORegistryProperties(interface
,
2581 interface_dict_keys
,
2582 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2583 #endif // !TARGET_OS_SIMULATOR
2585 // get the controller node
2586 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2587 if (kr
!= kIOReturnSuccess
) {
2588 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2592 controller_dict
= copyIORegistryProperties(controller
,
2593 controller_dict_keys
,
2594 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2597 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2598 if (kr
!= kIOReturnSuccess
) {
2599 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2603 bus_dict
= copyIORegistryProperties(bus
,
2605 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2607 // get the registry entry ID
2608 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2609 if (kr
!= kIOReturnSuccess
) {
2610 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2614 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2615 assert(interfacePrivate
!= NULL
);
2616 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2617 interfacePrivate
->entryID
= entryID
;
2619 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2620 val
= IORegistryEntrySearchCFProperty(interface
,
2622 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2624 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2626 if (isA_CFDictionary(val
)) {
2627 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2632 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2633 // get user-notification / auto-configuration preference
2634 val
= IORegistryEntrySearchCFProperty(interface
,
2636 kSCNetworkInterfaceConfigurationActionKey
,
2638 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2640 if (isA_CFString(val
)) {
2641 interfacePrivate
->configurationAction
= CFRetain(val
);
2646 // get HiddenConfiguration preference
2647 val
= IORegistryEntrySearchCFProperty(interface
,
2649 kSCNetworkInterfaceHiddenConfigurationKey
,
2651 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2653 interfacePrivate
->hidden
= TRUE
;
2657 CFRelease(interfacePrivate
);
2658 interfacePrivate
= NULL
;
2663 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2665 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2666 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2668 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2669 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2671 return (SCNetworkInterfaceRef
)interfacePrivate
;
2675 static CF_RETURNS_RETAINED CFArrayRef
2676 findMatchingInterfaces(CFDictionaryRef matching
,
2677 processInterface func
,
2678 CFStringRef hidden_key
,
2679 Boolean keep_pre_configured
)
2681 CFMutableArrayRef interfaces
;
2682 io_registry_entry_t interface
;
2684 io_iterator_t iterator
= MACH_PORT_NULL
;
2687 * A reference to the "matching" dictionary will be consumed by the
2688 * the call to IOServiceGetMatchingServices so we bump up the retain
2693 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2694 if (kr
!= kIOReturnSuccess
) {
2695 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2699 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2701 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2702 SCNetworkInterfaceRef match
;
2704 match
= createInterface(interface
, func
, hidden_key
);
2705 if (match
!= NULL
) {
2706 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2707 CFArrayAppendValue(interfaces
, match
);
2712 IOObjectRelease(interface
);
2715 IOObjectRelease(iterator
);
2722 #pragma mark helper functions
2726 findConfiguration(CFStringRef interface_type
)
2728 for (size_t i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2729 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2740 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2742 CFIndex interfaceIndex
;
2743 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2745 if (interfacePrivate
->serviceID
== NULL
) {
2746 // if not associated with a service (yet)
2747 _SCErrorSet(kSCStatusInvalidArgument
);
2751 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2752 if (interfaceIndex
== kCFNotFound
) {
2753 // unknown interface type, use per-service configuration preferences
2754 return interfacePrivate
->interface_type
; // entity
2757 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2758 // if configuration information can be associated with this interface type
2759 return *configurations
[interfaceIndex
].entity_hardware
;
2762 _SCErrorSet(kSCStatusInvalidArgument
);
2769 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2770 CFStringRef extendedType
,
2771 Boolean requirePerInterface
)
2773 CFStringRef defaultType
;
2774 CFIndex extendedIndex
;
2775 CFIndex interfaceIndex
;
2776 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2777 Boolean isL2TP
= FALSE
;
2780 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2781 if (defaultType
== NULL
) {
2785 if (CFEqual(extendedType
, defaultType
)) {
2786 // extended and default configuration types cannot conflict
2790 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2791 if (interfaceIndex
== kCFNotFound
) {
2792 // configuration information for unknown interface type's
2793 // are stored along with the service and we don't allow
2794 // per-service extended configurations
2798 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2799 CFStringRef interfaceType
;
2801 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2802 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2803 SCNetworkInterfaceRef child
;
2805 child
= SCNetworkInterfaceGetInterface(interface
);
2806 if (child
!= NULL
) {
2807 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2808 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2815 if (requirePerInterface
&&
2816 !configurations
[interfaceIndex
].per_interface_config
&&
2818 // we don't allow per-service extended configurations (except
2819 // that we do allow IPSec as an extended type for PPP->L2TP)
2823 extendedIndex
= findConfiguration(extendedType
);
2824 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2825 // extended type cannot match a known interface type (except
2826 // that we do allow IPSec as an extended type for PPP->L2TP)
2832 * Should we check/match and specifically allow known extended
2833 * configuration types (e.g. EAPOL)?
2835 * Should we check/match and specifically block known internal
2836 * configuration types (e.g. QoSMarking)?
2838 * Lastly, should we ensure that any non-standard extended configuration
2839 * types be of the form com.myCompany.myType?
2848 _SCErrorSet(kSCStatusInvalidArgument
);
2855 CFStringRef defaultType
;
2856 CFMutableArrayRef types
;
2857 } extendedConfiguration
, *extendedConfigurationRef
;
2861 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2863 #pragma unused(value)
2864 CFStringRef extendedType
= (CFStringRef
)key
;
2865 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2867 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2868 // do not include the default configuration type
2872 if (CFArrayContainsValue(myContextRef
->types
,
2873 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2875 // if extendedType already has already been added
2879 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2886 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2888 CFIndex interfaceIndex
;
2889 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2891 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2892 if (interfaceIndex
== kCFNotFound
) {
2893 // if per-service (not per interface) configuration
2897 if (!configurations
[interfaceIndex
].per_interface_config
) {
2898 // if per-interface configuration not allowed
2902 return interfaceIndex
;
2906 static CF_RETURNS_RETAINED CFArrayRef
2907 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2910 CFIndex interfaceIndex
;
2911 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2912 extendedConfiguration myContext
;
2913 SCNetworkServiceRef service
;
2917 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2918 if (myContext
.defaultType
== NULL
) {
2919 myContext
.types
= NULL
;
2923 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2925 if (interfacePrivate
->serviceID
== NULL
) {
2926 // if not associated with a service (yet)
2930 interfaceIndex
= findPerInterfaceConfiguration(interface
);
2931 if (interfaceIndex
== kCFNotFound
) {
2932 // if no per-interface configuration
2936 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2937 interfacePrivate
->prefs
,
2938 interfacePrivate
->serviceID
,
2941 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2942 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2944 for (i
= 0; i
< n
; i
++) {
2945 CFDictionaryRef configs
;
2948 CFArrayRef services
;
2949 SCNetworkSetRef set
;
2951 set
= CFArrayGetValueAtIndex(sets
, i
);
2952 services
= SCNetworkSetCopyServices(set
);
2953 found
= CFArrayContainsValue(services
,
2954 CFRangeMake(0, CFArrayGetCount(services
)),
2956 CFRelease(services
);
2962 // add stored extended configuration types
2963 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2964 SCNetworkSetGetSetID(set
), // set
2965 interfacePrivate
->entity_device
, // service
2967 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2969 if (isA_CFDictionary(configs
)) {
2970 CFDictionaryApplyFunction(configs
,
2971 __addExtendedConfigurationType
,
2975 // add not-yet-stored extended configuration types
2976 if (interfacePrivate
->unsaved
!= NULL
) {
2977 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2978 __addExtendedConfigurationType
,
2986 if (sets
!= NULL
) CFRelease(sets
);
2990 return myContext
.types
;
2994 stringCreateArray(CFStringRef str
)
2996 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3000 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3001 CFStringRef extendedType
)
3003 CFMutableArrayRef array
= NULL
;
3007 SCNetworkServiceRef service
;
3010 // known interface type, per-interface configuration preferences
3012 // 1. look for all sets which contain the associated service
3013 // 2. add a per-set path for the interface configuration for
3016 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3017 interfacePrivate
->prefs
,
3018 interfacePrivate
->serviceID
,
3019 (SCNetworkInterfaceRef
)interfacePrivate
);
3021 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3022 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3024 for (i
= 0; i
< n
; i
++) {
3025 CFArrayRef services
;
3026 SCNetworkSetRef set
;
3028 set
= CFArrayGetValueAtIndex(sets
, i
);
3029 services
= SCNetworkSetCopyServices(set
);
3030 if (CFArrayContainsValue(services
,
3031 CFRangeMake(0, CFArrayGetCount(services
)),
3033 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3034 SCNetworkSetGetSetID(set
), // set
3035 interfacePrivate
->entity_device
, // service
3036 extendedType
); // entity
3037 if (array
== NULL
) {
3038 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3040 CFArrayAppendValue(array
, path
);
3043 CFRelease(services
);
3047 if (sets
!= NULL
) CFRelease(sets
);
3053 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3054 CFStringRef extendedType
)
3056 CFArrayRef array
= NULL
;
3057 CFIndex interfaceIndex
;
3060 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3061 if (interfaceIndex
== kCFNotFound
) {
3062 // unknown interface type, use per-service configuration preferences
3063 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3064 interfacePrivate
->serviceID
, // service
3065 extendedType
); // entity
3066 array
= stringCreateArray(path
);
3070 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3071 // known interface type, per-service configuration preferences
3072 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3073 interfacePrivate
->serviceID
, // service
3074 extendedType
); // entity
3075 array
= stringCreateArray(path
);
3079 else if (interfacePrivate
->serviceID
!= NULL
) {
3080 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3088 #pragma mark SCNetworkInterface <--> preferences entity
3093 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3095 CFMutableDictionaryRef entity
;
3096 CFIndex interfaceIndex
;
3097 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3099 entity
= CFDictionaryCreateMutable(NULL
,
3101 &kCFTypeDictionaryKeyCallBacks
,
3102 &kCFTypeDictionaryValueCallBacks
);
3103 if (interfacePrivate
->entity_type
!= NULL
) {
3104 CFDictionarySetValue(entity
,
3105 kSCPropNetInterfaceType
,
3106 interfacePrivate
->entity_type
);
3108 if (interfacePrivate
->entity_subtype
!= NULL
) {
3109 CFDictionarySetValue(entity
,
3110 kSCPropNetInterfaceSubType
,
3111 interfacePrivate
->entity_subtype
);
3113 if (interfacePrivate
->entity_device
!= NULL
) {
3114 CFDictionarySetValue(entity
,
3115 kSCPropNetInterfaceDeviceName
,
3116 interfacePrivate
->entity_device
);
3118 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3119 CFDictionarySetValue(entity
,
3120 CFSTR("DeviceUniqueIdentifier"),
3121 interfacePrivate
->entity_device_unique
);
3123 if (interfacePrivate
->hidden
) {
3124 CFDictionarySetValue(entity
,
3125 kSCNetworkInterfaceHiddenConfigurationKey
,
3129 // match the "hardware" with the lowest layer
3131 SCNetworkInterfaceRef nextInterface
;
3133 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3134 if (nextInterface
== NULL
) {
3138 interface
= nextInterface
;
3140 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3142 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3146 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3147 if (interfaceIndex
!= kCFNotFound
) {
3148 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3149 CFDictionarySetValue(entity
,
3150 kSCPropNetInterfaceHardware
,
3151 *configurations
[interfaceIndex
].entity_hardware
);
3154 CFDictionarySetValue(entity
,
3155 kSCPropNetInterfaceHardware
,
3156 interfacePrivate
->interface_type
);
3159 // add the localized display name (which will only be used when/if the
3160 // interface is removed from the system)
3161 CFDictionarySetValue(entity
,
3162 kSCPropUserDefinedName
,
3163 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3169 static SCNetworkInterfaceRef
3170 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3175 n
= CFArrayGetCount(interfaces
);
3176 for (i
= 0; i
< n
; i
++) {
3177 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3178 CFStringRef interfaceName
;
3180 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3181 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3182 CFRetain(interface
);
3190 #if !TARGET_OS_IPHONE
3191 static SCNetworkInterfaceRef
3192 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3195 SCNetworkInterfaceRef interface
= NULL
;
3197 if (prefs
== NULL
) {
3201 // check if the interface is an Ethernet Bond
3202 bonds
= SCBondInterfaceCopyAll(prefs
);
3203 if (bonds
!= NULL
) {
3204 interface
= findInterface(bonds
, ifDevice
);
3209 #endif // !TARGET_OS_IPHONE
3211 static SCNetworkInterfaceRef
3212 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3215 SCNetworkInterfaceRef interface
= NULL
;
3217 if (prefs
== NULL
) {
3221 // check if the interface is an bridge
3222 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3223 if (bridges
!= NULL
) {
3224 interface
= findInterface(bridges
, ifDevice
);
3230 static SCNetworkInterfaceRef
3231 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3233 SCNetworkInterfaceRef interface
= NULL
;
3236 if (prefs
== NULL
) {
3240 // check if the interface is a VLAN
3241 vlans
= SCVLANInterfaceCopyAll(prefs
);
3242 if (vlans
!= NULL
) {
3243 interface
= findInterface(vlans
, ifDevice
);
3253 static CFMutableDictionaryRef
3254 copy_ppp_entity(CFStringRef bsdName
)
3256 CFMutableDictionaryRef entity
= NULL
;
3257 CFStringRef pattern
;
3258 CFMutableArrayRef patterns
;
3259 CFDictionaryRef dict
;
3261 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3262 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3263 CFArrayAppendValue(patterns
, pattern
);
3265 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3266 CFArrayAppendValue(patterns
, pattern
);
3268 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3269 CFRelease(patterns
);
3272 const void * keys_q
[N_QUICK
];
3273 const void ** keys
= keys_q
;
3275 const void * vals_q
[N_QUICK
];
3276 const void ** vals
= vals_q
;
3278 n
= CFDictionaryGetCount(dict
);
3279 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3280 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3281 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3283 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3284 for (i
= 0; i
< n
; i
++) {
3285 CFArrayRef components
;
3286 CFStringRef interfaceKey
;
3287 CFDictionaryRef interfaceVal
;
3289 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3290 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3291 CFStringRef serviceID
;
3293 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3294 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3295 !CFEqual(bsdName
, ifName
)) {
3296 // if not matching PPP interface
3300 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3301 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3302 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3303 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3304 CFRelease(interfaceKey
);
3305 CFRelease(components
);
3306 if (interfaceVal
!= NULL
) {
3307 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3311 if (keys
!= keys_q
) {
3312 CFAllocatorDeallocate(NULL
, keys
);
3313 CFAllocatorDeallocate(NULL
, vals
);
3323 SCNetworkInterfaceRef
3324 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3325 CFStringRef bsdName
,
3328 #pragma unused(allocator)
3329 CFMutableDictionaryRef entity
= NULL
;
3331 SCNetworkInterfaceRef interface
;
3333 bzero(&ifr
, sizeof(ifr
));
3334 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3337 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3339 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3345 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3347 entity
= copy_ppp_entity(bsdName
);
3351 if (entity
== NULL
) {
3352 entity
= CFDictionaryCreateMutable(NULL
,
3354 &kCFTypeDictionaryKeyCallBacks
,
3355 &kCFTypeDictionaryValueCallBacks
);
3356 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3359 #if !TARGET_OS_IPHONE
3360 if ((flags
& kIncludeBondInterfaces
) == 0) {
3361 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3363 #endif // !TARGET_OS_IPHONE
3365 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3366 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3369 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3370 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3373 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3381 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3383 CFMutableStringRef interfacePrefix
= NULL
;
3387 if (isA_CFString(bsdName
) == NULL
) {
3388 SC_log(LOG_DEBUG
, "no BSD name");
3392 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3393 length
= CFStringGetLength(interfacePrefix
);
3395 while (length
> 0) {
3396 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3397 if (lastChar
>= '0' && lastChar
<= '9') {
3398 CFStringDelete(interfacePrefix
,
3399 CFRangeMake(length
-1, 1));
3404 length
= CFStringGetLength(interfacePrefix
);
3407 return interfacePrefix
;
3412 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3413 CFStringRef prefix
);
3417 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3419 Boolean success
= FALSE
;
3420 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3422 if (isA_SCNetworkInterface(interface
) == NULL
) {
3423 SC_log(LOG_INFO
, "No interface");
3427 if (CFEqual(currentBSDName
, newBSDName
)) {
3432 if (interfacePrivate
->entity_device
!= NULL
) {
3433 CFRelease(interfacePrivate
->entity_device
);
3435 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3443 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3445 Boolean success
= FALSE
;
3446 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3447 CFStringRef oldPath
= NULL
;
3448 CFStringRef newPath
= NULL
;
3450 // Using the BSD Name update the path
3451 oldPath
= interfacePrivate
->path
;
3452 if (isA_CFString(oldPath
) == NULL
) {
3455 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3456 if (interfacePrivate
->path
!= NULL
) {
3457 CFRelease(interfacePrivate
->path
);
3459 interfacePrivate
->path
= CFRetain(newPath
);
3463 if (newPath
!= NULL
) {
3471 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3474 SCNetworkInterfacePrivateRef interfacePrivate
;
3476 if (isA_CFString(prefix
) == NULL
) {
3480 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3484 if (interfacePrivate
->prefix
!= NULL
) {
3485 CFRelease(interfacePrivate
->prefix
);
3488 interfacePrivate
->prefix
= prefix
;
3495 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3498 SCNetworkInterfacePrivateRef interfacePrivate
;
3499 CFStringRef newBSDName
= NULL
;
3500 CFStringRef oldBSDName
= NULL
;
3502 if (isA_CFNumber(unit
) == NULL
) {
3505 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3507 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3509 if (interfacePrivate
->prefix
== NULL
) {
3510 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3511 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3512 if (interfaceNamePrefix
== NULL
) {
3513 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3516 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3517 CFRelease(interfaceNamePrefix
);
3522 if (interfacePrivate
->prefix
!= NULL
) {
3523 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3526 // Update the BSD Name
3527 if ((newBSDName
== NULL
) ||
3528 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3529 SC_log(LOG_INFO
, "BSD name update failed");
3533 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3534 SC_log(LOG_INFO
, "IOPath update failed");
3538 if (interfacePrivate
->unit
!= NULL
) {
3539 CFRelease(interfacePrivate
->unit
);
3541 interfacePrivate
->unit
= unit
;
3544 if (newBSDName
!= NULL
) {
3545 CFRelease(newBSDName
);
3553 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3555 CFMutableDictionaryRef interface_entity
= NULL
;
3556 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3557 CFBooleanRef active
= NULL
;
3558 CFStringRef bsdName
= NULL
;
3559 CFBooleanRef builtin
= NULL
;
3560 CFStringRef interfaceNamePrefix
= NULL
;
3561 CFNumberRef interfaceType
= NULL
;
3562 CFNumberRef interfaceUnit
= NULL
;
3563 CFDataRef macAddress
= NULL
;
3564 CFStringRef pathMatch
= NULL
;
3565 CFDictionaryRef info
= NULL
;
3566 CFStringRef type
= NULL
;
3568 if (interfacePrivate
->active
) {
3569 active
= kCFBooleanTrue
;
3572 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3573 if (!isA_CFString(bsdName
)) {
3577 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3578 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3579 if (!isA_CFString(interfaceNamePrefix
)) {
3583 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3584 if (!isA_CFNumber(interfaceType
)) {
3588 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3589 if (!isA_CFNumber(interfaceUnit
)) {
3593 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3594 if (!isA_CFData(macAddress
)) {
3598 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3599 if (!isA_CFString(pathMatch
)) {
3603 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3604 if (!isA_CFDictionary(info
)) {
3608 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3609 if (!isA_CFString(type
)) {
3613 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3614 &kCFTypeDictionaryKeyCallBacks
,
3615 &kCFTypeDictionaryValueCallBacks
);
3617 if (isA_CFBoolean(active
) != NULL
) {
3618 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3621 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3622 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3623 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3624 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3625 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3626 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3627 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3628 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3629 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3634 return interface_entity
;
3639 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3640 SCNetworkServiceRef service
)
3642 SCNetworkInterfacePrivateRef interfacePrivate
;
3643 SCNetworkServicePrivateRef servicePrivate
;
3645 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3646 if (interfacePrivate
->prefs
!= NULL
) {
3647 CFRelease(interfacePrivate
->prefs
);
3648 interfacePrivate
->prefs
= NULL
;
3650 if (interfacePrivate
->serviceID
!= NULL
) {
3651 CFRelease(interfacePrivate
->serviceID
);
3652 interfacePrivate
->serviceID
= NULL
;
3655 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3656 if (servicePrivate
->prefs
!= NULL
) {
3657 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3659 if (servicePrivate
->serviceID
!= NULL
) {
3660 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3669 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3674 if (bundle
== NULL
) {
3675 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3679 if (!isA_CFString(name
)) {
3680 // if no interface "name"
3684 // check non-localized name for a match
3685 str
= copy_interface_string(bundle
, key
, FALSE
);
3687 match
= CFEqual(name
, str
);
3694 // check localized name for a match
3695 str
= copy_interface_string(bundle
, key
, TRUE
);
3697 match
= CFEqual(name
, str
);
3708 #define kInterfaceTypeEthernetValue 6
3709 #define kInterfaceTypeFirewireValue 144
3712 static SCNetworkInterfaceRef
3713 __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator
,
3714 CFDictionaryRef interface_entity
)
3716 #pragma unused(allocator)
3717 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3718 CFBooleanRef active
= NULL
;
3719 CFStringRef bsdName
= NULL
;
3720 CFBooleanRef ioBuiltin
= NULL
;
3721 CFStringRef ioInterfaceNamePrefix
= NULL
;
3722 CFNumberRef ioInterfaceType
= NULL
;
3723 int ioInterfaceTypeNum
;
3724 CFNumberRef ioInterfaceUnit
= NULL
;
3725 CFDataRef ioMACAddress
= NULL
;
3726 CFStringRef ioPathMatch
= NULL
;
3727 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3728 CFStringRef userDefinedName
= NULL
;
3729 CFStringRef usbProductName
= NULL
;
3730 CFNumberRef idProduct
= NULL
;
3731 CFNumberRef idVendor
= NULL
;
3732 CFStringRef type
= NULL
;
3734 /* initialize runtime */
3735 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3737 if (isA_CFDictionary(interface_entity
) == NULL
) {
3738 SC_log(LOG_INFO
, "No interface entity");
3741 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3742 if (isA_CFBoolean(active
) == NULL
) {
3743 active
= kCFBooleanFalse
;
3745 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3746 if (isA_CFString(bsdName
) == NULL
) {
3747 SC_log(LOG_INFO
, "No BSD name");
3750 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3751 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3752 SC_log(LOG_INFO
, "No IOBuiltin property");
3755 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3756 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3757 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3758 if (ioInterfaceNamePrefix
== NULL
) {
3759 SC_log(LOG_INFO
, "No BSD interface name prefix");
3763 CFRetain(ioInterfaceNamePrefix
);
3765 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3766 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3767 SC_log(LOG_INFO
, "No IOInterfaceType");
3770 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3771 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3773 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3774 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3775 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3779 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3780 if (isA_CFData(ioMACAddress
) == NULL
) {
3781 SC_log(LOG_INFO
, "No IOMACAddress");
3784 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3785 if (isA_CFString(ioPathMatch
) == NULL
) {
3786 SC_log(LOG_INFO
, "No IOPathMatch");
3789 // Check if Path contains the BSD Name in the end
3791 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3792 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3793 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3796 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3797 #if !TARGET_OS_SIMULATOR
3798 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3799 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3800 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3801 #endif // !TARGET_OS_SIMULATOR
3803 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3804 if (isA_CFString(type
) == NULL
) {
3805 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3809 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3810 interfacePrivate
->active
= CFBooleanGetValue(active
);
3811 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3812 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3813 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3814 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3815 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3816 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3817 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3818 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3819 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3820 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3821 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3822 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3824 // Handling interface types to be seen in NetworkInterfaces.plist
3825 CFIndex interfaceIndex
;
3827 interfaceIndex
= findConfiguration(type
);
3828 if (interfaceIndex
!= kCFNotFound
) {
3829 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3831 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3834 // Extracting entity type from value of interface type
3835 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3836 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3837 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3838 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3841 if (ioInterfaceNamePrefix
!= NULL
) {
3842 CFRelease(ioInterfaceNamePrefix
);
3845 return (SCNetworkInterfaceRef
)interfacePrivate
;
3850 _SCNetworkInterfaceCacheOpen()
3852 if (!__SCNetworkInterfaceCacheIsOpen()) {
3853 S_interface_cache
= CFDictionaryCreateMutable(NULL
,
3855 &kCFTypeDictionaryKeyCallBacks
,
3856 &kCFTypeDictionaryValueCallBacks
);
3857 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): open", S_interface_cache
);
3863 _SCNetworkInterfaceCacheClose()
3865 if (__SCNetworkInterfaceCacheIsOpen()) {
3866 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): close", S_interface_cache
);
3867 CFRelease(S_interface_cache
);
3868 S_interface_cache
= NULL
;
3874 __SCNetworkInterfaceCacheAdd(CFStringRef bsdName
, CFArrayRef matchingInterfaces
)
3876 if (__SCNetworkInterfaceCacheIsOpen() &&
3878 matchingInterfaces
!= NULL
) {
3879 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): add %@", S_interface_cache
, bsdName
);
3880 CFDictionaryAddValue(S_interface_cache
, bsdName
, matchingInterfaces
);
3885 static inline Boolean
3886 __SCNetworkInterfaceCacheIsOpen()
3888 return (S_interface_cache
!= NULL
);
3893 __SCNetworkInterfaceCacheCopy(CFStringRef bsdName
)
3895 if (__SCNetworkInterfaceCacheIsOpen() &&
3897 CFArrayRef matchingInterfaces
= CFDictionaryGetValue(S_interface_cache
, bsdName
);
3898 if (matchingInterfaces
) {
3899 CFRetain(matchingInterfaces
);
3900 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache
, bsdName
);
3902 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache
, bsdName
);
3905 return matchingInterfaces
;
3912 SCNetworkInterfaceRef
3913 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3914 CFDictionaryRef interface_entity
,
3915 SCNetworkServiceRef service
)
3917 #pragma unused(allocator)
3918 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3919 CFStringRef ifDevice
;
3920 CFStringRef ifName
= NULL
;
3921 CFStringRef ifSubType
;
3923 CFStringRef ifUnique
;
3924 CFArrayRef matching_interfaces
= NULL
;
3925 SCPreferencesRef servicePref
= NULL
;
3926 Boolean useSystemInterfaces
= TRUE
;
3928 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3929 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3931 if (service
!= NULL
) {
3932 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3933 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3934 (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
)));
3937 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3938 if (ifType
== NULL
) {
3940 * The interface "Type" was not specified. We'll make an
3941 * assumption that this is an "Ethernet" interface. If a
3942 * real interface exists with the provided interface name
3943 * then the actual type will be set accordingly. If not, we'll
3944 * end up crafting an "Ethernet" SCNetworkInterface that
3945 * will keep the rest of the configuration APIs happy.
3947 ifType
= kSCValNetInterfaceTypeEthernet
;
3950 if (!isA_CFString(ifType
)) {
3954 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3955 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3956 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3957 if (!isA_CFString(ifSubType
)) {
3962 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3963 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3965 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3966 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3967 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3968 char bsdName
[IFNAMSIZ
];
3969 CFMutableDictionaryRef matching
;
3971 if (!isA_CFString(ifDevice
)) {
3975 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3976 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3979 if (useSystemInterfaces
) {
3980 // Check to see if we already have the info in the cache
3981 matching_interfaces
= __SCNetworkInterfaceCacheCopy(ifDevice
);
3982 if (matching_interfaces
== NULL
) {
3983 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3987 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3988 if (matching
== NULL
) {
3991 matching_interfaces
= findMatchingInterfaces(matching
,
3992 processNetworkInterface
,
3993 kSCNetworkInterfaceHiddenInterfaceKey
,
3996 __SCNetworkInterfaceCacheAdd(ifDevice
, matching_interfaces
);
3997 CFRelease(matching
);
4000 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4001 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4002 CFDictionaryRef matching
;
4003 CFStringRef match_keys
[2];
4004 CFStringRef match_vals
[2];
4006 if (!isA_CFString(ifDevice
)) {
4010 if (useSystemInterfaces
) {
4011 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4012 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4014 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4015 match_vals
[1] = ifDevice
;
4017 matching
= CFDictionaryCreate(NULL
,
4018 (const void **)match_keys
,
4019 (const void **)match_vals
,
4020 sizeof(match_keys
)/sizeof(match_keys
[0]),
4021 &kCFTypeDictionaryKeyCallBacks
,
4022 &kCFTypeDictionaryValueCallBacks
);
4023 matching_interfaces
= findMatchingInterfaces(matching
,
4024 processSerialInterface
,
4025 kSCNetworkInterfaceHiddenPortKey
,
4027 CFRelease(matching
);
4029 if (ifUnique
== NULL
) {
4031 Boolean useDeviceName
= TRUE
;
4033 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4037 for (i
= 0; i
< n
; i
++) {
4038 SCNetworkInterfacePrivateRef scanPrivate
;
4040 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4041 if (scanPrivate
->entity_device_unique
!= NULL
) {
4042 useDeviceName
= FALSE
;
4048 if (useDeviceName
&& useSystemInterfaces
) {
4049 if (matching_interfaces
!= NULL
) {
4050 CFRelease(matching_interfaces
);
4053 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4054 matching
= CFDictionaryCreate(NULL
,
4055 (const void **)match_keys
,
4056 (const void **)match_vals
,
4057 sizeof(match_keys
)/sizeof(match_keys
[0]),
4058 &kCFTypeDictionaryKeyCallBacks
,
4059 &kCFTypeDictionaryValueCallBacks
);
4060 matching_interfaces
= findMatchingInterfaces(matching
,
4061 processSerialInterface
,
4062 kSCNetworkInterfaceHiddenPortKey
,
4064 CFRelease(matching
);
4067 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4068 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4069 kSCNetworkInterfaceTypeL2TP
);
4070 #pragma GCC diagnostic push
4071 #pragma GCC diagnostic ignored "-Wdeprecated"
4072 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4073 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4074 kSCNetworkInterfaceTypePPTP
);
4075 #pragma GCC diagnostic pop
4077 // XXX do we allow non-Apple variants of PPP??? XXX
4078 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4081 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4082 if (!isA_CFString(ifDevice
)) {
4086 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4087 kSCNetworkInterfaceType6to4
);
4088 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4089 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4090 kSCNetworkInterfaceTypeIPSec
);
4091 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4092 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4093 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4094 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4095 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4098 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4099 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4103 if (matching_interfaces
!= NULL
) {
4105 SCPreferencesRef prefs
;
4106 Boolean temp_preferences
= FALSE
;
4108 n
= CFArrayGetCount(matching_interfaces
);
4111 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4112 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4113 // if the unique ID's match
4114 CFRetain(interfacePrivate
);
4118 interfacePrivate
= NULL
;
4121 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4125 if (CFDictionaryGetValueIfPresent(interface_entity
,
4126 kSCPropUserDefinedName
,
4127 (const void **)&ifName
) &&
4128 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4132 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4133 if (prefs
== NULL
) {
4134 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4135 if (prefs
!= NULL
) {
4136 temp_preferences
= TRUE
;
4139 if (prefs
== NULL
) {
4142 #if !TARGET_OS_IPHONE
4143 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4144 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4146 #endif // !TARGET_OS_IPHONE
4147 if ((interfacePrivate
== NULL
)
4148 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4149 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4152 if ((interfacePrivate
== NULL
)
4153 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4154 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4156 if (temp_preferences
) CFRelease(prefs
);
4159 if (ifUnique
!= NULL
) {
4162 // we are looking for an interface with a unique ID
4163 // so let's try to focus our choices
4164 for (i
= 0; i
< n
; i
++) {
4165 SCNetworkInterfacePrivateRef scanPrivate
;
4167 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4168 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4169 if (interfacePrivate
!= NULL
) {
4170 // if we've matched more than one interface
4171 interfacePrivate
= NULL
;
4174 interfacePrivate
= scanPrivate
;
4177 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4178 kSCPropUserDefinedName
,
4179 (const void **)&ifName
)) {
4182 // we don't have a unique ID but do have an interface
4183 // name. If the matching interfaces do have IDs than
4184 // we can try to focus our choices using the name
4185 for (i
= 0; i
< n
; i
++) {
4186 SCNetworkInterfacePrivateRef scanPrivate
;
4188 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4189 if (scanPrivate
->entity_device_unique
!= NULL
) {
4190 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4191 CFStringRef scanName
;
4193 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4194 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4195 continue; // if not the same display name
4199 if (interfacePrivate
!= NULL
) {
4200 // if we've matched more than one interface
4201 interfacePrivate
= NULL
;
4204 interfacePrivate
= scanPrivate
;
4207 if (interfacePrivate
== NULL
) {
4208 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4209 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4211 CFRetain(interfacePrivate
);
4214 CFRelease(matching_interfaces
);
4219 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4221 * if device not present on this system
4223 if (!useSystemInterfaces
) {
4224 if (interfacePrivate
!= NULL
) {
4225 CFRelease(interfacePrivate
);
4229 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4230 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4231 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4232 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4233 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4235 // Using UserDefinedName to check the validity of preferences file
4236 // when useSystemInterfaces is FALSE
4237 if (!useSystemInterfaces
) {
4238 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4239 if (isA_CFString(userDefinedName
) != NULL
) {
4240 CFRetain(userDefinedName
);
4241 if (interfacePrivate
->name
!= NULL
) {
4242 CFRelease(interfacePrivate
->name
);
4244 interfacePrivate
->name
= userDefinedName
;
4246 CFRetain(userDefinedName
);
4247 if (interfacePrivate
->localized_name
!= NULL
) {
4248 CFRelease(interfacePrivate
->localized_name
);
4250 interfacePrivate
->localized_name
= userDefinedName
;
4254 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4255 CFStringRef entity_hardware
;
4256 SCNetworkInterfaceRef virtualInterface
;
4258 if (!useSystemInterfaces
&&
4259 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4260 #if !TARGET_OS_IPHONE
4261 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4263 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4264 CFRelease(interfacePrivate
);
4265 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4267 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4268 if (isA_CFString((entity_hardware
)) &&
4269 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4270 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4271 interfacePrivate
->localized_key
= CFSTR("airport");
4272 interfacePrivate
->sort_order
= kSortAirPort
;
4276 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4278 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4279 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4280 interfacePrivate
->localized_key
= CFSTR("iPhone");
4281 interfacePrivate
->sort_order
= kSortTethered
;
4282 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4283 interfacePrivate
->localized_key
= CFSTR("iPad");
4284 interfacePrivate
->sort_order
= kSortTethered
;
4285 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4286 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4287 interfacePrivate
->sort_order
= kSortThunderbolt
;
4288 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4289 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4290 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4291 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4292 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4293 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4294 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4295 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4296 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4298 interfacePrivate
->sort_order
= kSortEthernet
;
4302 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4303 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4304 interfacePrivate
->sort_order
= kSortFireWire
;
4305 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4306 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4307 CFStringRef entity_hardware
;
4309 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4310 if (isA_CFString((entity_hardware
)) &&
4311 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4312 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4313 interfacePrivate
->sort_order
= kSortAirPort
;
4315 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4316 interfacePrivate
->sort_order
= kSortEthernet
;
4318 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4319 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4320 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4321 interfacePrivate
->sort_order
= kSortBluetooth
;
4322 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4323 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4324 interfacePrivate
->sort_order
= kSortIrDA
;
4325 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4326 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4327 interfacePrivate
->sort_order
= kSortWWAN
;
4329 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4330 interfacePrivate
->sort_order
= kSortModem
;
4333 SCNetworkInterfaceRef child
;
4335 CFRelease(interfacePrivate
);
4336 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4337 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4338 if (interfacePrivate
== NULL
) {
4342 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4343 SCNetworkInterfaceRef child
;
4344 CFRelease(interfacePrivate
);
4345 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4346 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4347 if (interfacePrivate
== NULL
) {
4350 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4351 CFRelease(interfacePrivate
);
4352 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4353 kSCNetworkInterfaceTypeIPSec
);
4354 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4355 CFRelease(interfacePrivate
);
4356 if (!isA_CFString(ifDevice
)) {
4359 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4360 kSCNetworkInterfaceType6to4
);
4361 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4362 CFRelease(interfacePrivate
);
4363 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4364 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4365 // if vendor interface
4366 pthread_mutex_lock(&lock
);
4367 if (vendor_interface_types
== NULL
) {
4368 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4370 CFSetAddValue(vendor_interface_types
, ifType
);
4371 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4372 pthread_mutex_unlock(&lock
);
4374 // if unknown interface
4375 CFRelease(interfacePrivate
);
4376 interfacePrivate
= NULL
;
4380 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4381 interfacePrivate
->hidden
= TRUE
;
4385 if (service
!= NULL
) {
4386 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4389 #if !TARGET_OS_IPHONE
4390 // set prefs & serviceID to Bond member interfaces
4391 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4396 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4397 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4398 for (i
= 0; i
< n
; i
++) {
4399 SCNetworkInterfaceRef member
;
4401 member
= CFArrayGetValueAtIndex(members
, i
);
4402 __SCNetworkInterfaceSetService(member
, service
);
4405 #endif // !TARGET_OS_IPHONE
4407 // set prefs & serviceID to Bridge member interfaces
4408 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4413 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4414 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4415 for (i
= 0; i
< n
; i
++) {
4416 SCNetworkInterfaceRef member
;
4418 member
= CFArrayGetValueAtIndex(members
, i
);
4419 __SCNetworkInterfaceSetService(member
, service
);
4422 // set prefs & serviceID to VLAN pyhsical interface
4423 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4424 SCNetworkInterfaceRef vlan_physical
;
4426 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4427 if (vlan_physical
!= NULL
) {
4428 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4433 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4434 SCNetworkInterfaceRef parent
;
4437 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4438 kSCNetworkInterfaceTypePPP
);
4439 CFRelease(interfacePrivate
);
4440 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4441 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4442 SCNetworkInterfaceRef parent
;
4445 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4446 kSCNetworkInterfaceTypeVPN
);
4447 CFRelease(interfacePrivate
);
4448 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4451 return (SCNetworkInterfaceRef
)interfacePrivate
;
4456 #pragma mark SCNetworkInterface APIs
4461 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4463 CFDictionaryRef matching
;
4464 CFArrayRef new_interfaces
;
4466 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4468 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4469 new_interfaces
= findMatchingInterfaces(matching
,
4470 processNetworkInterface
,
4471 kSCNetworkInterfaceHiddenInterfaceKey
,
4472 keep_pre_configured
);
4473 CFRelease(matching
);
4475 return new_interfaces
;
4481 __SCNetworkInterfaceCopyAll_Modem()
4483 CFDictionaryRef matching
;
4484 CFStringRef match_keys
[2];
4485 CFStringRef match_vals
[2];
4486 CFArrayRef new_interfaces
;
4488 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4489 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4491 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4492 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4494 matching
= CFDictionaryCreate(NULL
,
4495 (const void **)match_keys
,
4496 (const void **)match_vals
,
4497 sizeof(match_keys
)/sizeof(match_keys
[0]),
4498 &kCFTypeDictionaryKeyCallBacks
,
4499 &kCFTypeDictionaryValueCallBacks
);
4500 new_interfaces
= findMatchingInterfaces(matching
,
4501 processSerialInterface
,
4502 kSCNetworkInterfaceHiddenPortKey
,
4504 CFRelease(matching
);
4506 return new_interfaces
;
4512 __SCNetworkInterfaceCopyAll_RS232()
4514 CFDictionaryRef matching
;
4515 CFStringRef match_keys
[2];
4516 CFStringRef match_vals
[2];
4517 CFArrayRef new_interfaces
;
4519 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4520 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4522 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4523 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4525 matching
= CFDictionaryCreate(NULL
,
4526 (const void **)match_keys
,
4527 (const void **)match_vals
,
4528 sizeof(match_keys
)/sizeof(match_keys
[0]),
4529 &kCFTypeDictionaryKeyCallBacks
,
4530 &kCFTypeDictionaryValueCallBacks
);
4531 new_interfaces
= findMatchingInterfaces(matching
,
4532 processSerialInterface
,
4533 kSCNetworkInterfaceHiddenPortKey
,
4535 CFRelease(matching
);
4537 return new_interfaces
;
4541 #if !TARGET_OS_IPHONE
4543 addBTPANInterface(CFMutableArrayRef all_interfaces
)
4546 SCNetworkInterfaceRef interface
;
4549 n
= CFArrayGetCount(all_interfaces
);
4550 for (i
= 0; i
< n
; i
++) {
4551 SCNetworkInterfaceRef interface
;
4553 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4554 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4555 // if we already have a BT-PAN interface
4560 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4561 if (interface
!= NULL
) {
4562 // include BT-PAN interface
4563 CFArrayAppendValue(all_interfaces
, interface
);
4564 CFRelease(interface
);
4569 #endif // !TARGET_OS_IPHONE
4573 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4578 n
= CFArrayGetCount(new_interfaces
);
4579 for (i
= 0; i
< n
; i
++) {
4580 CFStringRef bsdName
;
4581 SCNetworkInterfaceRef interface
;
4583 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4584 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4585 if (bsdName
!= NULL
) {
4586 CFArrayAppendValue(all_interfaces
, interface
);
4595 __waitForInterfaces()
4600 SCDynamicStoreRef store
;
4602 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4603 if (store
== NULL
) {
4607 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4608 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4609 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4612 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4617 CFArrayRef changedKeys
;
4618 CFDictionaryRef dict
;
4619 Boolean quiet
= FALSE
;
4622 dict
= SCDynamicStoreCopyValue(store
, key
);
4624 if (isA_CFDictionary(dict
) &&
4625 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4626 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4635 ok
= SCDynamicStoreNotifyWait(store
);
4637 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4641 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4642 if (changedKeys
!= NULL
) {
4643 CFRelease(changedKeys
);
4655 CFArrayRef
/* of SCNetworkInterfaceRef's */
4656 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4658 CFMutableArrayRef all_interfaces
;
4659 CFArrayRef new_interfaces
;
4660 Boolean temp_preferences
= FALSE
;
4662 /* initialize runtime */
4663 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4665 /* wait for IOKit to quiesce */
4666 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4668 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4670 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4671 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4672 if (new_interfaces
!= NULL
) {
4673 add_interfaces(all_interfaces
, new_interfaces
);
4674 CFRelease(new_interfaces
);
4677 // get Modem interfaces
4678 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4679 if (new_interfaces
!= NULL
) {
4680 add_interfaces(all_interfaces
, new_interfaces
);
4681 CFRelease(new_interfaces
);
4684 // get serial (RS232) interfaces
4685 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4686 if (new_interfaces
!= NULL
) {
4687 add_interfaces(all_interfaces
, new_interfaces
);
4688 CFRelease(new_interfaces
);
4691 // get virtual network interfaces (Bond, Bridge, VLAN)
4692 if (prefs
== NULL
) {
4693 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4694 if (prefs
!= NULL
) {
4695 temp_preferences
= TRUE
;
4698 if (prefs
!= NULL
) {
4699 #if !TARGET_OS_IPHONE
4700 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4701 if (new_interfaces
!= NULL
) {
4702 add_interfaces(all_interfaces
, new_interfaces
);
4703 CFRelease(new_interfaces
);
4705 #endif // !TARGET_OS_IPHONE
4707 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4708 if (new_interfaces
!= NULL
) {
4709 add_interfaces(all_interfaces
, new_interfaces
);
4710 CFRelease(new_interfaces
);
4713 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4714 if (new_interfaces
!= NULL
) {
4715 add_interfaces(all_interfaces
, new_interfaces
);
4716 CFRelease(new_interfaces
);
4719 #if !TARGET_OS_IPHONE
4720 // add BT-PAN interface
4721 addBTPANInterface(all_interfaces
);
4722 #endif // !TARGET_OS_IPHONE
4724 if (temp_preferences
) CFRelease(prefs
);
4727 // all interfaces have been identified, order and return
4728 sort_interfaces(all_interfaces
);
4730 return all_interfaces
;
4734 CFArrayRef
/* of SCNetworkInterfaceRef's */
4735 SCNetworkInterfaceCopyAll()
4737 CFArrayRef all_interfaces
;
4739 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4740 return all_interfaces
;
4744 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4745 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4748 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4750 if (!isA_SCNetworkInterface(interface
)) {
4751 _SCErrorSet(kSCStatusInvalidArgument
);
4755 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4759 i
= findConfiguration(interfacePrivate
->interface_type
);
4760 if (i
!= kCFNotFound
) {
4761 if (configurations
[i
].supported_interfaces
!= doNone
) {
4762 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4763 if (configurations
[i
].supported_interfaces
& do6to4
) {
4764 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4766 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4767 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4769 if (configurations
[i
].supported_interfaces
& doPPP
) {
4770 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4772 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4773 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4777 SCNetworkInterfaceRef child
;
4779 child
= SCNetworkInterfaceGetInterface(interface
);
4780 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4781 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4782 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4788 return interfacePrivate
->supported_interface_types
;
4792 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4793 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4796 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4798 if (!isA_SCNetworkInterface(interface
)) {
4799 _SCErrorSet(kSCStatusInvalidArgument
);
4803 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4807 i
= findConfiguration(interfacePrivate
->interface_type
);
4808 if (i
!= kCFNotFound
) {
4809 if (configurations
[i
].supported_protocols
!= doNone
) {
4810 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4811 if (configurations
[i
].supported_protocols
& doDNS
) {
4812 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4814 if (configurations
[i
].supported_protocols
& doIPv4
) {
4815 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4817 if (configurations
[i
].supported_protocols
& doIPv6
) {
4818 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4820 if (configurations
[i
].supported_protocols
& doProxies
) {
4821 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4823 #if !TARGET_OS_IPHONE
4824 if (configurations
[i
].supported_protocols
& doSMB
) {
4825 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4827 #endif // !TARGET_OS_IPHONE
4833 return interfacePrivate
->supported_protocol_types
;
4837 SCNetworkInterfaceRef
4838 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4840 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4842 SCNetworkInterfacePrivateRef parentPrivate
;
4844 if (!isA_SCNetworkInterface(child
)) {
4845 _SCErrorSet(kSCStatusInvalidArgument
);
4849 if (!isA_CFString(interfaceType
)) {
4850 _SCErrorSet(kSCStatusInvalidArgument
);
4854 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4855 // can't layer on top of loopback
4856 _SCErrorSet(kSCStatusInvalidArgument
);
4860 childIndex
= findConfiguration(childPrivate
->interface_type
);
4862 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4864 childPrivate
->prefs
,
4865 childPrivate
->serviceID
);
4866 if (parentPrivate
== NULL
) {
4867 _SCErrorSet(kSCStatusFailed
);
4871 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4872 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4873 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4876 if (childIndex
!= kCFNotFound
) {
4877 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4878 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4880 // sorry, the child interface does not support PPP
4884 // if the child's interface type not known, use the child entities "Type"
4885 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4888 if (childPrivate
->entity_device
!= NULL
) {
4889 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4892 if (childPrivate
->entity_device_unique
!= NULL
) {
4893 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4895 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4896 if ((childIndex
== kCFNotFound
) ||
4897 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4898 // if the child interface does not support L2TP
4901 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4902 parentPrivate
->localized_key
= CFSTR("l2tp");
4903 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4904 #pragma GCC diagnostic push
4905 #pragma GCC diagnostic ignored "-Wdeprecated"
4906 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4907 if ((childIndex
== kCFNotFound
) ||
4908 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4909 // if the child interface does not support PPTP
4912 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4913 parentPrivate
->localized_key
= CFSTR("pptp");
4914 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4915 #pragma GCC diagnostic pop
4916 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4917 if ((childIndex
== kCFNotFound
) ||
4918 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4919 // if the child interface does not support 6to4
4923 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4924 parentPrivate
->localized_key
= CFSTR("6to4");
4925 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4926 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4927 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4928 if ((childIndex
== kCFNotFound
) ||
4929 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4930 // if the child interface does not support IPSec
4933 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4934 parentPrivate
->localized_key
= CFSTR("ipsec");
4935 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4936 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4937 if (childIndex
!= kCFNotFound
) {
4938 // if not a "vendor" child interface
4942 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4943 parentPrivate
->localized_key
= CFSTR("vpn");
4944 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4945 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4946 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4947 if (childPrivate
->entity_device
!= NULL
) {
4948 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4950 if (parentPrivate
->entity_subtype
!= NULL
) {
4951 CFArrayRef components
;
4953 CFStringRef vpnType
;
4956 // the "default" interface name is derived from the VPN type
4959 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4962 vpnType
= parentPrivate
->entity_subtype
;
4963 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4964 n
= CFArrayGetCount(components
);
4966 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4967 CFMutableStringRef str
;
4969 str
= CFStringCreateMutableCopy(NULL
,
4971 CFArrayGetValueAtIndex(components
, n
- 2));
4972 (void) CFStringFindAndReplace(str
,
4975 CFRangeMake(0, CFStringGetLength(str
)),
4977 parentPrivate
->localized_name
= str
;
4979 CFRelease(components
);
4981 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4982 // if custom interface type
4983 pthread_mutex_lock(&lock
);
4984 if (vendor_interface_types
== NULL
) {
4985 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4987 CFSetAddValue(vendor_interface_types
, interfaceType
);
4988 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4989 pthread_mutex_unlock(&lock
);
4991 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4992 // a dictionary with the same
4993 // name as the interfaceType
4995 // unknown interface type
4999 parentPrivate
->hidden
= childPrivate
->hidden
;
5001 if (childPrivate
->overrides
!= NULL
) {
5002 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5005 // The following change handles the case where a user has both an Ethernet and
5006 // PPPoE network service. Because a PPPoE service is typically associated with
5007 // an ISP we want it to be sorted higher in the service order.
5008 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5009 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5010 if ((childPrivate
->interface_type
!= NULL
) &&
5011 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5012 parentPrivate
->sort_order
= kSortAirportPPP
;
5014 parentPrivate
->sort_order
= kSortEthernetPPP
;
5017 // set sort order of the parent to match the child interface
5018 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5021 return (SCNetworkInterfaceRef
)parentPrivate
;
5025 CFRelease(parentPrivate
);
5026 _SCErrorSet(kSCStatusInvalidArgument
);
5033 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5035 CFDictionaryRef config
= NULL
;
5036 CFStringRef defaultType
;
5037 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5039 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5040 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5042 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5043 if (defaultType
!= NULL
) {
5047 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5048 SCNetworkSetGetSetID(set
), // set
5049 interfacePrivate
->entity_device
, // interface
5050 defaultType
); // entity
5052 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5055 if (config
== NULL
) {
5056 // if the "set" does not have a saved configuration, use
5057 // the [template] "interface" configuration
5058 if (interfacePrivate
->unsaved
!= NULL
) {
5059 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5060 if (config
== (CFDictionaryRef
)kCFNull
) {
5065 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5076 static CFDictionaryRef
5077 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5078 CFStringRef extendedType
)
5080 CFDictionaryRef config
= NULL
;
5081 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5084 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5085 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5087 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5088 if (paths
!= NULL
) {
5091 path
= CFArrayGetValueAtIndex(paths
, 0);
5092 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5096 if (interfacePrivate
->unsaved
!= NULL
) {
5097 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5098 if (config
== (CFDictionaryRef
)kCFNull
) {
5104 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5113 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5115 CFDictionaryRef config
;
5116 CFStringRef defaultType
;
5118 if (!isA_SCNetworkInterface(interface
)) {
5119 _SCErrorSet(kSCStatusInvalidArgument
);
5123 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5124 if (defaultType
== NULL
) {
5128 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5129 if (config
== NULL
) {
5130 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5131 SCNetworkInterfacePrivateRef interfacePrivate
;
5134 // if AirPort interface, check for a per-service config
5135 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5136 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5137 interfacePrivate
->serviceID
, // service
5138 kSCEntNetAirPort
); // entity
5139 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5143 if (config
== NULL
) {
5144 _SCErrorSet(kSCStatusOK
);
5152 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5153 CFStringRef extendedType
)
5155 CFDictionaryRef config
;
5157 if (!isA_SCNetworkInterface(interface
)) {
5158 _SCErrorSet(kSCStatusInvalidArgument
);
5162 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5163 _SCErrorSet(kSCStatusInvalidArgument
);
5167 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5168 if (config
== NULL
) {
5169 _SCErrorSet(kSCStatusOK
);
5178 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5180 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5182 return interfacePrivate
->entity_type
;
5188 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5190 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5192 return interfacePrivate
->entity_subtype
;
5197 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5199 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5201 if (!isA_SCNetworkInterface(interface
)) {
5202 _SCErrorSet(kSCStatusInvalidArgument
);
5206 if ((interfacePrivate
->interface
!= NULL
) &&
5207 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5208 _SCErrorSet(kSCStatusOK
);
5212 return interfacePrivate
->entity_device
;
5217 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5219 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5221 if (!isA_SCNetworkInterface(interface
)) {
5222 _SCErrorSet(kSCStatusInvalidArgument
);
5226 if ((interfacePrivate
->address
!= NULL
) &&
5227 (interfacePrivate
->addressString
== NULL
)) {
5231 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5234 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5235 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5237 if (n
> sizeof(mac
)) {
5238 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5241 for (cp
= mac_p
; n
> 0; n
-= 3) {
5242 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5245 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5246 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5249 return interfacePrivate
->addressString
;
5253 SCNetworkInterfaceRef
5254 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5256 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5258 if (!isA_SCNetworkInterface(interface
)) {
5259 _SCErrorSet(kSCStatusInvalidArgument
);
5263 return interfacePrivate
->interface
;
5268 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5270 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5272 if (!isA_SCNetworkInterface(interface
)) {
5273 _SCErrorSet(kSCStatusInvalidArgument
);
5277 return interfacePrivate
->interface_type
;
5282 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5284 CFStringRef str
= NULL
;
5287 str
= CFBundleCopyLocalizedString(bundle
,
5290 NETWORKINTERFACE_LOCALIZATIONS
);
5292 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5295 NETWORKINTERFACE_LOCALIZATIONS
);
5303 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5305 static Boolean reported
= FALSE
;
5306 CFStringRef str
= NULL
;
5308 str
= copy_string_from_bundle(bundle
, key
, localized
);
5311 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5317 if (CFEqual(str
, key
) && !reported
) {
5318 const CFStringRef knownStrKey
= CFSTR("airport");
5319 CFStringRef knownStrValue
= NULL
;
5321 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5322 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5323 /* We are here because we requested for a localized/non-localized string
5324 based on the localization key, but we were given the same key/NULL back,
5325 implying a bad...bad thing!
5327 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5331 #if TARGET_OS_IPHONE
5332 /* ...and we want to know about it! */
5333 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5334 #endif //TARGET_OS_IPHONE
5338 if (knownStrValue
!= NULL
) {
5339 CFRelease(knownStrValue
);
5349 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5351 CFMutableStringRef local
;
5354 local
= CFStringCreateMutable(NULL
, 0);
5356 while (interface
!= NULL
) {
5357 Boolean added
= FALSE
;
5358 SCNetworkInterfaceRef child
= NULL
;
5359 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5361 if ((interfacePrivate
->interface
!= NULL
) &&
5362 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5363 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5364 child
= interfacePrivate
->interface
;
5367 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5369 CFStringRef key
= interfacePrivate
->localized_key
;
5371 if (oldLocalization
) {
5372 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5373 interfacePrivate
->localized_key
);
5375 fmt
= copy_interface_string(bundle
, key
, localized
);
5377 CFStringAppendFormat(local
,
5380 interfacePrivate
->localized_arg1
,
5381 interfacePrivate
->localized_arg2
);
5385 if (oldLocalization
) {
5391 (interfacePrivate
->prefs
!= NULL
) &&
5392 (interfacePrivate
->serviceID
!= NULL
) &&
5394 CFDictionaryRef entity
;
5397 // check for (and use) the name of the interface when it
5398 // was last available
5399 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5400 interfacePrivate
->serviceID
,
5401 kSCEntNetInterface
);
5402 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5404 if (isA_CFDictionary(entity
)) {
5407 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5408 if (isA_CFString(name
)) {
5409 CFStringAppend(local
, name
);
5416 // create (non-)localized name based on the interface type
5417 CFStringAppend(local
, interfacePrivate
->interface_type
);
5419 // ... and, if this is a leaf node, the interface device
5420 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5421 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5425 if (child
!= NULL
) {
5426 // if this interface is layered over another
5427 CFStringAppend(local
, CFSTR(" --> "));
5433 name
= CFStringCreateCopy(NULL
, local
);
5440 #if !TARGET_OS_IPHONE
5443 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5447 if (!isA_SCNetworkInterface(interface
)) {
5448 _SCErrorSet(kSCStatusInvalidArgument
);
5452 name
= copy_display_name(interface
, TRUE
, TRUE
);
5459 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5461 CFStringRef localized_name
;
5463 if (!isA_SCNetworkInterface(interface
)) {
5464 _SCErrorSet(kSCStatusInvalidArgument
);
5468 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5469 return localized_name
;
5471 #endif // !TARGET_OS_IPHONE
5475 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5477 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5479 if (!isA_SCNetworkInterface(interface
)) {
5485 if (interfacePrivate
->name
!= NULL
) {
5486 CFRelease(interfacePrivate
->name
);
5488 interfacePrivate
->name
= name
;
5493 if (interfacePrivate
->localized_name
!= NULL
) {
5494 CFRelease(interfacePrivate
->localized_name
);
5496 interfacePrivate
->localized_name
= name
;
5501 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5503 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5505 if (!isA_SCNetworkInterface(interface
)) {
5509 return interfacePrivate
->name
;
5515 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5517 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5519 if (!isA_SCNetworkInterface(interface
)) {
5520 _SCErrorSet(kSCStatusInvalidArgument
);
5524 if (interfacePrivate
->name
== NULL
) {
5525 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5528 return interfacePrivate
->name
;
5533 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5535 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5537 if (!isA_SCNetworkInterface(interface
)) {
5538 _SCErrorSet(kSCStatusInvalidArgument
);
5542 if (interfacePrivate
->localized_name
== NULL
) {
5543 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5546 return interfacePrivate
->localized_name
;
5552 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5554 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5555 CFDictionaryRef overrides
= NULL
;
5557 if (interfacePrivate
->overrides
!= NULL
) {
5558 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5566 SCNetworkInterfaceGetTypeID(void)
5568 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5569 return __kSCNetworkInterfaceTypeID
;
5575 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5576 SCNetworkInterfaceRef interface
,
5577 CFStringRef defaultType
,
5578 CFDictionaryRef config
,
5581 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5584 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5585 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5587 if (defaultType
== NULL
) {
5588 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5589 if (defaultType
== NULL
) {
5594 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5601 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5602 SCNetworkSetGetSetID(set
), // set
5603 interfacePrivate
->entity_device
, // interface
5604 defaultType
); // entity
5606 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5609 // if configuration has been saved
5610 if (interfacePrivate
->unsaved
!= NULL
) {
5611 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5612 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5613 CFRelease(interfacePrivate
->unsaved
);
5614 interfacePrivate
->unsaved
= NULL
;
5620 if (config
== NULL
) {
5621 // remember that we are clearing the configuration
5622 config
= (CFDictionaryRef
)kCFNull
;
5625 if (interfacePrivate
->unsaved
== NULL
) {
5626 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5628 &kCFTypeDictionaryKeyCallBacks
,
5629 &kCFTypeDictionaryValueCallBacks
);
5631 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5634 _SCErrorSet(kSCStatusNoKey
);
5645 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5646 CFStringRef extendedType
,
5647 CFDictionaryRef config
,
5650 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5654 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5655 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5657 if (extendedType
== NULL
) {
5658 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5659 if (extendedType
== NULL
) {
5664 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5668 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5669 if (paths
!= NULL
) {
5673 n
= CFArrayGetCount(paths
);
5674 for (i
= 0; i
< n
; i
++) {
5677 path
= CFArrayGetValueAtIndex(paths
, i
);
5678 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5685 // if configuration has been saved
5686 if (interfacePrivate
->unsaved
!= NULL
) {
5687 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5688 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5689 CFRelease(interfacePrivate
->unsaved
);
5690 interfacePrivate
->unsaved
= NULL
;
5698 if (config
== NULL
) {
5699 // remember that we are clearing the configuration
5700 config
= (CFDictionaryRef
)kCFNull
;
5703 if (interfacePrivate
->unsaved
== NULL
) {
5704 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5706 &kCFTypeDictionaryKeyCallBacks
,
5707 &kCFTypeDictionaryValueCallBacks
);
5709 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5712 _SCErrorSet(kSCStatusNoKey
);
5721 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5723 CFStringRef defaultType
;
5726 if (!isA_SCNetworkInterface(interface
)) {
5727 _SCErrorSet(kSCStatusInvalidArgument
);
5731 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5732 if (defaultType
== NULL
) {
5736 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5738 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5740 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5748 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5749 CFStringRef extendedType
,
5750 CFDictionaryRef config
)
5754 if (!isA_SCNetworkInterface(interface
)) {
5755 _SCErrorSet(kSCStatusInvalidArgument
);
5759 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5763 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5765 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5767 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5775 #pragma mark SCNetworkInterface [Refresh Configuration] API
5778 #ifndef kSCEntNetRefreshConfiguration
5779 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5780 #endif // kSCEntNetRefreshConfiguration
5783 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5788 if (!isA_CFString(ifName
)) {
5789 _SCErrorSet(kSCStatusInvalidArgument
);
5793 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5794 kSCDynamicStoreDomainState
,
5796 kSCEntNetRefreshConfiguration
);
5797 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5804 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5806 CFDataRef data
= NULL
;
5808 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5809 uint32_t status
= kSCStatusOK
;
5810 CFDataRef reply
= NULL
;
5812 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5813 ok
= __SCPreferencesCreate_helper(prefs
);
5819 // serialize the interface name
5820 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5825 // have the helper "refresh" the configuration
5826 status
= kSCStatusOK
;
5828 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5829 SCHELPER_MSG_INTERFACE_REFRESH
,
5833 if (data
!= NULL
) CFRelease(data
);
5838 if (status
!= kSCStatusOK
) {
5847 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5848 _SCHelperClose(&prefsPrivate
->helper_port
);
5851 status
= kSCStatusAccessError
;
5856 _SCErrorSet(status
);
5862 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5865 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5867 if (!isA_SCNetworkInterface(interface
)) {
5868 _SCErrorSet(kSCStatusInvalidArgument
);
5872 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5873 if (ifName
== NULL
) {
5874 _SCErrorSet(kSCStatusInvalidArgument
);
5878 if (interfacePrivate
->prefs
!= NULL
) {
5879 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5880 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5882 if (prefsPrivate
->authorizationData
!= NULL
) {
5883 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5887 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5892 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5894 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5899 #pragma mark SCNetworkInterface Password APIs
5903 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5905 CFStringRef unique_id
= NULL
;
5907 if (config
!= NULL
) {
5908 CFStringRef encryption
;
5910 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5911 if (isA_CFString(encryption
) &&
5912 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5913 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5916 if (unique_id
== NULL
) {
5917 unique_id
= serviceID
;
5925 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5927 CFMutableStringRef shared_id
= NULL
;
5929 if (config
!= NULL
) {
5930 CFStringRef encryption
;
5932 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5933 if (isA_CFString(encryption
) &&
5934 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5935 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5936 if (shared_id
!= NULL
) {
5937 CFRetain(shared_id
);
5942 if (shared_id
== NULL
) {
5943 CFStringRef unique_id
;
5945 unique_id
= getPasswordID(config
, serviceID
);
5946 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5947 CFStringAppend(shared_id
, CFSTR(".SS"));
5955 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5957 CFMutableStringRef xauth_id
= NULL
;
5959 if (config
!= NULL
) {
5960 CFStringRef encryption
;
5962 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
5963 if (isA_CFString(encryption
) &&
5964 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
5965 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
5966 if (xauth_id
!= NULL
) {
5972 if (xauth_id
== NULL
) {
5973 CFStringRef unique_id
;
5975 unique_id
= getPasswordID(config
, serviceID
);
5976 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5977 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
5985 checkInterfacePassword(SCNetworkInterfaceRef interface
,
5986 SCNetworkInterfacePasswordType passwordType
,
5987 SCPreferencesRef
*prefs
,
5988 CFStringRef
*serviceID
)
5990 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5992 if (!isA_SCNetworkInterface(interface
)) {
5996 *serviceID
= interfacePrivate
->serviceID
;
5997 if (*serviceID
== NULL
) {
6001 *prefs
= interfacePrivate
->prefs
;
6002 if (*prefs
== NULL
) {
6006 switch (passwordType
) {
6007 case kSCNetworkInterfacePasswordTypePPP
: {
6008 CFStringRef interfaceType
;
6010 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6011 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6019 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6020 CFStringRef interfaceType
;
6022 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6023 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6024 interface
= SCNetworkInterfaceGetInterface(interface
);
6025 if (interface
!= NULL
) {
6026 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6027 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6028 // if PPP->L2TP interface
6032 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6033 // if IPSec interface
6040 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6044 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6045 CFStringRef interfaceType
;
6047 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6048 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6049 // if IPSec interface
6056 case kSCNetworkInterfacePasswordTypeVPN
: {
6057 CFStringRef interfaceType
;
6059 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6060 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6076 _SCErrorSet(kSCStatusInvalidArgument
);
6082 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6083 SCNetworkInterfacePasswordType passwordType
)
6085 Boolean exists
= FALSE
;
6086 SCPreferencesRef prefs
= NULL
;
6087 CFStringRef serviceID
= NULL
;
6089 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6093 switch (passwordType
) {
6094 case kSCNetworkInterfacePasswordTypePPP
: {
6095 CFDictionaryRef config
;
6096 CFStringRef unique_id
;
6098 // get configuration
6099 config
= SCNetworkInterfaceGetConfiguration(interface
);
6102 unique_id
= getPasswordID(config
, serviceID
);
6105 exists
= __extract_password(prefs
,
6107 kSCPropNetPPPAuthPassword
,
6108 kSCPropNetPPPAuthPasswordEncryption
,
6109 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6115 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6116 CFDictionaryRef config
;
6118 CFStringRef shared_id
;
6120 // get configuration
6121 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6123 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6125 config
= SCNetworkInterfaceGetConfiguration(interface
);
6128 // get sharedSecret ID
6129 shared_id
= copySharedSecretID(config
, serviceID
);
6132 exists
= __extract_password(prefs
,
6134 kSCPropNetIPSecSharedSecret
,
6135 kSCPropNetIPSecSharedSecretEncryption
,
6136 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6139 CFRelease(shared_id
);
6143 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6144 CFDictionaryRef config
;
6145 CFStringRef unique_id
= NULL
;
6147 // get configuration
6148 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6150 // get 802.1X identifier
6151 if (config
!= NULL
) {
6152 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6154 if (!isA_CFString(unique_id
)) {
6159 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6163 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6164 CFDictionaryRef config
;
6165 CFStringRef xauth_id
;
6167 // get configuration
6168 config
= SCNetworkInterfaceGetConfiguration(interface
);
6171 xauth_id
= copyXAuthID(config
, serviceID
);
6174 exists
= __extract_password(prefs
,
6176 kSCPropNetIPSecXAuthPassword
,
6177 kSCPropNetIPSecXAuthPasswordEncryption
,
6178 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6181 CFRelease(xauth_id
);
6185 case kSCNetworkInterfacePasswordTypeVPN
: {
6186 CFDictionaryRef config
;
6189 // get configuration
6190 config
= SCNetworkInterfaceGetConfiguration(interface
);
6193 vpn_id
= getPasswordID(config
, serviceID
);
6196 exists
= __extract_password(prefs
,
6198 kSCPropNetVPNAuthPassword
,
6199 kSCPropNetVPNAuthPasswordEncryption
,
6200 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6207 _SCErrorSet(kSCStatusInvalidArgument
);
6216 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6217 SCNetworkInterfacePasswordType passwordType
)
6219 CFDataRef password
= NULL
;
6220 SCPreferencesRef prefs
= NULL
;
6221 CFStringRef serviceID
= NULL
;
6223 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6227 switch (passwordType
) {
6228 case kSCNetworkInterfacePasswordTypePPP
: {
6229 CFDictionaryRef config
;
6230 CFStringRef unique_id
;
6232 // get configuration
6233 config
= SCNetworkInterfaceGetConfiguration(interface
);
6236 unique_id
= getPasswordID(config
, serviceID
);
6239 (void) __extract_password(prefs
,
6241 kSCPropNetPPPAuthPassword
,
6242 kSCPropNetPPPAuthPasswordEncryption
,
6243 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6249 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6250 CFDictionaryRef config
;
6252 CFStringRef shared_id
;
6254 // get configuration
6255 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6257 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6259 config
= SCNetworkInterfaceGetConfiguration(interface
);
6262 // get sharedSecret ID
6263 shared_id
= copySharedSecretID(config
, serviceID
);
6266 (void) __extract_password(prefs
,
6268 kSCPropNetIPSecSharedSecret
,
6269 kSCPropNetIPSecSharedSecretEncryption
,
6270 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6274 CFRelease(shared_id
);
6278 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6279 CFDictionaryRef config
;
6280 CFStringRef unique_id
= NULL
;
6282 // get configuration
6283 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6285 // get 802.1X identifier
6286 if (config
!= NULL
) {
6287 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6289 if (!isA_CFString(unique_id
)) {
6290 _SCErrorSet(kSCStatusFailed
);
6295 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6299 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6300 CFDictionaryRef config
;
6301 CFStringRef xauth_id
;
6303 // get configuration
6304 config
= SCNetworkInterfaceGetConfiguration(interface
);
6307 xauth_id
= copyXAuthID(config
, serviceID
);
6310 (void) __extract_password(prefs
,
6312 kSCPropNetIPSecXAuthPassword
,
6313 kSCPropNetIPSecXAuthPasswordEncryption
,
6314 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6317 CFRelease(xauth_id
);
6321 case kSCNetworkInterfacePasswordTypeVPN
: {
6322 CFDictionaryRef config
;
6325 // get configuration
6326 config
= SCNetworkInterfaceGetConfiguration(interface
);
6329 vpn_id
= getPasswordID(config
, serviceID
);
6332 (void) __extract_password(prefs
,
6334 kSCPropNetVPNAuthPassword
,
6335 kSCPropNetVPNAuthPasswordEncryption
,
6336 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6343 _SCErrorSet(kSCStatusInvalidArgument
);
6352 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6353 SCNetworkInterfacePasswordType passwordType
)
6356 SCPreferencesRef prefs
= NULL
;
6357 CFStringRef serviceID
= NULL
;
6359 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6363 switch (passwordType
) {
6364 case kSCNetworkInterfacePasswordTypePPP
: {
6365 CFDictionaryRef config
;
6366 CFDictionaryRef newConfig
= NULL
;
6367 CFStringRef unique_id
;
6369 // get configuration
6370 config
= SCNetworkInterfaceGetConfiguration(interface
);
6373 unique_id
= getPasswordID(config
, serviceID
);
6376 ok
= __remove_password(prefs
,
6378 kSCPropNetPPPAuthPassword
,
6379 kSCPropNetPPPAuthPasswordEncryption
,
6380 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6384 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6385 if (newConfig
!= NULL
) CFRelease(newConfig
);
6391 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6392 CFDictionaryRef config
;
6394 CFDictionaryRef newConfig
= NULL
;
6395 CFStringRef shared_id
;
6397 // get configuration
6398 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6400 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6402 config
= SCNetworkInterfaceGetConfiguration(interface
);
6405 // get sharedSecret ID
6406 shared_id
= copySharedSecretID(config
, serviceID
);
6409 ok
= __remove_password(prefs
,
6411 kSCPropNetIPSecSharedSecret
,
6412 kSCPropNetIPSecSharedSecretEncryption
,
6413 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6418 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6422 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6425 if (newConfig
!= NULL
) CFRelease(newConfig
);
6428 CFRelease(shared_id
);
6432 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6433 CFDictionaryRef config
;
6434 CFStringRef unique_id
= NULL
;
6436 // get configuration
6437 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6439 // get 802.1X identifier
6440 if (config
!= NULL
) {
6441 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6443 if (!isA_CFString(unique_id
)) {
6444 _SCErrorSet(kSCStatusFailed
);
6449 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6453 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6454 CFDictionaryRef config
;
6455 CFDictionaryRef newConfig
= NULL
;
6456 CFStringRef xauth_id
;
6458 // get configuration
6459 config
= SCNetworkInterfaceGetConfiguration(interface
);
6462 xauth_id
= copyXAuthID(config
, serviceID
);
6465 ok
= __remove_password(prefs
,
6467 kSCPropNetIPSecXAuthPassword
,
6468 kSCPropNetIPSecXAuthPasswordEncryption
,
6469 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6473 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6474 if (newConfig
!= NULL
) CFRelease(newConfig
);
6477 CFRelease(xauth_id
);
6481 case kSCNetworkInterfacePasswordTypeVPN
: {
6482 CFDictionaryRef config
;
6483 CFDictionaryRef newConfig
= NULL
;
6486 // get configuration
6487 config
= SCNetworkInterfaceGetConfiguration(interface
);
6490 vpn_id
= getPasswordID(config
, serviceID
);
6493 ok
= __remove_password(prefs
,
6495 kSCPropNetVPNAuthPassword
,
6496 kSCPropNetVPNAuthPasswordEncryption
,
6497 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6501 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6502 if (newConfig
!= NULL
) CFRelease(newConfig
);
6508 _SCErrorSet(kSCStatusInvalidArgument
);
6517 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6518 SCNetworkInterfacePasswordType passwordType
,
6520 CFDictionaryRef options
)
6522 CFStringRef account
= NULL
;
6523 CFDictionaryRef config
;
6524 CFStringRef description
= NULL
;
6525 CFStringRef label
= NULL
;
6527 SCPreferencesRef prefs
= NULL
;
6528 CFStringRef serviceID
= NULL
;
6530 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6534 switch (passwordType
) {
6535 case kSCNetworkInterfacePasswordTypePPP
: {
6536 SCNetworkServiceRef service
= NULL
;
6537 CFStringRef unique_id
;
6539 // get configuration
6540 config
= SCNetworkInterfaceGetConfiguration(interface
);
6543 unique_id
= getPasswordID(config
, serviceID
);
6545 // get "Account", "Name", "Kind"
6546 if (config
!= NULL
) {
6547 // auth name --> keychain "Account"
6548 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6550 // PPP [user defined] "name" --> keychain "Name"
6551 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6554 if (label
== NULL
) {
6555 // service name --> keychain "Name"
6556 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6561 label
= SCNetworkServiceGetName(service
);
6562 if (label
== NULL
) {
6563 // interface name --> keychain "Name"
6564 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6568 if (bundle
!= NULL
) {
6569 // "PPP Password" --> keychain "Kind"
6570 description
= CFBundleCopyLocalizedString(bundle
,
6571 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6572 CFSTR("PPP Password"),
6577 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6579 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6580 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6585 CFMutableDictionaryRef newConfig
;
6587 if (config
!= NULL
) {
6588 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6590 newConfig
= CFDictionaryCreateMutable(NULL
,
6592 &kCFTypeDictionaryKeyCallBacks
,
6593 &kCFTypeDictionaryValueCallBacks
);
6595 CFDictionarySetValue(newConfig
,
6596 kSCPropNetPPPAuthPassword
,
6598 CFDictionarySetValue(newConfig
,
6599 kSCPropNetPPPAuthPasswordEncryption
,
6600 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6601 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6602 CFRelease(newConfig
);
6605 if (description
!= NULL
) CFRelease(description
);
6606 if (service
!= NULL
) CFRelease(service
);
6610 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6611 CFDictionaryRef baseConfig
= NULL
;
6613 SCNetworkServiceRef service
= NULL
;
6614 CFStringRef shared_id
;
6616 // get configuration
6617 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6618 config
= SCNetworkInterfaceGetConfiguration(interface
);
6620 baseConfig
= config
;
6621 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6624 // get sharedSecret ID
6625 shared_id
= copySharedSecretID(config
, serviceID
);
6627 // get "Account", "Name", "Kind"
6628 if (config
!= NULL
) {
6629 CFStringRef localIdentifier
;
6630 CFStringRef localIdentifierType
;
6632 if (CFDictionaryGetValueIfPresent(config
,
6633 kSCPropNetIPSecLocalIdentifierType
,
6634 (const void **)&localIdentifierType
)
6635 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6636 && CFDictionaryGetValueIfPresent(config
,
6637 kSCPropNetIPSecLocalIdentifier
,
6638 (const void **)&localIdentifier
)
6639 && isA_CFString(localIdentifier
)) {
6640 // local identifier --> keychain "Account"
6641 account
= localIdentifier
;
6644 // PPP [user defined] "name" --> keychain "Name"
6646 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6648 if (baseConfig
!= NULL
) {
6649 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6654 if (label
== NULL
) {
6655 // service name --> keychain "Name"
6656 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6661 label
= SCNetworkServiceGetName(service
);
6662 if (label
== NULL
) {
6663 // interface name --> keychain "Name"
6664 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6668 if (bundle
!= NULL
) {
6669 // "IPSec Shared Secret" --> keychain "Kind"
6670 description
= CFBundleCopyLocalizedString(bundle
,
6671 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6672 CFSTR("IPSec Shared Secret"),
6677 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6679 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6680 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6685 CFMutableDictionaryRef newConfig
= NULL
;
6687 if (config
!= NULL
) {
6688 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6690 newConfig
= CFDictionaryCreateMutable(NULL
,
6692 &kCFTypeDictionaryKeyCallBacks
,
6693 &kCFTypeDictionaryValueCallBacks
);
6695 CFDictionarySetValue(newConfig
,
6696 kSCPropNetIPSecSharedSecret
,
6698 CFDictionarySetValue(newConfig
,
6699 kSCPropNetIPSecSharedSecretEncryption
,
6700 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6702 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6706 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6708 CFRelease(newConfig
);
6711 if (description
!= NULL
) CFRelease(description
);
6712 if (service
!= NULL
) CFRelease(service
);
6713 CFRelease(shared_id
);
6717 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6718 CFStringRef account
= NULL
;
6719 CFStringRef unique_id
= NULL
;
6721 // get configuration
6722 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6724 // get 802.1X identifier
6725 if (config
!= NULL
) {
6726 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6727 unique_id
= isA_CFString(unique_id
);
6729 if (unique_id
!= NULL
) {
6730 CFRetain(unique_id
);
6734 uuid
= CFUUIDCreate(NULL
);
6735 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6739 // 802.1x UserName --> keychain "Account"
6740 if (config
!= NULL
) {
6741 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6744 // get "Name", "Kind"
6745 if (bundle
!= NULL
) {
6746 CFStringRef interface_name
;
6748 // "Network Connection (%@)" --> keychain "Name"
6749 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6750 if (interface_name
!= NULL
) {
6751 CFStringRef label_fmt
;
6753 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6754 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6755 CFSTR("Network Connection (%@)"),
6757 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6758 CFRelease(label_fmt
);
6760 label
= CFBundleCopyLocalizedString(bundle
,
6761 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6762 CFSTR("Network Connection"),
6766 // "802.1X Password" --> keychain "Kind"
6767 description
= CFBundleCopyLocalizedString(bundle
,
6768 CFSTR("KEYCHAIN_KIND_EAPOL"),
6769 CFSTR("802.1X Password"),
6774 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6776 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6777 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6782 CFMutableDictionaryRef newConfig
= NULL
;
6784 if (config
!= NULL
) {
6785 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6787 newConfig
= CFDictionaryCreateMutable(NULL
,
6789 &kCFTypeDictionaryKeyCallBacks
,
6790 &kCFTypeDictionaryValueCallBacks
);
6792 CFDictionarySetValue(newConfig
,
6793 kEAPClientPropUserPasswordKeychainItemID
,
6795 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6798 CFRelease(newConfig
);
6801 CFRelease(unique_id
);
6802 if (label
!= NULL
) CFRelease(label
);
6803 if (description
!= NULL
) CFRelease(description
);
6807 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6808 SCNetworkServiceRef service
= NULL
;
6809 CFStringRef xauth_id
;
6811 // get configuration
6812 config
= SCNetworkInterfaceGetConfiguration(interface
);
6815 xauth_id
= copyXAuthID(config
, serviceID
);
6817 // get "Account", "Name", "Kind"
6818 if (config
!= NULL
) {
6819 // auth name --> keychain "Account"
6820 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6822 // IPSec [user defined] "name" --> keychain "Name"
6823 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6826 if (label
== NULL
) {
6827 // service name --> keychain "Name"
6828 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6833 label
= SCNetworkServiceGetName(service
);
6834 if (label
== NULL
) {
6835 // interface name --> keychain "Name"
6836 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6840 if (bundle
!= NULL
) {
6841 // "IPSec XAuth Password" --> keychain "Kind"
6842 description
= CFBundleCopyLocalizedString(bundle
,
6843 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6844 CFSTR("IPSec XAuth Password"),
6849 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6851 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6852 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6857 CFMutableDictionaryRef newConfig
;
6859 if (config
!= NULL
) {
6860 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6862 newConfig
= CFDictionaryCreateMutable(NULL
,
6864 &kCFTypeDictionaryKeyCallBacks
,
6865 &kCFTypeDictionaryValueCallBacks
);
6867 CFDictionarySetValue(newConfig
,
6868 kSCPropNetIPSecXAuthPassword
,
6870 CFDictionarySetValue(newConfig
,
6871 kSCPropNetIPSecXAuthPasswordEncryption
,
6872 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6873 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6874 CFRelease(newConfig
);
6877 CFRelease(xauth_id
);
6878 if (description
!= NULL
) CFRelease(description
);
6879 if (service
!= NULL
) CFRelease(service
);
6883 case kSCNetworkInterfacePasswordTypeVPN
: {
6884 SCNetworkServiceRef service
= NULL
;
6887 // get configuration
6888 config
= SCNetworkInterfaceGetConfiguration(interface
);
6891 vpn_id
= getPasswordID(config
, serviceID
);
6893 // get "Account", "Name", "Kind"
6894 if (config
!= NULL
) {
6895 // auth name --> keychain "Account"
6896 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6898 // VPN [user defined] "name" --> keychain "Name"
6899 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6902 if (label
== NULL
) {
6903 // service name --> keychain "Name"
6904 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6909 label
= SCNetworkServiceGetName(service
);
6910 if (label
== NULL
) {
6911 // interface name --> keychain "Name"
6912 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6916 if (bundle
!= NULL
) {
6917 // "VPN Password" --> keychain "Kind"
6918 description
= CFBundleCopyLocalizedString(bundle
,
6919 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6920 CFSTR("VPN Password"),
6925 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6927 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6928 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6933 CFMutableDictionaryRef newConfig
;
6935 if (config
!= NULL
) {
6936 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6938 newConfig
= CFDictionaryCreateMutable(NULL
,
6940 &kCFTypeDictionaryKeyCallBacks
,
6941 &kCFTypeDictionaryValueCallBacks
);
6943 CFDictionarySetValue(newConfig
,
6944 kSCPropNetVPNAuthPassword
,
6946 CFDictionarySetValue(newConfig
,
6947 kSCPropNetVPNAuthPasswordEncryption
,
6948 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6949 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6950 CFRelease(newConfig
);
6953 if (description
!= NULL
) CFRelease(description
);
6954 if (service
!= NULL
) CFRelease(service
);
6959 _SCErrorSet(kSCStatusInvalidArgument
);
6968 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
6972 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
6974 CFMutableDictionaryRef info
;
6975 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6978 if (interface
== NULL
) {
6982 info
= CFDictionaryCreateMutable(NULL
,
6984 &kCFTypeDictionaryKeyCallBacks
,
6985 &kCFTypeDictionaryValueCallBacks
);
6987 // add non-localized interface name
6988 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
6990 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
6994 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
6995 #if !TARGET_OS_SIMULATOR
6996 if (interfacePrivate
->usb
.name
!= NULL
) {
6997 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
6999 if (interfacePrivate
->usb
.vid
!= NULL
) {
7000 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
7002 if (interfacePrivate
->usb
.pid
!= NULL
) {
7003 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
7005 #endif // !TARGET_OS_SIMULATOR
7008 if (CFDictionaryGetCount(info
) == 0) {
7009 // do not return an empty dictionary
7018 SCNetworkInterfaceRef
7019 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7021 SCNetworkInterfaceRef interface
= NULL
;
7023 /* initialize runtime */
7024 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7026 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7027 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
7028 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7029 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
7037 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7039 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7041 return interfacePrivate
->configurationAction
;
7046 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7048 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7050 return interfacePrivate
->address
;
7055 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7057 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7059 return interfacePrivate
->prefix
;
7064 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7066 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7068 return interfacePrivate
->type
;
7073 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7075 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7077 return interfacePrivate
->unit
;
7082 update_ift_family(SCNetworkInterfaceRef interface
)
7084 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7086 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7088 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7089 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7092 bzero(&ifr
, sizeof(ifr
));
7093 if ((bsdName
!= NULL
) &&
7094 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7097 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7099 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7100 ifr
.ifr_type
.ift_family
= 0;
7101 ifr
.ifr_type
.ift_subfamily
= 0;
7107 interfacePrivate
->family
= CFNumberCreate(NULL
,
7108 kCFNumberSInt32Type
,
7109 &ifr
.ifr_type
.ift_family
);
7110 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7111 kCFNumberSInt32Type
,
7112 &ifr
.ifr_type
.ift_subfamily
);
7118 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7120 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7122 // note: family not in IORegistry, fetch with ioctl()
7124 if (interfacePrivate
->family
== NULL
) {
7125 update_ift_family(interface
);
7128 return interfacePrivate
->family
;
7133 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7135 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7137 // note: subfamily not in IORegistry, fetch with ioctl()
7139 if (interfacePrivate
->subfamily
== NULL
) {
7140 update_ift_family(interface
);
7143 return interfacePrivate
->subfamily
;
7148 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7150 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7152 return interfacePrivate
->path
;
7157 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7159 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7161 return interfacePrivate
->entryID
;
7167 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7169 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7171 return interfacePrivate
->active
;
7176 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7178 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7180 return interfacePrivate
->builtin
;
7185 #pragma mark SCNetworkInterface SPIs
7188 #if !TARGET_OS_EMBEDDED
7190 SCNetworkInterfaceRef
7191 _SCNetworkInterfaceCopyBTPANInterface(void)
7193 CFDictionaryRef dict
;
7194 SCNetworkInterfaceRef interface
= NULL
;
7197 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7198 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7202 CFStringRef if_name
;
7203 SCNetworkInterfacePrivateRef interfacePrivate
;
7205 if (isA_CFDictionary(dict
) &&
7206 CFDictionaryGetValueIfPresent(dict
,
7207 kInterfaceNamerKey_BT_PAN_Name
,
7208 (const void **)&if_name
) &&
7209 isA_CFString(if_name
)) {
7210 CFMutableDictionaryRef entity
;
7212 entity
= CFDictionaryCreateMutable(NULL
,
7214 &kCFTypeDictionaryKeyCallBacks
,
7215 &kCFTypeDictionaryValueCallBacks
);
7216 CFDictionarySetValue(entity
,
7217 kSCPropNetInterfaceType
,
7218 kSCValNetInterfaceTypeEthernet
);
7219 CFDictionarySetValue(entity
,
7220 kSCPropNetInterfaceDeviceName
,
7222 CFDictionarySetValue(entity
,
7223 kSCPropUserDefinedName
,
7224 CFSTR(BT_PAN_NAME
));
7225 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7229 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7231 if ((interfacePrivate
!= NULL
) &&
7232 (interfacePrivate
->address
== NULL
) &&
7233 CFDictionaryGetValueIfPresent(dict
,
7234 kInterfaceNamerKey_BT_PAN_Mac
,
7235 (const void **)&addr
) &&
7237 interfacePrivate
->address
= CFRetain(addr
);
7245 #endif // !TARGET_OS_EMBEDDED
7249 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7251 io_registry_entry_t device
;
7252 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7253 CFStringRef device_path
= NULL
;
7254 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7256 CFStringRef match_keys
[2];
7257 CFTypeRef match_vals
[2];
7258 CFDictionaryRef match_dict
;
7259 CFDictionaryRef matching
;
7261 if (interfacePrivate
->entity_device
== NULL
) {
7265 if (interfacePrivate
->entity_device_unique
== NULL
) {
7269 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7270 match_vals
[0] = interfacePrivate
->entity_device
;
7271 match_dict
= CFDictionaryCreate(NULL
,
7272 (const void **)match_keys
,
7273 (const void **)match_vals
,
7275 &kCFTypeDictionaryKeyCallBacks
,
7276 &kCFTypeDictionaryValueCallBacks
);
7278 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7279 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7280 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7281 match_vals
[1] = match_dict
;
7282 matching
= CFDictionaryCreate(NULL
,
7283 (const void **)match_keys
,
7284 (const void **)match_vals
,
7285 sizeof(match_keys
)/sizeof(match_keys
[0]),
7286 &kCFTypeDictionaryKeyCallBacks
,
7287 &kCFTypeDictionaryValueCallBacks
);
7288 CFRelease(match_dict
);
7290 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7291 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7292 if (kr
!= kIOReturnSuccess
) {
7293 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7297 while ((device_path
== NULL
) &&
7298 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7299 CFDictionaryRef overrides
;
7301 overrides
= IORegistryEntrySearchCFProperty(device
,
7303 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7305 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7306 if (overrides
!= NULL
) {
7307 CFDictionaryRef modemOverrides
;
7309 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7310 if (modemOverrides
!= NULL
) {
7311 CFRetain(modemOverrides
);
7313 CFRelease(overrides
);
7314 overrides
= modemOverrides
;
7316 if (overrides
== NULL
) {
7317 overrides
= IORegistryEntrySearchCFProperty(device
,
7319 CFSTR("DeviceModemOverrides"),
7321 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7323 if (overrides
!= NULL
) {
7324 if (isA_CFDictionary(overrides
)) {
7325 CFStringRef matchIdentifier
;
7327 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7328 if (isA_CFString(matchIdentifier
) &&
7329 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7330 device_path
= IORegistryEntryCreateCFProperty(device
,
7331 CFSTR(kIOTTYDeviceKey
),
7336 CFRelease(overrides
);
7338 IOObjectRelease(device
);
7341 IOObjectRelease(device_iterator
);
7345 if (device_path
== NULL
) {
7346 // if we haven't found an exact match to our UniqueIdentifier
7347 // so we simply return the base name.
7348 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7349 if (device_path
!= NULL
) {
7350 CFRetain(device_path
);
7362 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7364 #if TARGET_OS_SIMULATOR
7365 #pragma unused(interface)
7366 #else // TARGET_OS_SIMULATOR
7367 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7369 if (!interfacePrivate
->hidden
) {
7370 // if not HiddenConfiguration
7374 if ((interfacePrivate
->overrides
== NULL
) ||
7375 (!CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) &&
7376 !CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7377 // if no [IPv4/IPv6] configuration overrides
7381 if (interfacePrivate
->builtin
) {
7382 // if built-in (and overrides are present)
7386 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7389 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7390 (vid
== kIOUSBVendorIDAppleComputer
)) {
7391 // if Apple interface (and overrides are present)
7395 #endif // TARGET_OS_SIMULATOR
7402 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7404 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7406 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7411 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7413 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7415 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7420 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7422 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7424 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7429 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7431 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7433 return interfacePrivate
->hidden
;
7438 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7440 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7442 return (interfacePrivate
->sort_order
== kSortTethered
);
7447 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7449 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7450 CFStringRef interfaceType
;
7452 if (!isA_SCNetworkInterface(interface
)) {
7456 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7457 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7462 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7463 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7465 // if an empty bridge
7469 for (i
= 0; i
< n
; i
++) {
7470 SCNetworkInterfaceRef member
;
7471 SCNetworkInterfacePrivateRef memberPrivate
;
7473 member
= CFArrayGetValueAtIndex(members
, i
);
7474 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7475 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7480 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7484 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7492 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7494 CFDictionaryRef policy
;
7496 if (!isA_SCNetworkInterface(interface
)) {
7497 _SCErrorSet(kSCStatusInvalidArgument
);
7501 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7502 if (policy
== NULL
) {
7503 _SCErrorSet(kSCStatusOK
);
7510 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7514 if (!isA_SCNetworkInterface(interface
)) {
7515 _SCErrorSet(kSCStatusInvalidArgument
);
7519 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7521 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7523 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7531 #pragma mark SCNetworkInterface [internal] SPIs
7535 SCNetworkInterfacePrivateRef
7536 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7537 SCNetworkInterfaceRef interface
,
7538 SCPreferencesRef prefs
,
7539 CFStringRef serviceID
)
7541 #pragma unused(allocator)
7542 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7543 SCNetworkInterfacePrivateRef newPrivate
;
7545 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7546 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7548 if (interface
== kSCNetworkInterfaceIPv4
) {
7549 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7552 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7553 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7554 if (oldPrivate
->interface
!= NULL
) {
7555 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7556 oldPrivate
->interface
, // interface
7557 prefs
, // [new] prefs
7558 serviceID
); // [new] serviceID
7560 if (oldPrivate
->name
!= NULL
) {
7561 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7563 if (oldPrivate
->prefix
!= NULL
) {
7564 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7566 if (oldPrivate
->localized_name
!= NULL
) {
7567 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7569 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7570 if (oldPrivate
->localized_arg1
!= NULL
) {
7571 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7573 if (oldPrivate
->localized_arg2
!= NULL
) {
7574 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7576 if (oldPrivate
->unsaved
!= NULL
) {
7577 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7579 if (oldPrivate
->entity_device
!= NULL
) {
7580 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7582 if (oldPrivate
->entity_device_unique
!= NULL
) {
7583 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7585 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7586 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7587 if (oldPrivate
->supported_interface_types
!= NULL
) {
7588 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7590 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7591 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7593 if (oldPrivate
->address
!= NULL
) {
7594 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7596 newPrivate
->builtin
= oldPrivate
->builtin
;
7597 if (oldPrivate
->configurationAction
!= NULL
) {
7598 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7600 newPrivate
->hidden
= oldPrivate
->hidden
;
7601 if (oldPrivate
->location
!= NULL
) {
7602 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7604 if (oldPrivate
->path
!= NULL
) {
7605 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7607 newPrivate
->entryID
= oldPrivate
->entryID
;
7608 if (oldPrivate
->overrides
!= NULL
) {
7609 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7611 if (oldPrivate
->type
!= NULL
) {
7612 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7614 if (oldPrivate
->unit
!= NULL
) {
7615 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7617 if (oldPrivate
->family
!= NULL
) {
7618 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7620 if (oldPrivate
->subfamily
!= NULL
) {
7621 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7623 if (oldPrivate
->usb
.name
!= NULL
) {
7624 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7626 if (oldPrivate
->usb
.vid
!= NULL
) {
7627 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7629 if (oldPrivate
->usb
.pid
!= NULL
) {
7630 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7632 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7634 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7635 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7636 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7638 if (oldPrivate
->bond
.mode
!= NULL
) {
7639 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7641 if (oldPrivate
->bond
.options
!= NULL
) {
7642 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7645 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7646 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7647 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7649 if (oldPrivate
->bridge
.options
!= NULL
) {
7650 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7653 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7654 if (oldPrivate
->vlan
.interface
!= NULL
) {
7655 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7657 if (oldPrivate
->vlan
.tag
!= NULL
) {
7658 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7660 if (oldPrivate
->vlan
.options
!= NULL
) {
7661 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7670 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7672 CFMutableArrayRef configs
;
7674 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7676 while (interface
!= NULL
) {
7677 CFStringRef defaultType
;
7678 CFMutableDictionaryRef interfaceConfiguration
;
7680 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7682 &kCFTypeDictionaryKeyCallBacks
,
7683 &kCFTypeDictionaryValueCallBacks
);
7685 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7686 if (defaultType
!= NULL
) {
7687 CFDictionaryRef config
;
7688 CFArrayRef extendedTypes
;
7691 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7693 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7695 if (config
== NULL
) {
7696 config
= (CFDictionaryRef
)kCFNull
;
7698 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7700 extendedTypes
= extendedConfigurationTypes(interface
);
7701 if (extendedTypes
!= NULL
) {
7705 n
= CFArrayGetCount(extendedTypes
);
7706 for (i
= 0; i
< n
; i
++) {
7707 CFStringRef extendedType
;
7709 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7710 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7711 if (config
== NULL
) {
7712 config
= (CFDictionaryRef
)kCFNull
;
7714 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7717 CFRelease(extendedTypes
);
7721 CFArrayAppendValue(configs
, interfaceConfiguration
);
7722 CFRelease(interfaceConfiguration
);
7724 interface
= SCNetworkInterfaceGetInterface(interface
);
7731 __private_extern__ Boolean
7732 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7734 CFArrayRef interfaces
;
7735 Boolean match
= FALSE
;
7736 CFMutableSetRef members
;
7738 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7740 #if !TARGET_OS_IPHONE
7741 // add Bond [member] interfaces
7742 interfaces
= SCBondInterfaceCopyAll(prefs
);
7743 if (interfaces
!= NULL
) {
7744 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7745 CFRelease(interfaces
);
7747 #endif // !TARGET_OS_IPHONE
7749 // add Bridge [member] interfaces
7750 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7751 if (interfaces
!= NULL
) {
7752 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7753 CFRelease(interfaces
);
7756 if (CFSetGetCount(members
) == 0) {
7760 while (interface
!= NULL
) {
7761 match
= CFSetContainsValue(members
, interface
);
7763 // if the interface is a member of an
7764 // Ethernet Bond or Bridge
7768 interface
= SCNetworkInterfaceGetInterface(interface
);
7780 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7784 for (i
= 0; interface
!= NULL
; i
++) {
7785 CFStringRef defaultType
;
7786 CFDictionaryRef interfaceConfiguration
;
7789 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7791 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7792 if (defaultType
!= NULL
) {
7793 CFDictionaryRef config
;
7794 CFArrayRef extendedTypes
;
7796 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7798 if (config
== (CFDictionaryRef
)kCFNull
) {
7802 // if service is not associated with the set
7803 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
7805 // apply default configuration to this set
7806 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
7809 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7812 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7814 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7819 extendedTypes
= extendedConfigurationTypes(interface
);
7820 if (extendedTypes
!= NULL
) {
7824 n
= CFArrayGetCount(extendedTypes
);
7825 for (j
= 0; j
< n
; j
++) {
7826 CFStringRef extendedType
;
7828 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7829 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7831 if (config
== (CFDictionaryRef
)kCFNull
) {
7834 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
7836 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7839 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7841 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7847 CFRelease(extendedTypes
);
7851 interface
= SCNetworkInterfaceGetInterface(interface
);
7858 SCNetworkInterfaceRef
7859 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
7861 SCNetworkInterfaceRef interface
;
7863 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
7864 if (interface
== NULL
) {
7868 if (store
!= NULL
) {
7869 SCNetworkInterfacePrivateRef interfacePrivate
=
7870 (SCNetworkInterfacePrivateRef
)interface
;
7873 interfacePrivate
->store
= store
;
7880 #if !TARGET_OS_SIMULATOR
7881 SCNetworkServicePrimaryRank
7882 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7884 IPMonitorControlRef control
;
7885 SCNetworkInterfacePrivateRef interfacePrivate
=
7886 (SCNetworkInterfacePrivateRef
)interface
;
7887 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
7889 control
= interfacePrivate
->IPMonitorControl
;
7890 if (control
!= NULL
) {
7893 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7894 if (ifName
!= NULL
) {
7895 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
7899 _SCErrorSet(kSCStatusInvalidArgument
);
7906 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7907 SCNetworkServicePrimaryRank newRank
)
7909 IPMonitorControlRef control
;
7910 SCNetworkInterfacePrivateRef interfacePrivate
=
7911 (SCNetworkInterfacePrivateRef
)interface
;
7914 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7915 if (ifName
== NULL
) {
7916 _SCErrorSet(kSCStatusInvalidArgument
);
7919 control
= interfacePrivate
->IPMonitorControl
;
7920 if (control
== NULL
) {
7921 control
= IPMonitorControlCreate();
7922 if (control
== NULL
) {
7923 _SCErrorSet(kSCStatusFailed
);
7926 interfacePrivate
->IPMonitorControl
= control
;
7928 return IPMonitorControlSetInterfacePrimaryRank(control
,
7934 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7936 Boolean disable_until_needed
= FALSE
;
7937 CFNumberRef disable_prop
= NULL
;
7938 CFIndex interfaceIndex
;
7939 SCNetworkInterfacePrivateRef interfacePrivate
7940 = (SCNetworkInterfacePrivateRef
)interface
;
7941 CFArrayRef path_list
;
7943 if (interfacePrivate
->prefs
== NULL
) {
7944 _SCErrorSet(kSCStatusInvalidArgument
);
7947 interfaceIndex
= findPerInterfaceConfiguration(interface
);
7948 if (interfaceIndex
== kCFNotFound
) {
7949 _SCErrorSet(kSCStatusInvalidArgument
);
7952 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7953 if (path_list
!= NULL
) {
7954 CFDictionaryRef config
;
7955 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
7957 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7958 CFRelease(path_list
);
7959 if (config
!= NULL
) {
7962 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
7963 disable_prop
= isA_CFNumber(disable_prop
);
7964 if (disable_prop
!= NULL
) {
7965 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
7966 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
7969 /* invalid property, ignore it */
7970 disable_prop
= NULL
;
7975 if (disable_prop
== NULL
) {
7976 disable_until_needed
7977 = _SCNetworkInterfaceIsTethered(interface
);
7979 _SCErrorSet(kSCStatusOK
);
7980 return (disable_until_needed
);
7984 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
7988 CFIndex interfaceIndex
;
7989 SCNetworkInterfacePrivateRef interfacePrivate
7990 = (SCNetworkInterfacePrivateRef
)interface
;
7992 CFArrayRef path_list
;
7994 if (interfacePrivate
->prefs
== NULL
) {
7995 _SCErrorSet(kSCStatusInvalidArgument
);
7998 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
7999 _SCErrorSet(kSCStatusInvalidArgument
);
8002 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8003 if (interfaceIndex
== kCFNotFound
) {
8004 _SCErrorSet(kSCStatusInvalidArgument
);
8007 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8008 if (path_list
== NULL
) {
8009 _SCErrorSet(kSCStatusInvalidArgument
);
8012 count
= CFArrayGetCount(path_list
);
8013 for (i
= 0; i
< count
; i
++) {
8014 CFDictionaryRef config
;
8015 CFMutableDictionaryRef new_config
;
8016 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
8018 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
8019 if (config
!= NULL
) {
8021 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
8024 = CFDictionaryCreateMutable(NULL
, 0,
8025 &kCFTypeDictionaryKeyCallBacks
,
8026 &kCFTypeDictionaryValueCallBacks
);
8028 if (disable
!= NULL
) {
8029 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
8031 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
8033 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
,
8035 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
8037 CFRelease(new_config
);
8042 CFRelease(path_list
);
8047 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8054 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8055 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8061 #else // !TARGET_OS_SIMULATOR
8063 SCNetworkServicePrimaryRank
8064 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8066 #pragma unused(interface)
8067 return (kSCNetworkServicePrimaryRankDefault
);
8071 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8072 SCNetworkServicePrimaryRank newRank
)
8074 #pragma unused(interface)
8075 #pragma unused(newRank)
8076 _SCErrorSet(kSCStatusInvalidArgument
);
8081 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8083 #pragma unused(interface)
8088 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8090 #pragma unused(interface)
8091 #pragma unused(disable)
8096 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8098 #pragma unused(interface)
8099 #pragma unused(disable)
8100 _SCErrorSet(kSCStatusInvalidArgument
);
8104 #endif // !TARGET_OS_SIMULATOR
8108 CFArrayRef
// SCNetworkInterfaceRef
8109 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs
)
8111 CFStringRef defaultNetworkInterfacePath
= NULL
;
8113 CFMutableArrayRef interfaceList
= NULL
;
8114 SCNetworkInterfaceRef interfaceNamer
= NULL
;
8116 /* initialize runtime */
8117 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8119 if (ni_prefs
== NULL
) {
8120 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8121 assert(defaultNetworkInterfacePath
!= NULL
);
8122 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8125 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8126 if (isA_CFArray(if_list
)) {
8128 CFIndex n
= CFArrayGetCount(if_list
);
8130 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8131 for (i
= 0; i
< n
; i
++) {
8132 CFDictionaryRef dict
;
8134 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8135 if (isA_CFDictionary(dict
) != NULL
) {
8136 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
);
8138 if (interfaceNamer
!= NULL
) {
8139 CFArrayAppendValue(interfaceList
, interfaceNamer
);
8140 CFRelease(interfaceNamer
);
8146 if (defaultNetworkInterfacePath
!= NULL
) {
8147 CFRelease(defaultNetworkInterfacePath
);
8148 // prefs were created in the function, and hence need to be released
8149 CFRelease(ni_prefs
);
8151 return interfaceList
;
8157 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
8159 CFStringRef defaultNetworkInterfacePath
= NULL
;
8160 Boolean success
= FALSE
;
8162 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
8163 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8164 assert(defaultNetworkInterfacePath
!= NULL
);
8165 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8168 if (isA_CFArray(interfacesToSave
) == NULL
) {
8169 SC_log(LOG_INFO
, "No interfaces to save");
8172 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
8175 if (defaultNetworkInterfacePath
!= NULL
) {
8176 CFRelease(defaultNetworkInterfacePath
);
8177 // prefs were created in the function, and hence need to be released
8185 SCNetworkInterfaceRef
8186 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8189 SCNetworkInterfaceRef interface
= NULL
;
8190 CFStringRef defaultNetworkInterfacePath
;
8192 /* initialize runtime */
8193 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8195 if (ni_prefs
== NULL
) {
8196 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8197 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8198 CFRelease(defaultNetworkInterfacePath
);
8204 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8206 if (isA_CFArray(if_list
) != NULL
) {
8208 CFIndex count
= CFArrayGetCount(if_list
);
8210 for (idx
= 0; idx
< count
; idx
++) {
8211 CFDictionaryRef dict
;
8212 CFStringRef tmp_bsdName
;
8214 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8215 if (isA_CFDictionary(dict
) == NULL
) {
8219 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8220 if (tmp_bsdName
== NULL
) {
8223 if (CFEqual(bsdName
, tmp_bsdName
)) {
8224 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
);
8230 CFRelease(ni_prefs
);
8236 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8238 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8239 CFStringRef bsdName
= NULL
;
8240 SCNetworkInterfaceRef interface
= NULL
;
8243 count
= CFArrayGetCount(interfaces
);
8245 SC_log(LOG_INFO
, "No interfaces");
8248 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8250 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8251 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8253 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8254 if (isA_CFString(bsdName
) == NULL
) {
8255 SC_log(LOG_INFO
, "No BSD name");
8258 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8260 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8261 CFRelease(mappingBSDToInterface
);
8262 mappingBSDToInterface
= NULL
;
8263 SC_log(LOG_INFO
, "No mappings");
8266 return mappingBSDToInterface
;
8269 __private_extern__ Boolean
8270 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8272 CFStringRef intfSubtype
;
8274 if (entity
== NULL
) {
8278 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8279 #pragma GCC diagnostic push
8280 #pragma GCC diagnostic ignored "-Wdeprecated"
8281 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8284 #pragma GCC diagnostic pop