2 * Copyright (c) 2004-2018 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 <os/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 (void);
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"));
337 if (interfacePrivate
->trustRequired
) {
338 CFStringAppendFormat(result
, NULL
, CFSTR(", trust required = TRUE"));
340 #endif // TARGET_OS_IPHONE
341 if (interfacePrivate
->location
!= NULL
) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
344 if (interfacePrivate
->path
!= NULL
) {
345 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
347 if (interfacePrivate
->entryID
!= 0) {
348 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
350 if (interfacePrivate
->type
!= NULL
) {
351 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
353 if (interfacePrivate
->unit
!= NULL
) {
354 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
356 if (interfacePrivate
->family
!= NULL
) {
357 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
359 if (interfacePrivate
->subfamily
!= NULL
) {
360 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
362 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
366 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
367 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
370 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
371 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
375 if (interfacePrivate
->usb
.name
!= NULL
) {
376 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
377 interfacePrivate
->usb
.name
);
380 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
384 if (interfacePrivate
->configurationAction
!= NULL
) {
385 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
387 if (interfacePrivate
->overrides
!= NULL
) {
388 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
390 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
391 if (interfacePrivate
->prefs
!= NULL
) {
392 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
394 if (interfacePrivate
->serviceID
!= NULL
) {
395 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
397 if (interfacePrivate
->interface
!= NULL
) {
398 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
400 if (interfacePrivate
->unsaved
!= NULL
) {
401 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
404 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
408 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
409 for (i
= 0; i
< n
; i
++) {
410 SCNetworkInterfaceRef member
;
412 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
413 CFStringAppendFormat(result
, NULL
,
415 (i
== 0) ? ", interfaces = " : ",",
416 SCNetworkInterfaceGetBSDName(member
));
419 if (interfacePrivate
->bond
.mode
!= NULL
) {
420 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
422 if (interfacePrivate
->bond
.options
!= NULL
) {
425 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
426 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
430 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
434 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
435 for (i
= 0; i
< n
; i
++) {
436 SCNetworkInterfaceRef member
;
438 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
439 CFStringAppendFormat(result
, NULL
,
441 (i
== 0) ? ", interfaces = " : ",",
442 SCNetworkInterfaceGetBSDName(member
));
445 if (interfacePrivate
->bridge
.options
!= NULL
) {
448 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
449 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
453 if (interfacePrivate
->vlan
.interface
!= NULL
) {
454 CFStringAppendFormat(result
, NULL
,
455 CFSTR(", interface = %@"),
456 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
458 if (interfacePrivate
->vlan
.tag
!= NULL
) {
459 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
461 if (interfacePrivate
->vlan
.options
!= NULL
) {
464 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
465 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
469 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
476 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
478 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
480 /* release resources */
482 if (interfacePrivate
->name
!= NULL
)
483 CFRelease(interfacePrivate
->name
);
485 if (interfacePrivate
->localized_name
!= NULL
)
486 CFRelease(interfacePrivate
->localized_name
);
488 if (interfacePrivate
->localized_arg1
!= NULL
)
489 CFRelease(interfacePrivate
->localized_arg1
);
491 if (interfacePrivate
->localized_arg2
!= NULL
)
492 CFRelease(interfacePrivate
->localized_arg2
);
494 if (interfacePrivate
->interface
!= NULL
)
495 CFRelease(interfacePrivate
->interface
);
497 if (interfacePrivate
->prefs
!= NULL
)
498 CFRelease(interfacePrivate
->prefs
);
500 if (interfacePrivate
->store
!= NULL
)
501 CFRelease(interfacePrivate
->store
);
503 if (interfacePrivate
->serviceID
!= NULL
)
504 CFRelease(interfacePrivate
->serviceID
);
506 if (interfacePrivate
->unsaved
!= NULL
)
507 CFRelease(interfacePrivate
->unsaved
);
509 if (interfacePrivate
->entity_device
!= NULL
)
510 CFRelease(interfacePrivate
->entity_device
);
512 if (interfacePrivate
->entity_device_unique
!= NULL
)
513 CFRelease(interfacePrivate
->entity_device_unique
);
515 if (interfacePrivate
->supported_interface_types
!= NULL
)
516 CFRelease(interfacePrivate
->supported_interface_types
);
518 if (interfacePrivate
->supported_protocol_types
!= NULL
)
519 CFRelease(interfacePrivate
->supported_protocol_types
);
521 if (interfacePrivate
->address
!= NULL
)
522 CFRelease(interfacePrivate
->address
);
524 if (interfacePrivate
->addressString
!= NULL
)
525 CFRelease(interfacePrivate
->addressString
);
527 if (interfacePrivate
->configurationAction
!= NULL
)
528 CFRelease(interfacePrivate
->configurationAction
);
530 if (interfacePrivate
->location
!= NULL
)
531 CFRelease(interfacePrivate
->location
);
533 if (interfacePrivate
->path
!= NULL
)
534 CFRelease(interfacePrivate
->path
);
536 if (interfacePrivate
->overrides
!= NULL
)
537 CFRelease(interfacePrivate
->overrides
);
539 if (interfacePrivate
->prefix
!= NULL
)
540 CFRelease(interfacePrivate
->prefix
);
542 if (interfacePrivate
->type
!= NULL
)
543 CFRelease(interfacePrivate
->type
);
545 if (interfacePrivate
->unit
!= NULL
)
546 CFRelease(interfacePrivate
->unit
);
548 if (interfacePrivate
->family
!= NULL
)
549 CFRelease(interfacePrivate
->family
);
551 if (interfacePrivate
->subfamily
!= NULL
)
552 CFRelease(interfacePrivate
->subfamily
);
554 if (interfacePrivate
->usb
.name
!= NULL
)
555 CFRelease(interfacePrivate
->usb
.name
);
557 if (interfacePrivate
->usb
.pid
!= NULL
)
558 CFRelease(interfacePrivate
->usb
.pid
);
560 if (interfacePrivate
->usb
.vid
!= NULL
)
561 CFRelease(interfacePrivate
->usb
.vid
);
563 if (interfacePrivate
->bond
.interfaces
!= NULL
)
564 CFRelease(interfacePrivate
->bond
.interfaces
);
566 if (interfacePrivate
->bond
.mode
!= NULL
)
567 CFRelease(interfacePrivate
->bond
.mode
);
569 if (interfacePrivate
->bond
.options
!= NULL
)
570 CFRelease(interfacePrivate
->bond
.options
);
572 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
573 CFRelease(interfacePrivate
->bridge
.interfaces
);
575 if (interfacePrivate
->bridge
.options
!= NULL
)
576 CFRelease(interfacePrivate
->bridge
.options
);
578 if (interfacePrivate
->vlan
.interface
!= NULL
)
579 CFRelease(interfacePrivate
->vlan
.interface
);
581 if (interfacePrivate
->vlan
.tag
!= NULL
)
582 CFRelease(interfacePrivate
->vlan
.tag
);
584 if (interfacePrivate
->vlan
.options
!= NULL
)
585 CFRelease(interfacePrivate
->vlan
.options
);
586 #if !TARGET_OS_SIMULATOR
587 if (interfacePrivate
->IPMonitorControl
!= NULL
)
588 CFRelease(interfacePrivate
->IPMonitorControl
);
589 #endif // !TARGET_OS_SIMULATOR
595 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
597 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
598 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
603 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
604 return FALSE
; // if not the same interface type
607 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
608 return FALSE
; // if not the same device
611 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
612 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
613 return FALSE
; // if not the same device unique identifier
615 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
619 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
620 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
621 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
622 return FALSE
; // if same device but not the same display name
626 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
627 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
628 return FALSE
; // if not the same interfaces
630 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
631 return FALSE
; // if not the same mode
635 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
636 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
637 return FALSE
; // if not the same interfaces
641 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
642 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
643 return FALSE
; // if not the same physical interface
645 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
646 return FALSE
; // if not the same tag
650 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
651 return FALSE
; // if not the same layering
659 __SCNetworkInterfaceHash(CFTypeRef cf
)
662 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
664 if (interfacePrivate
->entity_device
!= NULL
) {
665 if (interfacePrivate
->entity_device_unique
== NULL
) {
666 hash
= CFHash(interfacePrivate
->entity_device
);
670 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
671 interfacePrivate
->entity_device
,
672 interfacePrivate
->entity_device_unique
);
683 __SCNetworkInterfaceInitialize(void)
688 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
690 // initialize __kSCNetworkInterfaceIPv4
691 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
692 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
693 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
695 // initialize __kSCNetworkInterfaceLoopback
696 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
697 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
698 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
699 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
700 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
702 // get CFBundleRef for SystemConfiguration.framework
703 bundle
= _SC_CFBundleGet();
705 // get mach port used to communication with IOKit
706 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
707 if (kr
!= kIOReturnSuccess
) {
708 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
716 SCNetworkInterfacePrivateRef
717 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
718 SCNetworkInterfaceRef interface
,
719 SCPreferencesRef prefs
,
720 CFStringRef serviceID
)
722 SCNetworkInterfacePrivateRef interfacePrivate
;
725 /* initialize runtime */
726 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
728 /* allocate target */
729 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
730 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
731 __kSCNetworkInterfaceTypeID
,
734 if (interfacePrivate
== NULL
) {
738 /* initialize non-zero/NULL members */
739 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
740 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
741 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
742 interfacePrivate
->sort_order
= kSortUnknown
;
744 return interfacePrivate
;
750 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
754 struct if_msghdr
* ifm
;
755 char * if_name
= NULL
;
756 unsigned int if_index
;
758 Boolean vlanOK
= FALSE
;
760 // get the interface index
761 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
762 if (if_name
== NULL
) {
763 return FALSE
; // if conversion error
765 if_index
= if_nametoindex(if_name
);
767 goto done
; // if unknown interface
770 // get information for the specified interface
775 mib
[4] = NET_RT_IFLIST
;
776 mib
[5] = if_index
; /* ask for exactly one interface */
778 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
779 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
782 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
783 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
784 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
788 // check the link type and hwassist flags
789 // ALIGN: buf is aligned
790 ifm
= (struct if_msghdr
*)(void *)buf
;
791 switch (ifm
->ifm_type
) {
793 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
794 struct if_data
*if_data
= &ifm
->ifm_data
;
796 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
806 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
807 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
814 __SCCopyMacAddress(CFStringRef ifname
)
816 struct ifaddrs
*ifap
;
817 char ifname_c
[IFNAMSIZ
];
819 CFDataRef macAddress
= NULL
;
821 if(_SC_cfstring_to_cstring(ifname
,
824 kCFStringEncodingUTF8
) == NULL
) {
828 if (getifaddrs(&ifap
) == -1) {
830 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
834 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
835 struct sockaddr_dl
*sdl
;
837 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
841 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
842 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
843 if (sdl
->sdl_family
!= AF_LINK
) {
847 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
856 SCNetworkInterfacePrivateRef
857 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
860 SCNetworkInterfacePrivateRef interfacePrivate
;
862 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
863 if (interfacePrivate
== NULL
) {
867 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
868 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
869 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
870 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
871 interfacePrivate
->builtin
= TRUE
;
872 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
873 interfacePrivate
->sort_order
= kSortBond
;
875 interfacePrivate
->localized_key
= CFSTR("bond");
876 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
878 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
879 // interfacePrivate->bond.mode = NULL;
880 // interfacePrivate->bond.options = NULL;
882 return interfacePrivate
;
887 SCNetworkInterfacePrivateRef
888 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
889 CFStringRef bridge_if
)
891 SCNetworkInterfacePrivateRef interfacePrivate
;
893 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
894 if (interfacePrivate
== NULL
) {
898 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
899 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
900 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
901 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
902 interfacePrivate
->builtin
= TRUE
;
903 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
904 interfacePrivate
->sort_order
= kSortBridge
;
906 interfacePrivate
->localized_key
= CFSTR("bridge");
907 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
909 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
910 // interfacePrivate->bridge.options = NULL;
912 return interfacePrivate
;
917 SCNetworkInterfacePrivateRef
918 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
921 SCNetworkInterfacePrivateRef interfacePrivate
;
923 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
924 if (interfacePrivate
== NULL
) {
928 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
929 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
930 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
931 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
932 interfacePrivate
->builtin
= TRUE
;
933 interfacePrivate
->sort_order
= kSortVLAN
;
935 interfacePrivate
->localized_key
= CFSTR("vlan");
936 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
938 // interfacePrivate->vlan.interface = NULL;
939 // interfacePrivate->vlan.tag = NULL;
940 // interfacePrivate->vlan.options = NULL;
942 return interfacePrivate
;
947 #pragma mark Interface ordering
950 static CF_RETURNS_RETAINED CFArrayRef
951 split_path(CFStringRef path
)
953 CFArrayRef components
;
954 CFMutableStringRef nPath
;
956 // turn '@'s into '/'s
957 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
958 (void) CFStringFindAndReplace(nPath
,
961 CFRangeMake(0, CFStringGetLength(nPath
)),
964 // split path into components to be compared
965 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
973 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
975 #pragma unused(context)
976 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
977 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
978 CFComparisonResult res
= kCFCompareEqualTo
;
980 /* sort by interface type */
981 if (dev1
->sort_order
!= dev2
->sort_order
) {
982 if (dev1
->sort_order
< dev2
->sort_order
) {
983 res
= kCFCompareLessThan
;
985 res
= kCFCompareGreaterThan
;
990 /* built-in interfaces sort first */
991 if (dev1
->builtin
!= dev2
->builtin
) {
993 res
= kCFCompareLessThan
;
995 res
= kCFCompareGreaterThan
;
1000 /* ... and then, sort built-in interfaces by "location" */
1001 if (dev1
->builtin
) {
1002 if (dev1
->location
!= dev2
->location
) {
1003 if (isA_CFString(dev1
->location
)) {
1004 if (isA_CFString(dev2
->location
)) {
1005 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1007 res
= kCFCompareLessThan
;
1010 res
= kCFCompareGreaterThan
;
1013 if (res
!= kCFCompareEqualTo
) {
1019 /* ... and, then sort by IOPathMatch */
1020 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1021 CFArrayRef elements1
;
1022 CFArrayRef elements2
;
1028 elements1
= split_path(dev1
->path
);
1029 n1
= CFArrayGetCount(elements1
);
1031 elements2
= split_path(dev2
->path
);
1032 n2
= CFArrayGetCount(elements2
);
1034 n
= (n1
<= n2
) ? n1
: n2
;
1035 for (i
= 0; i
< n
; i
++) {
1044 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1045 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1047 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1049 q1
= strtoq(str
, &end
, 16);
1050 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1051 CFAllocatorDeallocate(NULL
, str
);
1054 // if e1 is a valid numeric string
1055 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1057 q2
= strtoq(str
, &end
, 16);
1058 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1059 CFAllocatorDeallocate(NULL
, str
);
1062 // if e2 is also a valid numeric string
1065 res
= kCFCompareEqualTo
;
1067 } else if (q1
< q2
) {
1068 res
= kCFCompareLessThan
;
1070 res
= kCFCompareGreaterThan
;
1076 res
= CFStringCompare(e1
, e2
, 0);
1077 if (res
!= kCFCompareEqualTo
) {
1082 if (res
== kCFCompareEqualTo
) {
1084 res
= kCFCompareLessThan
;
1085 } else if (n1
< n2
) {
1086 res
= kCFCompareGreaterThan
;
1090 CFRelease(elements1
);
1091 CFRelease(elements2
);
1093 if (res
!= kCFCompareEqualTo
) {
1098 /* ... and, then sort by BSD interface name */
1099 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1100 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1101 if (res
!= kCFCompareEqualTo
) {
1106 /* ... and lastly, sort by BSD interface unique identifier */
1107 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1108 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1109 // if (res != kCFCompareEqualTo) {
1119 sort_interfaces(CFMutableArrayRef all_interfaces
)
1123 n
= CFArrayGetCount(all_interfaces
);
1128 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1135 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1137 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1139 return interfacePrivate
->sort_order
;
1144 #pragma mark Interface details
1148 IOCopyCFStringValue(CFTypeRef ioVal
)
1150 if (isA_CFString(ioVal
)) {
1151 return CFStringCreateCopy(NULL
, ioVal
);
1154 if (isA_CFData(ioVal
)) {
1155 return CFStringCreateWithCString(NULL
,
1156 (const char *)CFDataGetBytePtr(ioVal
),
1157 kCFStringEncodingUTF8
);
1165 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1167 CFStringRef if_bsdName
;
1168 CFStringRef if_prefix
;
1169 CFNumberRef if_unit
;
1171 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1172 if (if_bsdName
!= NULL
) {
1173 return IOCopyCFStringValue(if_bsdName
);
1176 // no BSD name, get interface prefix and unit
1177 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1178 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1179 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1180 // if both prefix and unit available, construct BSD name
1181 if_bsdName
= CFStringCreateWithFormat(NULL
,
1193 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1197 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1198 return IOCopyCFStringValue(ioVal
);
1203 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1205 Boolean match
= FALSE
;
1206 CFIndex prefixLen
= CFStringGetLength(prefix
);
1207 CFStringRef str
= NULL
;
1209 if (!isA_CFString(ioVal
)) {
1210 if (isA_CFData(ioVal
)) {
1211 str
= CFStringCreateWithCStringNoCopy(NULL
,
1212 (const char *)CFDataGetBytePtr(ioVal
),
1213 kCFStringEncodingUTF8
,
1221 if ((ioVal
!= NULL
) &&
1222 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1223 (CFStringCompareWithOptions(ioVal
,
1225 CFRangeMake(0, prefixLen
),
1226 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1230 if (str
!= NULL
) CFRelease(str
);
1235 static const struct {
1236 const CFStringRef name
;
1237 const CFStringRef slot
;
1238 } slot_mappings
[] = {
1240 { CFSTR("A1") , CFSTR("1") },
1241 { CFSTR("B1") , CFSTR("2") },
1242 { CFSTR("C1") , CFSTR("3") },
1244 // Blue&White G3, Yikes G4
1245 { CFSTR("J12"), CFSTR("1") },
1246 { CFSTR("J11"), CFSTR("2") },
1247 { CFSTR("J10"), CFSTR("3") },
1248 { CFSTR("J9"), CFSTR("4") },
1251 { CFSTR("A") , CFSTR("1") },
1252 { CFSTR("B") , CFSTR("2") },
1253 { CFSTR("C") , CFSTR("3") },
1254 { CFSTR("D") , CFSTR("4") },
1256 // Digital Audio G4 (and later models)
1257 { CFSTR("1") , CFSTR("1") },
1258 { CFSTR("2") , CFSTR("2") },
1259 { CFSTR("3") , CFSTR("3") },
1260 { CFSTR("4") , CFSTR("4") },
1261 { CFSTR("5") , CFSTR("5") }
1265 static const CFStringRef slot_prefixes
[] = {
1266 CFSTR("thunderbolt slot "),
1272 static CF_RETURNS_RETAINED CFStringRef
1273 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1276 io_registry_entry_t parent
;
1277 CFMutableStringRef slot
;
1278 CFTypeRef slot_name
;
1281 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1283 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1284 if (slot_name
!= NULL
) {
1285 slot
= CFStringCreateMutable(NULL
, 0);
1286 if (isA_CFString(slot_name
)) {
1287 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1288 CFStringAppend(slot
, slot_name
);
1289 } else if (isA_CFData(slot_name
)) {
1290 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1291 CFStringAppendCString(slot
,
1292 (const char *)CFDataGetBytePtr(slot_name
),
1293 kCFStringEncodingUTF8
);
1296 for (size_t i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1299 len
= CFStringGetLength(slot_prefixes
[i
]);
1300 if (CFStringGetLength(slot
) > len
) {
1301 (void) CFStringFindAndReplace(slot
,
1304 CFRangeMake(0, len
),
1305 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1309 for (size_t i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1310 if (CFStringCompare(slot
,
1311 slot_mappings
[i
].name
,
1312 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1314 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1319 CFRelease(slot_name
);
1322 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1324 case kIOReturnSuccess
: {
1325 CFTypeRef parent_pci_slot_name
= NULL
;
1326 CFStringRef parent_slot
;
1328 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1329 if (parent_slot
!= NULL
) {
1330 if (slot
!= NULL
) CFRelease(slot
);
1331 slot
= (CFMutableStringRef
)parent_slot
;
1333 if (pci_slot_name
!= NULL
) {
1334 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1335 *pci_slot_name
= parent_pci_slot_name
;
1337 CFRelease(parent_pci_slot_name
);
1341 IOObjectRelease(parent
);
1344 case kIOReturnNoDevice
:
1345 // if we have hit the root node
1348 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1356 static CFComparisonResult
1357 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1359 #pragma unused(context)
1360 CFStringRef bsd1
= (CFStringRef
)val1
;
1361 CFStringRef bsd2
= (CFStringRef
)val2
;
1363 return CFStringCompare(bsd1
, bsd2
, 0);
1367 static CF_RETURNS_RETAINED CFStringRef
1368 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1371 CFStringRef port_name
= NULL
;
1372 CFMutableArrayRef port_names
;
1375 CFStringRef match_keys
[2];
1376 CFTypeRef match_vals
[2];
1377 CFDictionaryRef match_dict
;
1378 CFDictionaryRef matching
;
1379 io_registry_entry_t slot
;
1380 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1382 match_keys
[0] = CFSTR("AAPL,slot-name");
1383 match_vals
[0] = slot_name
;
1385 match_dict
= CFDictionaryCreate(NULL
,
1386 (const void **)match_keys
,
1387 (const void **)match_vals
,
1389 &kCFTypeDictionaryKeyCallBacks
,
1390 &kCFTypeDictionaryValueCallBacks
);
1392 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1393 match_vals
[0] = CFSTR("IOPCIDevice");
1395 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1396 match_vals
[1] = match_dict
;
1398 // note: the "matching" dictionary will be consumed by the following
1399 matching
= CFDictionaryCreate(NULL
,
1400 (const void **)match_keys
,
1401 (const void **)match_vals
,
1402 sizeof(match_keys
)/sizeof(match_keys
[0]),
1403 &kCFTypeDictionaryKeyCallBacks
,
1404 &kCFTypeDictionaryValueCallBacks
);
1405 CFRelease(match_dict
);
1407 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1408 if (kr
!= kIOReturnSuccess
) {
1409 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1410 return MACH_PORT_NULL
;
1413 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1415 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1416 io_registry_entry_t child
;
1417 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1419 kr
= IORegistryEntryCreateIterator(slot
,
1421 kIORegistryIterateRecursively
,
1423 if (kr
!= kIOReturnSuccess
) {
1424 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1425 CFRelease(port_names
);
1426 return MACH_PORT_NULL
;
1429 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1430 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1431 CFMutableDictionaryRef interface_dict
= NULL
;
1433 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1434 if (interface_dict
!= NULL
) {
1435 CFNumberRef child_if_type
;
1436 int child_ift
= ift
;
1438 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1439 if (child_if_type
!= NULL
) {
1440 if (!isA_CFNumber(child_if_type
) ||
1441 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1442 // assume that it's a match
1447 if (ift
== child_ift
) {
1448 CFStringRef if_bsdName
;
1450 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1451 if (if_bsdName
!= NULL
) {
1452 CFArrayAppendValue(port_names
, if_bsdName
);
1453 CFRelease(if_bsdName
);
1457 CFRelease(interface_dict
);
1460 IOObjectRelease(child
);
1462 IOObjectRelease(child_iterator
);
1463 IOObjectRelease(slot
);
1465 IOObjectRelease(slot_iterator
);
1467 n
= CFArrayGetCount(port_names
);
1469 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1470 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1471 if (n
!= kCFNotFound
) {
1472 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1476 CFRelease(port_names
);
1482 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1484 CFStringRef bsd_name
= NULL
;
1485 CFMutableDictionaryRef interface_dict
= NULL
;
1487 CFTypeRef pci_slot_name
;
1492 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1493 if (interface_dict
!= NULL
) {
1494 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1495 CFRelease(interface_dict
);
1498 if (bsd_name
== NULL
) {
1502 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1503 if (*slot_name
!= NULL
) {
1504 if (pci_slot_name
!= NULL
) {
1505 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1506 CFRelease(pci_slot_name
);
1511 CFRelease(bsd_name
);
1517 isBuiltin(io_registry_entry_t interface
)
1521 slot
= pci_slot(interface
, NULL
);
1523 // interfaces which have a "slot" are not built-in
1533 isBluetoothBuiltin(Boolean
*haveController
)
1535 Boolean builtin
= FALSE
;
1536 io_object_t hciController
;
1537 io_iterator_t iter
= MACH_PORT_NULL
;
1540 kr
= IOServiceGetMatchingServices(masterPort
,
1541 IOServiceMatching("IOBluetoothHCIController"),
1543 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1544 if (kr
!= kIOReturnSuccess
) {
1545 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1547 *haveController
= FALSE
;
1550 *haveController
= TRUE
;
1552 hciController
= IOIteratorNext(iter
);
1553 IOObjectRelease(iter
);
1554 if(hciController
!= MACH_PORT_NULL
) {
1555 #if !TARGET_OS_SIMULATOR
1556 CFNumberRef idVendor
;
1558 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1559 if (idVendor
!= NULL
) {
1562 if (isA_CFNumber(idVendor
) &&
1563 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1564 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1568 CFRelease(idVendor
);
1570 #endif // !TARGET_OS_SIMULATOR
1572 IOObjectRelease(hciController
);
1580 isThunderbolt(io_registry_entry_t interface
)
1584 val
= IORegistryEntrySearchCFProperty(interface
,
1586 CFSTR(kPCIThunderboltString
),
1588 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1599 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1600 io_registry_entry_t interface
,
1601 CFDictionaryRef interface_dict
,
1602 io_registry_entry_t controller
,
1603 CFDictionaryRef controller_dict
,
1604 io_registry_entry_t bus
,
1605 CFDictionaryRef bus_dict
)
1607 #if TARGET_OS_SIMULATOR
1608 #pragma unused(interfacePrivate)
1609 #pragma unused(interface)
1610 #endif // TARGET_OS_SIMULATOR
1611 #pragma unused(interface_dict)
1612 #pragma unused(controller)
1613 #pragma unused(controller_dict)
1615 #pragma unused(bus_dict)
1616 #if !TARGET_OS_SIMULATOR
1618 if (interfacePrivate
->usb
.name
== NULL
) {
1619 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1621 CFSTR(kUSBProductString
),
1623 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1625 if (interfacePrivate
->usb
.vid
== NULL
) {
1626 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1628 CFSTR(kUSBVendorID
),
1630 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1632 if (interfacePrivate
->usb
.pid
== NULL
) {
1633 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1635 CFSTR(kUSBProductID
),
1637 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1639 #endif // !TARGET_OS_SIMULATOR
1646 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1647 io_registry_entry_t interface
,
1650 Boolean updated
= FALSE
;
1653 // check if a "Product Name" has been provided
1654 val
= IORegistryEntrySearchCFProperty(interface
,
1656 CFSTR(kIOPropertyProductNameKey
),
1658 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1659 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1660 // else, use "USB Product Name" if available
1661 val
= CFRetain(interfacePrivate
->usb
.name
);
1664 CFStringRef productName
;
1666 productName
= IOCopyCFStringValue(val
);
1669 if (productName
!= NULL
) {
1670 if (CFStringGetLength(productName
) > 0) {
1671 // if we have a [somewhat reasonable?] product name
1672 if (interfacePrivate
->name
!= NULL
) {
1673 CFRelease(interfacePrivate
->name
);
1675 interfacePrivate
->name
= CFRetain(productName
);
1676 if (interfacePrivate
->localized_name
!= NULL
) {
1677 CFRelease(interfacePrivate
->localized_name
);
1678 interfacePrivate
->localized_name
= NULL
;
1680 if (bundle
!= NULL
) {
1681 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1687 CFRelease(productName
);
1696 #pragma mark Interface enumeration
1699 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1700 io_registry_entry_t interface
,
1701 CFDictionaryRef interface_dict
,
1702 io_registry_entry_t controller
,
1703 CFDictionaryRef controller_dict
,
1704 io_registry_entry_t bus
,
1705 CFDictionaryRef bus_dict
);
1709 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1710 io_registry_entry_t interface
,
1711 CFStringRef override
)
1716 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1717 val
= IORegistryEntrySearchCFProperty(interface
,
1721 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1724 if (isA_CFDictionary(val
)) {
1725 if (interfacePrivate
->overrides
== NULL
) {
1726 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1728 &kCFTypeDictionaryKeyCallBacks
,
1729 &kCFTypeDictionaryValueCallBacks
);
1731 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1741 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1742 io_registry_entry_t interface
,
1743 CFDictionaryRef interface_dict
,
1744 io_registry_entry_t controller
,
1745 CFDictionaryRef controller_dict
,
1746 io_registry_entry_t bus
,
1747 CFDictionaryRef bus_dict
)
1757 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1758 if (isA_CFNumber(num
) &&
1759 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1760 interfacePrivate
->type
= CFRetain(num
);
1762 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1770 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1771 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1772 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1773 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1774 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1775 interfacePrivate
->sort_order
= kSortAirPort
;
1776 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1777 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1778 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1779 interfacePrivate
->sort_order
= kSortThunderbolt
;
1780 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1781 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1782 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1783 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1784 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1785 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1786 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1787 interfacePrivate
->sort_order
= kSortTethered
;
1788 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1789 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1790 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1791 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1794 if (interfacePrivate
->interface_type
== NULL
) {
1795 val
= IORegistryEntrySearchCFProperty(interface
,
1797 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1799 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1801 if (isA_CFString(val
)) {
1802 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1803 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1804 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1805 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1806 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1807 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1808 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1809 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1810 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1811 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1812 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1813 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1821 if (interfacePrivate
->interface_type
== NULL
) {
1822 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1824 if (CFEqual(str
, CFSTR("radio"))) {
1825 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1826 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1827 interfacePrivate
->sort_order
= kSortOtherWireless
;
1834 if (interfacePrivate
->interface_type
== NULL
) {
1835 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1836 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1837 interfacePrivate
->sort_order
= kSortEthernet
;
1839 // BOND support only enabled for ethernet devices
1840 interfacePrivate
->supportsBond
= TRUE
;
1843 // enable Bridge support
1844 interfacePrivate
->supportsBridge
= TRUE
;
1847 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1849 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1852 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1854 interfacePrivate
->builtin
= isBuiltin(interface
);
1857 if (!interfacePrivate
->builtin
&&
1858 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1859 // always treat AirPort interfaces as built-in
1860 interfacePrivate
->builtin
= TRUE
;
1864 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1865 if ((interfacePrivate
->location
!= NULL
) &&
1866 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1867 CFRelease(interfacePrivate
->location
);
1868 interfacePrivate
->location
= NULL
;
1872 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1873 if (isA_CFNumber(num
) &&
1874 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1875 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1876 interfacePrivate
->supportsVLAN
= TRUE
;
1881 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1882 interfacePrivate
->localized_key
= CFSTR("airport");
1883 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1884 if ((interfacePrivate
->location
== NULL
) ||
1885 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1886 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1888 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1889 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1891 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1892 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1893 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1894 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1895 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1896 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1897 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1898 interfacePrivate
->localized_key
= CFSTR("wireless");
1899 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1900 } else if (interfacePrivate
->builtin
) {
1901 if ((interfacePrivate
->location
== NULL
) ||
1902 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1903 interfacePrivate
->localized_key
= CFSTR("ether");
1905 interfacePrivate
->localized_key
= CFSTR("multiether");
1906 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1909 CFStringRef provider
;
1911 // check provider class
1912 provider
= IORegistryEntrySearchCFProperty(interface
,
1914 CFSTR(kIOProviderClassKey
),
1916 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1917 if (provider
!= NULL
) {
1918 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1919 CFStringRef port_name
;
1920 CFStringRef slot_name
;
1922 // set interface "name"
1923 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1924 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1925 if (isThunderbolt(interface
)) {
1926 if (port_name
== NULL
) {
1927 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1928 interfacePrivate
->localized_arg1
= slot_name
;
1930 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1931 interfacePrivate
->localized_arg1
= slot_name
;
1932 interfacePrivate
->localized_arg2
= port_name
;
1936 if (port_name
== NULL
) {
1937 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1938 interfacePrivate
->localized_arg1
= slot_name
;
1940 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1941 interfacePrivate
->localized_arg1
= slot_name
;
1942 interfacePrivate
->localized_arg2
= port_name
;
1947 io_registry_entry_t node
= interface
;
1949 while (provider
!= NULL
) {
1950 #if !TARGET_OS_SIMULATOR
1951 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
1952 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
1953 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
))) {
1954 // get USB info (if available)
1955 processUSBInterface(interfacePrivate
,
1963 // set interface "name"
1964 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1965 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1966 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1970 #endif // !TARGET_OS_SIMULATOR
1972 if (node
== interface
) {
1974 } else if (node
== controller
) {
1980 CFRelease(provider
);
1981 provider
= IORegistryEntrySearchCFProperty(node
,
1983 CFSTR(kIOProviderClassKey
),
1985 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1988 if (interfacePrivate
->localized_key
== NULL
) {
1989 update_interface_name(interfacePrivate
, interface
, FALSE
);
1993 if (provider
!= NULL
) CFRelease(provider
);
1996 if (interfacePrivate
->localized_key
== NULL
) {
1997 // if no provider, not a PCI device, or no slot information
1998 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1999 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2006 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2009 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2012 interfacePrivate
->builtin
= isBuiltin(interface
);
2015 interfacePrivate
->sort_order
= kSortFireWire
;
2018 if (interfacePrivate
->builtin
) {
2019 interfacePrivate
->localized_key
= CFSTR("firewire");
2021 CFStringRef port_name
;
2022 CFStringRef slot_name
;
2024 // set interface "name"
2025 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2026 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2027 if (isThunderbolt(interface
)) {
2028 if (port_name
== NULL
) {
2029 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2030 interfacePrivate
->localized_arg1
= slot_name
;
2032 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2033 interfacePrivate
->localized_arg1
= slot_name
;
2034 interfacePrivate
->localized_arg2
= port_name
;
2037 if (port_name
== NULL
) {
2038 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2039 interfacePrivate
->localized_arg1
= slot_name
;
2041 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2042 interfacePrivate
->localized_arg1
= slot_name
;
2043 interfacePrivate
->localized_arg2
= port_name
;
2051 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2056 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2058 // Hardware (MAC) address
2059 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2060 if (isA_CFData(data
)) {
2061 interfacePrivate
->address
= CFRetain(data
);
2065 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2066 if (isA_CFString(str
)) {
2067 interfacePrivate
->prefix
= CFRetain(str
);
2071 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2072 if (isA_CFNumber(num
) &&
2073 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2074 interfacePrivate
->unit
= CFRetain(num
);
2077 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2078 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2085 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2087 CFDictionaryRef dict
;
2088 CFMutableDictionaryRef newDict
;
2090 if (interfacePrivate
->overrides
== NULL
) {
2091 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2093 &kCFTypeDictionaryKeyCallBacks
,
2094 &kCFTypeDictionaryValueCallBacks
);
2097 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2099 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2101 newDict
= CFDictionaryCreateMutable(NULL
,
2103 &kCFTypeDictionaryKeyCallBacks
,
2104 &kCFTypeDictionaryValueCallBacks
);
2106 if (script
!= NULL
) {
2107 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2109 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2111 if (CFDictionaryGetCount(newDict
) > 0) {
2112 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2114 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2118 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2119 CFRelease(interfacePrivate
->overrides
);
2120 interfacePrivate
->overrides
= NULL
;
2127 is_valid_connection_script(CFStringRef script
)
2129 char ccl
[MAXPATHLEN
];
2130 char path
[MAXPATHLEN
];
2131 sysdir_search_path_enumeration_state state
;
2133 (void) _SC_cfstring_to_cstring(script
,
2136 kCFStringEncodingUTF8
);
2138 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2139 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2140 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2142 struct stat statBuf
;
2144 if (ccl
[0] == '/') {
2145 path
[0] = '\0'; // if modemCCL is a full path
2147 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2149 strlcat(path
, ccl
, sizeof(path
));
2151 if (stat(path
, &statBuf
) != 0) {
2152 if (errno
== ENOENT
) {
2156 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2159 if (S_ISREG(statBuf
.st_mode
)) {
2160 // if we have a valid CCL script
2164 #define BUNDLE_EXT ".ccl"
2165 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2170 if ((n
<= BUNDLE_EXT_LEN
) ||
2171 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2172 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2173 if (stat(path
, &statBuf
) != 0) {
2174 if (errno
== ENOENT
) {
2178 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2182 if (S_ISDIR(statBuf
.st_mode
)) {
2183 // if we have a valid CCL bundle
2193 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2194 io_registry_entry_t interface
,
2195 CFDictionaryRef interface_dict
,
2196 io_registry_entry_t controller
,
2197 CFDictionaryRef controller_dict
,
2198 io_registry_entry_t bus
,
2199 CFDictionaryRef bus_dict
)
2201 CFStringRef base
= NULL
;
2203 Boolean isModem
= FALSE
;
2204 Boolean isWWAN
= FALSE
;
2205 CFStringRef modemCCL
= NULL
;
2209 // check if initializing
2210 val
= IORegistryEntrySearchCFProperty(interface
,
2212 kSCNetworkInterfaceInitializingKey
,
2214 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2216 Boolean initializing
;
2218 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2221 return FALSE
; // if this interface is still initializing
2226 val
= IORegistryEntrySearchCFProperty(interface
,
2230 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2232 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2237 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2238 if (interfacePrivate
->entity_device
== NULL
) {
2242 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2244 base
= CFRetain(interfacePrivate
->entity_device
);
2250 * Exclude ports named "irda" because otherwise the IrDA ports on the
2251 * original iMac (rev's A through D) show up as serial ports. Given
2252 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2253 * even support it, these ports definitely shouldn't be listed.
2255 if (CFStringCompare(base
,
2257 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2261 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2262 Boolean haveController
= FALSE
;
2265 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2266 interfacePrivate
->sort_order
= kSortBluetooth
;
2267 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2268 if (!haveController
) {
2269 // if device with no controller present
2272 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2274 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2275 interfacePrivate
->sort_order
= kSortIrDA
;
2276 } else if (isWWAN
) {
2278 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2279 interfacePrivate
->sort_order
= kSortWWAN
;
2282 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2283 interfacePrivate
->sort_order
= kSortModem
;
2287 interfacePrivate
->entity_type
= kSCEntNetModem
;
2289 // Entity (Hardware)
2290 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2291 if (!isA_CFString(ift
)) {
2295 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2299 if (CFEqual(base
, CFSTR("modem"))) {
2300 interfacePrivate
->builtin
= TRUE
;
2301 interfacePrivate
->sort_order
= kSortInternalModem
;
2302 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2303 interfacePrivate
->sort_order
= kSortUSBModem
;
2305 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2307 interfacePrivate
->sort_order
= kSortSerialPort
;
2312 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2313 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2315 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2316 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2318 // look for modem CCL, unique identifier
2319 if (interfacePrivate
->overrides
!= NULL
) {
2320 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2322 CFStringRef uniqueID
;
2324 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2325 modemCCL
= isA_CFString(modemCCL
);
2327 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2328 uniqueID
= isA_CFString(uniqueID
);
2329 if (uniqueID
!= NULL
) {
2330 // retain the device's base name and the unique id
2331 CFRelease(interfacePrivate
->entity_device
);
2332 interfacePrivate
->entity_device
= CFRetain(base
);
2333 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2338 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2339 // a bit harder for the modem CCL
2340 if (modemCCL
== NULL
) {
2341 val
= IORegistryEntrySearchCFProperty(interface
,
2345 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2347 modemCCL
= IOCopyCFStringValue(val
);
2348 if (modemCCL
!= NULL
) {
2349 set_connection_script(interfacePrivate
, modemCCL
);
2350 CFRelease(modemCCL
);
2358 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2359 interfacePrivate
->localized_key
= CFSTR("irda");
2360 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2361 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2363 CFStringRef localized
= NULL
;
2364 CFStringRef name
= NULL
;
2365 CFMutableStringRef port
;
2367 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2368 CFStringLowercase(port
, NULL
);
2371 CFStringAppend(port
, CFSTR("-port"));
2374 // set non-localized name
2375 if (bundle
!= NULL
) {
2376 name
= copy_interface_string(bundle
, port
, FALSE
);
2379 if (!CFEqual(port
, name
)) {
2380 // if [English] localization available
2381 interfacePrivate
->name
= name
;
2383 // if no [English] localization available, use TTY base name
2385 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2388 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2391 // set localized name
2392 if (bundle
!= NULL
) {
2393 localized
= copy_interface_string(bundle
, port
, TRUE
);
2395 if (localized
!= NULL
) {
2396 if (!CFEqual(port
, localized
)) {
2397 // if localization available
2398 interfacePrivate
->localized_name
= localized
;
2400 // if no localization available, use TTY base name
2401 CFRelease(localized
);
2402 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2405 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2408 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2409 // get USB info (if available)
2410 processUSBInterface(interfacePrivate
,
2418 // set interface "name"
2419 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2420 // if "ModemCCL" not provided, also check if the product/interface
2421 // name matches a CCL script
2422 if ((modemCCL
== NULL
) &&
2423 is_valid_connection_script(interfacePrivate
->name
)) {
2424 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2436 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2437 CFRelease(interfacePrivate
->entity_device
);
2438 interfacePrivate
->entity_device
= NULL
;
2440 if (base
!= NULL
) CFRelease(base
);
2447 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2450 * Create a path for a registry entry.
2454 CFStringRef str
= NULL
;
2456 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2457 if (status
== kIOReturnSuccess
) {
2458 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2459 } else if (status
== kIOReturnBadArgument
) {
2460 io_registry_entry_t parent
;
2462 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2463 if (status
== kIOReturnSuccess
) {
2464 CFStringRef str_parent
;
2466 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2467 if (str_parent
!= NULL
) {
2470 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2471 if (status
== kIOReturnSuccess
) {
2474 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2475 if (status
== kIOReturnSuccess
) {
2476 str
= CFStringCreateWithFormat(NULL
,
2483 str
= CFStringCreateWithFormat(NULL
,
2491 CFRelease(str_parent
);
2494 IOObjectRelease(parent
);
2501 static CFMutableDictionaryRef
2502 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2505 CFMutableDictionaryRef reg_dict
= NULL
;
2506 CFTypeRef value
= NULL
;
2508 reg_dict
= CFDictionaryCreateMutable(NULL
,
2510 &kCFTypeDictionaryKeyCallBacks
,
2511 &kCFTypeDictionaryValueCallBacks
);
2513 for (; idx
< numKeys
; idx
++) {
2514 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2515 if (value
!= NULL
) {
2516 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2524 static SCNetworkInterfaceRef
2525 createInterface(io_registry_entry_t interface
, processInterface func
,
2526 CFStringRef hidden_key
)
2528 io_registry_entry_t bus
= MACH_PORT_NULL
;
2529 CFMutableDictionaryRef bus_dict
= NULL
;
2530 io_registry_entry_t controller
= MACH_PORT_NULL
;
2531 CFMutableDictionaryRef controller_dict
= NULL
;
2532 uint64_t entryID
= 0;
2533 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2534 CFMutableDictionaryRef interface_dict
= NULL
;
2539 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2541 const CFStringRef interface_dict_keys
[] = {
2542 CFSTR(kIOInterfaceType
),
2544 CFSTR(kIOBSDNameKey
),
2545 CFSTR(kIOPrimaryInterface
),
2546 CFSTR(kIOInterfaceNamePrefix
),
2547 CFSTR(kIOInterfaceUnit
),
2548 CFSTR(kIOTTYDeviceKey
),
2549 CFSTR(kIOTTYBaseNameKey
),
2550 CFSTR(kIOSerialBSDTypeKey
),
2553 #endif // !TARGET_OS_SIMULATOR
2555 const CFStringRef controller_dict_keys
[] = {
2557 CFSTR(kIOMACAddress
)
2560 const CFStringRef bus_dict_keys
[] = {
2564 if (hidden_key
!= NULL
) {
2566 val
= IORegistryEntrySearchCFProperty(interface
,
2570 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2573 goto done
; // if this interface should not be exposed
2577 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2578 // get the dictionary associated with the [interface] node
2579 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2580 if (kr
!= kIOReturnSuccess
) {
2581 SC_log(LOG_INFO
, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr
);
2585 interface_dict
= copyIORegistryProperties(interface
,
2586 interface_dict_keys
,
2587 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2588 #endif // !TARGET_OS_SIMULATOR
2590 // get the controller node
2591 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2592 if (kr
!= kIOReturnSuccess
) {
2593 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2597 controller_dict
= copyIORegistryProperties(controller
,
2598 controller_dict_keys
,
2599 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2602 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2603 if (kr
!= kIOReturnSuccess
) {
2604 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2608 bus_dict
= copyIORegistryProperties(bus
,
2610 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2612 // get the registry entry ID
2613 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2614 if (kr
!= kIOReturnSuccess
) {
2615 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2619 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2620 assert(interfacePrivate
!= NULL
);
2621 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2622 interfacePrivate
->entryID
= entryID
;
2624 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2625 val
= IORegistryEntrySearchCFProperty(interface
,
2627 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2629 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2631 if (isA_CFDictionary(val
)) {
2632 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2637 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2638 // get user-notification / auto-configuration preference
2639 val
= IORegistryEntrySearchCFProperty(interface
,
2641 kSCNetworkInterfaceConfigurationActionKey
,
2643 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2645 if (isA_CFString(val
)) {
2646 interfacePrivate
->configurationAction
= CFRetain(val
);
2651 // get HiddenConfiguration preference
2652 val
= IORegistryEntrySearchCFProperty(interface
,
2654 kSCNetworkInterfaceHiddenConfigurationKey
,
2656 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2658 interfacePrivate
->hidden
= TRUE
;
2662 #if TARGET_OS_IPHONE
2663 // get TrustRequired preference
2664 val
= IORegistryEntrySearchCFProperty(interface
,
2666 kSCNetworkInterfaceTrustRequiredKey
,
2668 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2670 if (isA_CFBoolean(val
)) {
2671 interfacePrivate
->trustRequired
= CFBooleanGetValue(val
);
2675 #endif // TARGET_OS_IPHONE
2677 CFRelease(interfacePrivate
);
2678 interfacePrivate
= NULL
;
2683 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2685 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2686 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2688 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2689 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2691 return (SCNetworkInterfaceRef
)interfacePrivate
;
2695 static CF_RETURNS_RETAINED CFArrayRef
2696 findMatchingInterfaces(CFDictionaryRef matching
,
2697 processInterface func
,
2698 CFStringRef hidden_key
,
2699 Boolean keep_pre_configured
)
2701 CFMutableArrayRef interfaces
;
2702 io_registry_entry_t interface
;
2704 io_iterator_t iterator
= MACH_PORT_NULL
;
2707 * A reference to the "matching" dictionary will be consumed by the
2708 * the call to IOServiceGetMatchingServices so we bump up the retain
2713 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2714 if (kr
!= kIOReturnSuccess
) {
2715 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2719 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2721 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2722 SCNetworkInterfaceRef match
;
2724 match
= createInterface(interface
, func
, hidden_key
);
2725 if (match
!= NULL
) {
2726 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2727 CFArrayAppendValue(interfaces
, match
);
2732 IOObjectRelease(interface
);
2735 IOObjectRelease(iterator
);
2742 #pragma mark helper functions
2746 findConfiguration(CFStringRef interface_type
)
2748 for (size_t i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2749 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2760 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2762 CFIndex interfaceIndex
;
2763 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2765 if (interfacePrivate
->serviceID
== NULL
) {
2766 // if not associated with a service (yet)
2767 _SCErrorSet(kSCStatusInvalidArgument
);
2771 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2772 if (interfaceIndex
== kCFNotFound
) {
2773 // unknown interface type, use per-service configuration preferences
2774 return interfacePrivate
->interface_type
; // entity
2777 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2778 // if configuration information can be associated with this interface type
2779 return *configurations
[interfaceIndex
].entity_hardware
;
2782 _SCErrorSet(kSCStatusInvalidArgument
);
2789 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2790 CFStringRef extendedType
,
2791 Boolean requirePerInterface
)
2793 CFStringRef defaultType
;
2794 CFIndex extendedIndex
;
2795 CFIndex interfaceIndex
;
2796 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2797 Boolean isL2TP
= FALSE
;
2800 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2801 if (defaultType
== NULL
) {
2805 if (CFEqual(extendedType
, defaultType
)) {
2806 // extended and default configuration types cannot conflict
2810 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2811 if (interfaceIndex
== kCFNotFound
) {
2812 // configuration information for unknown interface type's
2813 // are stored along with the service and we don't allow
2814 // per-service extended configurations
2818 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2819 CFStringRef interfaceType
;
2821 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2822 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2823 SCNetworkInterfaceRef child
;
2825 child
= SCNetworkInterfaceGetInterface(interface
);
2826 if (child
!= NULL
) {
2827 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2828 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2835 if (requirePerInterface
&&
2836 !configurations
[interfaceIndex
].per_interface_config
&&
2838 // we don't allow per-service extended configurations (except
2839 // that we do allow IPSec as an extended type for PPP->L2TP)
2843 extendedIndex
= findConfiguration(extendedType
);
2844 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2845 // extended type cannot match a known interface type (except
2846 // that we do allow IPSec as an extended type for PPP->L2TP)
2852 * Should we check/match and specifically allow known extended
2853 * configuration types (e.g. EAPOL)?
2855 * Should we check/match and specifically block known internal
2856 * configuration types (e.g. QoSMarking)?
2858 * Lastly, should we ensure that any non-standard extended configuration
2859 * types be of the form com.myCompany.myType?
2868 _SCErrorSet(kSCStatusInvalidArgument
);
2875 CFStringRef defaultType
;
2876 CFMutableArrayRef types
;
2877 } extendedConfiguration
, *extendedConfigurationRef
;
2881 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2883 #pragma unused(value)
2884 CFStringRef extendedType
= (CFStringRef
)key
;
2885 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2887 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2888 // do not include the default configuration type
2892 if (CFArrayContainsValue(myContextRef
->types
,
2893 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2895 // if extendedType already has already been added
2899 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2906 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2908 CFIndex interfaceIndex
;
2909 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2911 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2912 if (interfaceIndex
== kCFNotFound
) {
2913 // if per-service (not per interface) configuration
2917 if (!configurations
[interfaceIndex
].per_interface_config
) {
2918 // if per-interface configuration not allowed
2922 return interfaceIndex
;
2926 static CF_RETURNS_RETAINED CFArrayRef
2927 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2930 CFIndex interfaceIndex
;
2931 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2932 extendedConfiguration myContext
;
2933 SCNetworkServiceRef service
;
2937 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2938 if (myContext
.defaultType
== NULL
) {
2939 myContext
.types
= NULL
;
2943 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2945 if (interfacePrivate
->serviceID
== NULL
) {
2946 // if not associated with a service (yet)
2950 interfaceIndex
= findPerInterfaceConfiguration(interface
);
2951 if (interfaceIndex
== kCFNotFound
) {
2952 // if no per-interface configuration
2956 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2957 interfacePrivate
->prefs
,
2958 interfacePrivate
->serviceID
,
2961 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2962 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2964 for (i
= 0; i
< n
; i
++) {
2965 CFDictionaryRef configs
;
2968 CFArrayRef services
;
2969 SCNetworkSetRef set
;
2971 set
= CFArrayGetValueAtIndex(sets
, i
);
2972 services
= SCNetworkSetCopyServices(set
);
2973 found
= CFArrayContainsValue(services
,
2974 CFRangeMake(0, CFArrayGetCount(services
)),
2976 CFRelease(services
);
2982 // add stored extended configuration types
2983 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2984 SCNetworkSetGetSetID(set
), // set
2985 interfacePrivate
->entity_device
, // service
2987 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2989 if (isA_CFDictionary(configs
)) {
2990 CFDictionaryApplyFunction(configs
,
2991 __addExtendedConfigurationType
,
2995 // add not-yet-stored extended configuration types
2996 if (interfacePrivate
->unsaved
!= NULL
) {
2997 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2998 __addExtendedConfigurationType
,
3006 if (sets
!= NULL
) CFRelease(sets
);
3010 return myContext
.types
;
3014 stringCreateArray(CFStringRef str
)
3016 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3020 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3021 CFStringRef extendedType
)
3023 CFMutableArrayRef array
= NULL
;
3027 SCNetworkServiceRef service
;
3030 // known interface type, per-interface configuration preferences
3032 // 1. look for all sets which contain the associated service
3033 // 2. add a per-set path for the interface configuration for
3036 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3037 interfacePrivate
->prefs
,
3038 interfacePrivate
->serviceID
,
3039 (SCNetworkInterfaceRef
)interfacePrivate
);
3041 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3042 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3044 for (i
= 0; i
< n
; i
++) {
3045 CFArrayRef services
;
3046 SCNetworkSetRef set
;
3048 set
= CFArrayGetValueAtIndex(sets
, i
);
3049 services
= SCNetworkSetCopyServices(set
);
3050 if (CFArrayContainsValue(services
,
3051 CFRangeMake(0, CFArrayGetCount(services
)),
3053 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3054 SCNetworkSetGetSetID(set
), // set
3055 interfacePrivate
->entity_device
, // service
3056 extendedType
); // entity
3057 if (array
== NULL
) {
3058 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3060 CFArrayAppendValue(array
, path
);
3063 CFRelease(services
);
3067 if (sets
!= NULL
) CFRelease(sets
);
3073 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3074 CFStringRef extendedType
)
3076 CFArrayRef array
= NULL
;
3077 CFIndex interfaceIndex
;
3080 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3081 if (interfaceIndex
== kCFNotFound
) {
3082 // unknown interface type, use per-service configuration preferences
3083 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3084 interfacePrivate
->serviceID
, // service
3085 extendedType
); // entity
3086 array
= stringCreateArray(path
);
3090 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3091 // known interface type, per-service configuration preferences
3092 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3093 interfacePrivate
->serviceID
, // service
3094 extendedType
); // entity
3095 array
= stringCreateArray(path
);
3099 else if (interfacePrivate
->serviceID
!= NULL
) {
3100 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3108 #pragma mark SCNetworkInterface <--> preferences entity
3113 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3115 CFMutableDictionaryRef entity
;
3116 CFIndex interfaceIndex
;
3117 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3119 entity
= CFDictionaryCreateMutable(NULL
,
3121 &kCFTypeDictionaryKeyCallBacks
,
3122 &kCFTypeDictionaryValueCallBacks
);
3123 if (interfacePrivate
->entity_type
!= NULL
) {
3124 CFDictionarySetValue(entity
,
3125 kSCPropNetInterfaceType
,
3126 interfacePrivate
->entity_type
);
3128 if (interfacePrivate
->entity_subtype
!= NULL
) {
3129 CFDictionarySetValue(entity
,
3130 kSCPropNetInterfaceSubType
,
3131 interfacePrivate
->entity_subtype
);
3133 if (interfacePrivate
->entity_device
!= NULL
) {
3134 CFDictionarySetValue(entity
,
3135 kSCPropNetInterfaceDeviceName
,
3136 interfacePrivate
->entity_device
);
3138 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3139 CFDictionarySetValue(entity
,
3140 CFSTR("DeviceUniqueIdentifier"),
3141 interfacePrivate
->entity_device_unique
);
3143 if (interfacePrivate
->hidden
) {
3144 CFDictionarySetValue(entity
,
3145 kSCNetworkInterfaceHiddenConfigurationKey
,
3148 #if TARGET_OS_IPHONE
3149 if (interfacePrivate
->trustRequired
) {
3150 CFDictionarySetValue(entity
,
3151 kSCNetworkInterfaceTrustRequiredKey
,
3154 #endif // TARGET_OS_IPHONE
3156 // match the "hardware" with the lowest layer
3158 SCNetworkInterfaceRef nextInterface
;
3160 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3161 if (nextInterface
== NULL
) {
3165 interface
= nextInterface
;
3167 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3169 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3173 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3174 if (interfaceIndex
!= kCFNotFound
) {
3175 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3176 CFDictionarySetValue(entity
,
3177 kSCPropNetInterfaceHardware
,
3178 *configurations
[interfaceIndex
].entity_hardware
);
3181 CFDictionarySetValue(entity
,
3182 kSCPropNetInterfaceHardware
,
3183 interfacePrivate
->interface_type
);
3186 // add the localized display name (which will only be used when/if the
3187 // interface is removed from the system)
3188 CFDictionarySetValue(entity
,
3189 kSCPropUserDefinedName
,
3190 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3196 static SCNetworkInterfaceRef
3197 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3202 n
= CFArrayGetCount(interfaces
);
3203 for (i
= 0; i
< n
; i
++) {
3204 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3205 CFStringRef interfaceName
;
3207 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3208 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3209 CFRetain(interface
);
3217 #if !TARGET_OS_IPHONE
3218 static SCNetworkInterfaceRef
3219 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3222 SCNetworkInterfaceRef interface
= NULL
;
3224 if (prefs
== NULL
) {
3228 // check if the interface is an Ethernet Bond
3229 bonds
= SCBondInterfaceCopyAll(prefs
);
3230 if (bonds
!= NULL
) {
3231 interface
= findInterface(bonds
, ifDevice
);
3236 #endif // !TARGET_OS_IPHONE
3238 static SCNetworkInterfaceRef
3239 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3242 SCNetworkInterfaceRef interface
= NULL
;
3244 if (prefs
== NULL
) {
3248 // check if the interface is an bridge
3249 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3250 if (bridges
!= NULL
) {
3251 interface
= findInterface(bridges
, ifDevice
);
3257 static SCNetworkInterfaceRef
3258 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3260 SCNetworkInterfaceRef interface
= NULL
;
3263 if (prefs
== NULL
) {
3267 // check if the interface is a VLAN
3268 vlans
= SCVLANInterfaceCopyAll(prefs
);
3269 if (vlans
!= NULL
) {
3270 interface
= findInterface(vlans
, ifDevice
);
3280 static CFMutableDictionaryRef
3281 copy_ppp_entity(CFStringRef bsdName
)
3283 CFMutableDictionaryRef entity
= NULL
;
3284 CFStringRef pattern
;
3285 CFMutableArrayRef patterns
;
3286 CFDictionaryRef dict
;
3288 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3289 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3290 CFArrayAppendValue(patterns
, pattern
);
3292 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3293 CFArrayAppendValue(patterns
, pattern
);
3295 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3296 CFRelease(patterns
);
3299 const void * keys_q
[N_QUICK
];
3300 const void ** keys
= keys_q
;
3302 const void * vals_q
[N_QUICK
];
3303 const void ** vals
= vals_q
;
3305 n
= CFDictionaryGetCount(dict
);
3306 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3307 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3308 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3310 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3311 for (i
= 0; i
< n
; i
++) {
3312 CFArrayRef components
;
3313 CFStringRef interfaceKey
;
3314 CFDictionaryRef interfaceVal
;
3316 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3317 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3318 CFStringRef serviceID
;
3320 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3321 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3322 !CFEqual(bsdName
, ifName
)) {
3323 // if not matching PPP interface
3327 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3328 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3329 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3330 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3331 CFRelease(interfaceKey
);
3332 CFRelease(components
);
3333 if (interfaceVal
!= NULL
) {
3334 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3338 if (keys
!= keys_q
) {
3339 CFAllocatorDeallocate(NULL
, keys
);
3340 CFAllocatorDeallocate(NULL
, vals
);
3350 SCNetworkInterfaceRef
3351 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3352 CFStringRef bsdName
,
3355 #pragma unused(allocator)
3356 CFMutableDictionaryRef entity
= NULL
;
3358 SCNetworkInterfaceRef interface
;
3360 bzero(&ifr
, sizeof(ifr
));
3361 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3364 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3366 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3372 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3374 entity
= copy_ppp_entity(bsdName
);
3378 if (entity
== NULL
) {
3379 entity
= CFDictionaryCreateMutable(NULL
,
3381 &kCFTypeDictionaryKeyCallBacks
,
3382 &kCFTypeDictionaryValueCallBacks
);
3383 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3386 #if !TARGET_OS_IPHONE
3387 if ((flags
& kIncludeBondInterfaces
) == 0) {
3388 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3390 #endif // !TARGET_OS_IPHONE
3392 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3393 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3396 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3397 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3400 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3408 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3410 CFMutableStringRef interfacePrefix
= NULL
;
3414 if (isA_CFString(bsdName
) == NULL
) {
3415 SC_log(LOG_DEBUG
, "no BSD name");
3419 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3420 length
= CFStringGetLength(interfacePrefix
);
3422 while (length
> 0) {
3423 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3424 if (lastChar
>= '0' && lastChar
<= '9') {
3425 CFStringDelete(interfacePrefix
,
3426 CFRangeMake(length
-1, 1));
3431 length
= CFStringGetLength(interfacePrefix
);
3434 return interfacePrefix
;
3439 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3440 CFStringRef prefix
);
3444 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3446 Boolean success
= FALSE
;
3447 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3449 if (isA_SCNetworkInterface(interface
) == NULL
) {
3450 SC_log(LOG_INFO
, "No interface");
3454 if (CFEqual(currentBSDName
, newBSDName
)) {
3459 if (interfacePrivate
->entity_device
!= NULL
) {
3460 CFRelease(interfacePrivate
->entity_device
);
3462 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3470 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3472 Boolean success
= FALSE
;
3473 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3474 CFStringRef oldPath
= NULL
;
3475 CFStringRef newPath
= NULL
;
3477 // Using the BSD Name update the path
3478 oldPath
= interfacePrivate
->path
;
3479 if (isA_CFString(oldPath
) == NULL
) {
3482 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3483 if (interfacePrivate
->path
!= NULL
) {
3484 CFRelease(interfacePrivate
->path
);
3486 interfacePrivate
->path
= CFRetain(newPath
);
3490 if (newPath
!= NULL
) {
3498 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3501 SCNetworkInterfacePrivateRef interfacePrivate
;
3503 if (isA_CFString(prefix
) == NULL
) {
3507 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3511 if (interfacePrivate
->prefix
!= NULL
) {
3512 CFRelease(interfacePrivate
->prefix
);
3515 interfacePrivate
->prefix
= prefix
;
3522 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3525 SCNetworkInterfacePrivateRef interfacePrivate
;
3526 CFStringRef newBSDName
= NULL
;
3527 CFStringRef oldBSDName
= NULL
;
3529 if (isA_CFNumber(unit
) == NULL
) {
3532 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3534 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3536 if (interfacePrivate
->prefix
== NULL
) {
3537 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3538 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3539 if (interfaceNamePrefix
== NULL
) {
3540 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3543 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3544 CFRelease(interfaceNamePrefix
);
3549 if (interfacePrivate
->prefix
!= NULL
) {
3550 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3553 // Update the BSD Name
3554 if ((newBSDName
== NULL
) ||
3555 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3556 SC_log(LOG_INFO
, "BSD name update failed");
3560 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3561 SC_log(LOG_INFO
, "IOPath update failed");
3565 if (interfacePrivate
->unit
!= NULL
) {
3566 CFRelease(interfacePrivate
->unit
);
3568 interfacePrivate
->unit
= unit
;
3571 if (newBSDName
!= NULL
) {
3572 CFRelease(newBSDName
);
3580 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3582 CFMutableDictionaryRef interface_entity
= NULL
;
3583 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3584 CFBooleanRef active
= NULL
;
3585 CFStringRef bsdName
= NULL
;
3586 CFBooleanRef builtin
= NULL
;
3587 CFStringRef interfaceNamePrefix
= NULL
;
3588 CFNumberRef interfaceType
= NULL
;
3589 CFNumberRef interfaceUnit
= NULL
;
3590 CFDataRef macAddress
= NULL
;
3591 CFStringRef pathMatch
= NULL
;
3592 CFDictionaryRef info
= NULL
;
3593 CFStringRef type
= NULL
;
3595 if (interfacePrivate
->active
) {
3596 active
= kCFBooleanTrue
;
3599 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3600 if (!isA_CFString(bsdName
)) {
3604 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3605 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3606 if (!isA_CFString(interfaceNamePrefix
)) {
3610 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3611 if (!isA_CFNumber(interfaceType
)) {
3615 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3616 if (!isA_CFNumber(interfaceUnit
)) {
3620 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3621 if (!isA_CFData(macAddress
)) {
3625 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3626 if (!isA_CFString(pathMatch
)) {
3630 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3631 if (!isA_CFDictionary(info
)) {
3635 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3636 if (!isA_CFString(type
)) {
3640 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3641 &kCFTypeDictionaryKeyCallBacks
,
3642 &kCFTypeDictionaryValueCallBacks
);
3644 if (isA_CFBoolean(active
) != NULL
) {
3645 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3648 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3649 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3650 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3651 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3652 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3653 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3654 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3655 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3656 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3661 return interface_entity
;
3666 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3667 SCNetworkServiceRef service
)
3669 SCNetworkInterfacePrivateRef interfacePrivate
;
3670 SCNetworkServicePrivateRef servicePrivate
;
3672 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3673 if (interfacePrivate
->prefs
!= NULL
) {
3674 CFRelease(interfacePrivate
->prefs
);
3675 interfacePrivate
->prefs
= NULL
;
3677 if (interfacePrivate
->serviceID
!= NULL
) {
3678 CFRelease(interfacePrivate
->serviceID
);
3679 interfacePrivate
->serviceID
= NULL
;
3682 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3683 if (servicePrivate
->prefs
!= NULL
) {
3684 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3686 if (servicePrivate
->serviceID
!= NULL
) {
3687 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3696 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3701 if (bundle
== NULL
) {
3702 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3706 if (!isA_CFString(name
)) {
3707 // if no interface "name"
3711 // check non-localized name for a match
3712 str
= copy_interface_string(bundle
, key
, FALSE
);
3714 match
= CFEqual(name
, str
);
3721 // check localized name for a match
3722 str
= copy_interface_string(bundle
, key
, TRUE
);
3724 match
= CFEqual(name
, str
);
3735 #define kInterfaceTypeEthernetValue 6
3736 #define kInterfaceTypeFirewireValue 144
3739 static SCNetworkInterfaceRef
3740 __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator
,
3741 CFDictionaryRef interface_entity
)
3743 #pragma unused(allocator)
3744 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3745 CFBooleanRef active
= NULL
;
3746 CFStringRef bsdName
= NULL
;
3747 CFBooleanRef ioBuiltin
= NULL
;
3748 CFStringRef ioInterfaceNamePrefix
= NULL
;
3749 CFNumberRef ioInterfaceType
= NULL
;
3750 int ioInterfaceTypeNum
;
3751 CFNumberRef ioInterfaceUnit
= NULL
;
3752 CFDataRef ioMACAddress
= NULL
;
3753 CFStringRef ioPathMatch
= NULL
;
3754 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3755 CFStringRef userDefinedName
= NULL
;
3756 CFStringRef usbProductName
= NULL
;
3757 CFNumberRef idProduct
= NULL
;
3758 CFNumberRef idVendor
= NULL
;
3759 CFStringRef type
= NULL
;
3761 /* initialize runtime */
3762 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3764 if (isA_CFDictionary(interface_entity
) == NULL
) {
3765 SC_log(LOG_INFO
, "No interface entity");
3768 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3769 if (isA_CFBoolean(active
) == NULL
) {
3770 active
= kCFBooleanFalse
;
3772 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3773 if (isA_CFString(bsdName
) == NULL
) {
3774 SC_log(LOG_INFO
, "No BSD name");
3777 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3778 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3779 SC_log(LOG_INFO
, "No IOBuiltin property");
3782 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3783 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3784 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3785 if (ioInterfaceNamePrefix
== NULL
) {
3786 SC_log(LOG_INFO
, "No BSD interface name prefix");
3790 CFRetain(ioInterfaceNamePrefix
);
3792 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3793 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3794 SC_log(LOG_INFO
, "No IOInterfaceType");
3797 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3798 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3800 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3801 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3802 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3806 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3807 if (isA_CFData(ioMACAddress
) == NULL
) {
3808 SC_log(LOG_INFO
, "No IOMACAddress");
3811 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3812 if (isA_CFString(ioPathMatch
) == NULL
) {
3813 SC_log(LOG_INFO
, "No IOPathMatch");
3816 // Check if Path contains the BSD Name in the end
3818 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3819 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3820 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3823 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3824 #if !TARGET_OS_SIMULATOR
3825 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3826 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3827 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3828 #endif // !TARGET_OS_SIMULATOR
3830 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3831 if (isA_CFString(type
) == NULL
) {
3832 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3836 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3837 interfacePrivate
->active
= CFBooleanGetValue(active
);
3838 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3839 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3840 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3841 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3842 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3843 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3844 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3845 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3846 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3847 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3848 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3849 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3851 // Handling interface types to be seen in NetworkInterfaces.plist
3852 CFIndex interfaceIndex
;
3854 interfaceIndex
= findConfiguration(type
);
3855 if (interfaceIndex
!= kCFNotFound
) {
3856 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3858 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3861 // Extracting entity type from value of interface type
3862 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3863 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3864 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3865 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3868 if (ioInterfaceNamePrefix
!= NULL
) {
3869 CFRelease(ioInterfaceNamePrefix
);
3872 return (SCNetworkInterfaceRef
)interfacePrivate
;
3878 _SCNetworkInterfaceCacheOpen(void)
3880 if (!__SCNetworkInterfaceCacheIsOpen()) {
3881 S_interface_cache
= CFDictionaryCreateMutable(NULL
,
3883 &kCFTypeDictionaryKeyCallBacks
,
3884 &kCFTypeDictionaryValueCallBacks
);
3885 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): open", S_interface_cache
);
3892 _SCNetworkInterfaceCacheClose(void)
3894 if (__SCNetworkInterfaceCacheIsOpen()) {
3895 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): close", S_interface_cache
);
3896 CFRelease(S_interface_cache
);
3897 S_interface_cache
= NULL
;
3903 __SCNetworkInterfaceCacheAdd(CFStringRef bsdName
, CFArrayRef matchingInterfaces
)
3905 if (__SCNetworkInterfaceCacheIsOpen() &&
3907 matchingInterfaces
!= NULL
) {
3908 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): add %@", S_interface_cache
, bsdName
);
3909 CFDictionaryAddValue(S_interface_cache
, bsdName
, matchingInterfaces
);
3914 static inline Boolean
3915 __SCNetworkInterfaceCacheIsOpen(void)
3917 return (S_interface_cache
!= NULL
);
3922 __SCNetworkInterfaceCacheCopy(CFStringRef bsdName
)
3924 if (__SCNetworkInterfaceCacheIsOpen() &&
3926 CFArrayRef matchingInterfaces
= CFDictionaryGetValue(S_interface_cache
, bsdName
);
3927 if (matchingInterfaces
) {
3928 CFRetain(matchingInterfaces
);
3929 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache
, bsdName
);
3931 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache
, bsdName
);
3934 return matchingInterfaces
;
3941 SCNetworkInterfaceRef
3942 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3943 CFDictionaryRef interface_entity
,
3944 SCNetworkServiceRef service
)
3946 #pragma unused(allocator)
3947 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3948 CFStringRef ifDevice
;
3949 CFStringRef ifName
= NULL
;
3950 CFStringRef ifSubType
;
3952 CFStringRef ifUnique
;
3953 CFArrayRef matching_interfaces
= NULL
;
3954 SCPreferencesRef servicePref
= NULL
;
3955 Boolean useSystemInterfaces
= TRUE
;
3957 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3958 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3960 if (service
!= NULL
) {
3961 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3962 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3963 (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
)));
3966 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3967 if (ifType
== NULL
) {
3969 * The interface "Type" was not specified. We'll make an
3970 * assumption that this is an "Ethernet" interface. If a
3971 * real interface exists with the provided interface name
3972 * then the actual type will be set accordingly. If not, we'll
3973 * end up crafting an "Ethernet" SCNetworkInterface that
3974 * will keep the rest of the configuration APIs happy.
3976 ifType
= kSCValNetInterfaceTypeEthernet
;
3979 if (!isA_CFString(ifType
)) {
3983 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3984 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3985 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3986 if (!isA_CFString(ifSubType
)) {
3991 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3992 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3994 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3995 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3996 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3997 char bsdName
[IFNAMSIZ
];
3998 CFMutableDictionaryRef matching
;
4000 if (!isA_CFString(ifDevice
)) {
4004 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
4005 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4008 if (useSystemInterfaces
) {
4009 // Check to see if we already have the info in the cache
4010 matching_interfaces
= __SCNetworkInterfaceCacheCopy(ifDevice
);
4011 if (matching_interfaces
== NULL
) {
4012 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
4016 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
4017 if (matching
== NULL
) {
4020 matching_interfaces
= findMatchingInterfaces(matching
,
4021 processNetworkInterface
,
4022 kSCNetworkInterfaceHiddenInterfaceKey
,
4025 __SCNetworkInterfaceCacheAdd(ifDevice
, matching_interfaces
);
4026 CFRelease(matching
);
4029 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4030 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4031 CFDictionaryRef matching
;
4032 CFStringRef match_keys
[2];
4033 CFStringRef match_vals
[2];
4035 if (!isA_CFString(ifDevice
)) {
4039 if (useSystemInterfaces
) {
4040 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4041 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4043 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4044 match_vals
[1] = ifDevice
;
4046 matching
= CFDictionaryCreate(NULL
,
4047 (const void **)match_keys
,
4048 (const void **)match_vals
,
4049 sizeof(match_keys
)/sizeof(match_keys
[0]),
4050 &kCFTypeDictionaryKeyCallBacks
,
4051 &kCFTypeDictionaryValueCallBacks
);
4052 matching_interfaces
= findMatchingInterfaces(matching
,
4053 processSerialInterface
,
4054 kSCNetworkInterfaceHiddenPortKey
,
4056 CFRelease(matching
);
4058 if (ifUnique
== NULL
) {
4060 Boolean useDeviceName
= TRUE
;
4062 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4066 for (i
= 0; i
< n
; i
++) {
4067 SCNetworkInterfacePrivateRef scanPrivate
;
4069 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4070 if (scanPrivate
->entity_device_unique
!= NULL
) {
4071 useDeviceName
= FALSE
;
4077 if (useDeviceName
&& useSystemInterfaces
) {
4078 if (matching_interfaces
!= NULL
) {
4079 CFRelease(matching_interfaces
);
4082 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4083 matching
= CFDictionaryCreate(NULL
,
4084 (const void **)match_keys
,
4085 (const void **)match_vals
,
4086 sizeof(match_keys
)/sizeof(match_keys
[0]),
4087 &kCFTypeDictionaryKeyCallBacks
,
4088 &kCFTypeDictionaryValueCallBacks
);
4089 matching_interfaces
= findMatchingInterfaces(matching
,
4090 processSerialInterface
,
4091 kSCNetworkInterfaceHiddenPortKey
,
4093 CFRelease(matching
);
4096 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4097 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4098 kSCNetworkInterfaceTypeL2TP
);
4099 #pragma GCC diagnostic push
4100 #pragma GCC diagnostic ignored "-Wdeprecated"
4101 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4102 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4103 kSCNetworkInterfaceTypePPTP
);
4104 #pragma GCC diagnostic pop
4106 // XXX do we allow non-Apple variants of PPP??? XXX
4107 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4110 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4111 if (!isA_CFString(ifDevice
)) {
4115 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4116 kSCNetworkInterfaceType6to4
);
4117 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4118 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4119 kSCNetworkInterfaceTypeIPSec
);
4120 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4121 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4122 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4123 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4124 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4127 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4128 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4132 if (matching_interfaces
!= NULL
) {
4134 SCPreferencesRef prefs
;
4135 Boolean temp_preferences
= FALSE
;
4137 n
= CFArrayGetCount(matching_interfaces
);
4140 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4141 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4142 // if the unique ID's match
4143 CFRetain(interfacePrivate
);
4147 interfacePrivate
= NULL
;
4150 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4154 if (CFDictionaryGetValueIfPresent(interface_entity
,
4155 kSCPropUserDefinedName
,
4156 (const void **)&ifName
) &&
4157 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4161 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4162 if (prefs
== NULL
) {
4163 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4164 if (prefs
!= NULL
) {
4165 temp_preferences
= TRUE
;
4168 if (prefs
== NULL
) {
4171 #if !TARGET_OS_IPHONE
4172 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4173 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4175 #endif // !TARGET_OS_IPHONE
4176 if ((interfacePrivate
== NULL
)
4177 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4178 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4181 if ((interfacePrivate
== NULL
)
4182 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4183 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4185 if (temp_preferences
) CFRelease(prefs
);
4188 if (ifUnique
!= NULL
) {
4191 // we are looking for an interface with a unique ID
4192 // so let's try to focus our choices
4193 for (i
= 0; i
< n
; i
++) {
4194 SCNetworkInterfacePrivateRef scanPrivate
;
4196 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4197 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4198 if (interfacePrivate
!= NULL
) {
4199 // if we've matched more than one interface
4200 interfacePrivate
= NULL
;
4203 interfacePrivate
= scanPrivate
;
4206 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4207 kSCPropUserDefinedName
,
4208 (const void **)&ifName
)) {
4211 // we don't have a unique ID but do have an interface
4212 // name. If the matching interfaces do have IDs than
4213 // we can try to focus our choices using the name
4214 for (i
= 0; i
< n
; i
++) {
4215 SCNetworkInterfacePrivateRef scanPrivate
;
4217 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4218 if (scanPrivate
->entity_device_unique
!= NULL
) {
4219 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4220 CFStringRef scanName
;
4222 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4223 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4224 continue; // if not the same display name
4228 if (interfacePrivate
!= NULL
) {
4229 // if we've matched more than one interface
4230 interfacePrivate
= NULL
;
4233 interfacePrivate
= scanPrivate
;
4236 if (interfacePrivate
== NULL
) {
4237 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4238 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4240 CFRetain(interfacePrivate
);
4243 CFRelease(matching_interfaces
);
4248 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4250 * if device not present on this system
4252 if (!useSystemInterfaces
) {
4253 if (interfacePrivate
!= NULL
) {
4254 CFRelease(interfacePrivate
);
4258 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4259 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4260 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4261 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4262 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4264 // Using UserDefinedName to check the validity of preferences file
4265 // when useSystemInterfaces is FALSE
4266 if (!useSystemInterfaces
) {
4267 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4268 if (isA_CFString(userDefinedName
) != NULL
) {
4269 CFRetain(userDefinedName
);
4270 if (interfacePrivate
->name
!= NULL
) {
4271 CFRelease(interfacePrivate
->name
);
4273 interfacePrivate
->name
= userDefinedName
;
4275 CFRetain(userDefinedName
);
4276 if (interfacePrivate
->localized_name
!= NULL
) {
4277 CFRelease(interfacePrivate
->localized_name
);
4279 interfacePrivate
->localized_name
= userDefinedName
;
4283 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4284 CFStringRef entity_hardware
;
4285 SCNetworkInterfaceRef virtualInterface
;
4287 if (!useSystemInterfaces
&&
4288 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4289 #if !TARGET_OS_IPHONE
4290 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4291 #endif // !TARGET_OS_IPHONE
4292 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4293 CFRelease(interfacePrivate
);
4294 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4296 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4297 if (isA_CFString((entity_hardware
)) &&
4298 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4299 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4300 interfacePrivate
->localized_key
= CFSTR("airport");
4301 interfacePrivate
->sort_order
= kSortAirPort
;
4305 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4307 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4308 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4309 interfacePrivate
->localized_key
= CFSTR("iPhone");
4310 interfacePrivate
->sort_order
= kSortTethered
;
4311 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4312 interfacePrivate
->localized_key
= CFSTR("iPad");
4313 interfacePrivate
->sort_order
= kSortTethered
;
4314 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4315 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4316 interfacePrivate
->sort_order
= kSortThunderbolt
;
4317 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4318 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4319 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4320 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4321 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4322 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4323 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4324 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4325 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4327 interfacePrivate
->sort_order
= kSortEthernet
;
4331 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4332 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4333 interfacePrivate
->sort_order
= kSortFireWire
;
4334 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4335 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4336 CFStringRef entity_hardware
;
4338 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4339 if (isA_CFString((entity_hardware
)) &&
4340 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4341 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4342 interfacePrivate
->sort_order
= kSortAirPort
;
4344 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4345 interfacePrivate
->sort_order
= kSortEthernet
;
4347 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4348 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4349 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4350 interfacePrivate
->sort_order
= kSortBluetooth
;
4351 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4352 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4353 interfacePrivate
->sort_order
= kSortIrDA
;
4354 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4355 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4356 interfacePrivate
->sort_order
= kSortWWAN
;
4358 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4359 interfacePrivate
->sort_order
= kSortModem
;
4362 SCNetworkInterfaceRef child
;
4364 CFRelease(interfacePrivate
);
4365 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4366 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4367 if (interfacePrivate
== NULL
) {
4371 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4372 SCNetworkInterfaceRef child
;
4373 CFRelease(interfacePrivate
);
4374 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4375 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4376 if (interfacePrivate
== NULL
) {
4379 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4380 CFRelease(interfacePrivate
);
4381 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4382 kSCNetworkInterfaceTypeIPSec
);
4383 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4384 CFRelease(interfacePrivate
);
4385 if (!isA_CFString(ifDevice
)) {
4388 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4389 kSCNetworkInterfaceType6to4
);
4390 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4391 CFRelease(interfacePrivate
);
4392 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4393 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4394 // if vendor interface
4395 pthread_mutex_lock(&lock
);
4396 if (vendor_interface_types
== NULL
) {
4397 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4399 CFSetAddValue(vendor_interface_types
, ifType
);
4400 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4401 pthread_mutex_unlock(&lock
);
4403 // if unknown interface
4404 CFRelease(interfacePrivate
);
4405 interfacePrivate
= NULL
;
4409 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4410 interfacePrivate
->hidden
= TRUE
;
4412 #if TARGET_OS_IPHONE
4413 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceTrustRequiredKey
)) {
4414 interfacePrivate
->trustRequired
= TRUE
;
4416 #endif // TARGET_OS_IPHONE
4419 if (service
!= NULL
) {
4420 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4423 #if !TARGET_OS_IPHONE
4424 // set prefs & serviceID to Bond member interfaces
4425 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4430 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4431 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4432 for (i
= 0; i
< n
; i
++) {
4433 SCNetworkInterfaceRef member
;
4435 member
= CFArrayGetValueAtIndex(members
, i
);
4436 __SCNetworkInterfaceSetService(member
, service
);
4439 #endif // !TARGET_OS_IPHONE
4441 // set prefs & serviceID to Bridge member interfaces
4442 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4447 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4448 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4449 for (i
= 0; i
< n
; i
++) {
4450 SCNetworkInterfaceRef member
;
4452 member
= CFArrayGetValueAtIndex(members
, i
);
4453 __SCNetworkInterfaceSetService(member
, service
);
4456 // set prefs & serviceID to VLAN pyhsical interface
4457 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4458 SCNetworkInterfaceRef vlan_physical
;
4460 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4461 if (vlan_physical
!= NULL
) {
4462 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4467 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4468 SCNetworkInterfaceRef parent
;
4471 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4472 kSCNetworkInterfaceTypePPP
);
4473 CFRelease(interfacePrivate
);
4474 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4475 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4476 SCNetworkInterfaceRef parent
;
4479 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4480 kSCNetworkInterfaceTypeVPN
);
4481 CFRelease(interfacePrivate
);
4482 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4485 return (SCNetworkInterfaceRef
)interfacePrivate
;
4490 #pragma mark SCNetworkInterface APIs
4495 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4497 CFDictionaryRef matching
;
4498 CFArrayRef new_interfaces
;
4500 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4502 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4503 new_interfaces
= findMatchingInterfaces(matching
,
4504 processNetworkInterface
,
4505 kSCNetworkInterfaceHiddenInterfaceKey
,
4506 keep_pre_configured
);
4507 CFRelease(matching
);
4509 return new_interfaces
;
4515 __SCNetworkInterfaceCopyAll_Modem()
4517 CFDictionaryRef matching
;
4518 CFStringRef match_keys
[2];
4519 CFStringRef match_vals
[2];
4520 CFArrayRef new_interfaces
;
4522 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4523 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4525 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4526 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4528 matching
= CFDictionaryCreate(NULL
,
4529 (const void **)match_keys
,
4530 (const void **)match_vals
,
4531 sizeof(match_keys
)/sizeof(match_keys
[0]),
4532 &kCFTypeDictionaryKeyCallBacks
,
4533 &kCFTypeDictionaryValueCallBacks
);
4534 new_interfaces
= findMatchingInterfaces(matching
,
4535 processSerialInterface
,
4536 kSCNetworkInterfaceHiddenPortKey
,
4538 CFRelease(matching
);
4540 return new_interfaces
;
4546 __SCNetworkInterfaceCopyAll_RS232()
4548 CFDictionaryRef matching
;
4549 CFStringRef match_keys
[2];
4550 CFStringRef match_vals
[2];
4551 CFArrayRef new_interfaces
;
4553 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4554 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4556 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4557 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4559 matching
= CFDictionaryCreate(NULL
,
4560 (const void **)match_keys
,
4561 (const void **)match_vals
,
4562 sizeof(match_keys
)/sizeof(match_keys
[0]),
4563 &kCFTypeDictionaryKeyCallBacks
,
4564 &kCFTypeDictionaryValueCallBacks
);
4565 new_interfaces
= findMatchingInterfaces(matching
,
4566 processSerialInterface
,
4567 kSCNetworkInterfaceHiddenPortKey
,
4569 CFRelease(matching
);
4571 return new_interfaces
;
4575 #if !TARGET_OS_IPHONE
4577 addBTPANInterface(CFMutableArrayRef all_interfaces
)
4580 SCNetworkInterfaceRef interface
;
4583 n
= CFArrayGetCount(all_interfaces
);
4584 for (i
= 0; i
< n
; i
++) {
4585 SCNetworkInterfaceRef interface
;
4587 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4588 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4589 // if we already have a BT-PAN interface
4594 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4595 if (interface
!= NULL
) {
4596 // include BT-PAN interface
4597 CFArrayAppendValue(all_interfaces
, interface
);
4598 CFRelease(interface
);
4603 #endif // !TARGET_OS_IPHONE
4607 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4612 n
= CFArrayGetCount(new_interfaces
);
4613 for (i
= 0; i
< n
; i
++) {
4614 CFStringRef bsdName
;
4615 SCNetworkInterfaceRef interface
;
4617 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4618 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4619 if (bsdName
!= NULL
) {
4620 CFArrayAppendValue(all_interfaces
, interface
);
4629 __waitForInterfaces()
4634 SCDynamicStoreRef store
;
4636 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4637 if (store
== NULL
) {
4641 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4642 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4643 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4646 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4651 CFArrayRef changedKeys
;
4652 CFDictionaryRef dict
;
4653 Boolean quiet
= FALSE
;
4656 dict
= SCDynamicStoreCopyValue(store
, key
);
4658 if (isA_CFDictionary(dict
) &&
4659 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4660 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4669 ok
= SCDynamicStoreNotifyWait(store
);
4671 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4675 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4676 if (changedKeys
!= NULL
) {
4677 CFRelease(changedKeys
);
4689 CFArrayRef
/* of SCNetworkInterfaceRef's */
4690 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4692 CFMutableArrayRef all_interfaces
;
4693 CFArrayRef new_interfaces
;
4694 Boolean temp_preferences
= FALSE
;
4696 /* initialize runtime */
4697 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4699 /* wait for IOKit to quiesce */
4700 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4702 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4704 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4705 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4706 if (new_interfaces
!= NULL
) {
4707 add_interfaces(all_interfaces
, new_interfaces
);
4708 CFRelease(new_interfaces
);
4711 // get Modem interfaces
4712 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4713 if (new_interfaces
!= NULL
) {
4714 add_interfaces(all_interfaces
, new_interfaces
);
4715 CFRelease(new_interfaces
);
4718 // get serial (RS232) interfaces
4719 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4720 if (new_interfaces
!= NULL
) {
4721 add_interfaces(all_interfaces
, new_interfaces
);
4722 CFRelease(new_interfaces
);
4725 // get virtual network interfaces (Bond, Bridge, VLAN)
4726 if (prefs
== NULL
) {
4727 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4728 if (prefs
!= NULL
) {
4729 temp_preferences
= TRUE
;
4732 if (prefs
!= NULL
) {
4733 #if !TARGET_OS_IPHONE
4734 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4735 if (new_interfaces
!= NULL
) {
4736 add_interfaces(all_interfaces
, new_interfaces
);
4737 CFRelease(new_interfaces
);
4739 #endif // !TARGET_OS_IPHONE
4741 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4742 if (new_interfaces
!= NULL
) {
4743 add_interfaces(all_interfaces
, new_interfaces
);
4744 CFRelease(new_interfaces
);
4747 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4748 if (new_interfaces
!= NULL
) {
4749 add_interfaces(all_interfaces
, new_interfaces
);
4750 CFRelease(new_interfaces
);
4753 #if !TARGET_OS_IPHONE
4754 // add BT-PAN interface
4755 addBTPANInterface(all_interfaces
);
4756 #endif // !TARGET_OS_IPHONE
4758 if (temp_preferences
) CFRelease(prefs
);
4761 // all interfaces have been identified, order and return
4762 sort_interfaces(all_interfaces
);
4764 return all_interfaces
;
4768 CFArrayRef
/* of SCNetworkInterfaceRef's */
4769 SCNetworkInterfaceCopyAll()
4771 CFArrayRef all_interfaces
;
4773 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4774 return all_interfaces
;
4778 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4779 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4782 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4784 if (!isA_SCNetworkInterface(interface
)) {
4785 _SCErrorSet(kSCStatusInvalidArgument
);
4789 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4793 i
= findConfiguration(interfacePrivate
->interface_type
);
4794 if (i
!= kCFNotFound
) {
4795 if (configurations
[i
].supported_interfaces
!= doNone
) {
4796 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4797 if (configurations
[i
].supported_interfaces
& do6to4
) {
4798 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4800 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4801 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4803 if (configurations
[i
].supported_interfaces
& doPPP
) {
4804 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4806 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4807 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4811 SCNetworkInterfaceRef child
;
4813 child
= SCNetworkInterfaceGetInterface(interface
);
4814 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4815 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4816 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4822 return interfacePrivate
->supported_interface_types
;
4826 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4827 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4830 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4832 if (!isA_SCNetworkInterface(interface
)) {
4833 _SCErrorSet(kSCStatusInvalidArgument
);
4837 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4841 i
= findConfiguration(interfacePrivate
->interface_type
);
4842 if (i
!= kCFNotFound
) {
4843 if (configurations
[i
].supported_protocols
!= doNone
) {
4844 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4845 if (configurations
[i
].supported_protocols
& doDNS
) {
4846 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4848 if (configurations
[i
].supported_protocols
& doIPv4
) {
4849 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4851 if (configurations
[i
].supported_protocols
& doIPv6
) {
4852 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4854 if (configurations
[i
].supported_protocols
& doProxies
) {
4855 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4857 #if !TARGET_OS_IPHONE
4858 if (configurations
[i
].supported_protocols
& doSMB
) {
4859 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4861 #endif // !TARGET_OS_IPHONE
4867 return interfacePrivate
->supported_protocol_types
;
4871 SCNetworkInterfaceRef
4872 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4874 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4876 SCNetworkInterfacePrivateRef parentPrivate
;
4878 if (!isA_SCNetworkInterface(child
)) {
4879 _SCErrorSet(kSCStatusInvalidArgument
);
4883 if (!isA_CFString(interfaceType
)) {
4884 _SCErrorSet(kSCStatusInvalidArgument
);
4888 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4889 // can't layer on top of loopback
4890 _SCErrorSet(kSCStatusInvalidArgument
);
4894 childIndex
= findConfiguration(childPrivate
->interface_type
);
4896 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4898 childPrivate
->prefs
,
4899 childPrivate
->serviceID
);
4900 if (parentPrivate
== NULL
) {
4901 _SCErrorSet(kSCStatusFailed
);
4905 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4906 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4907 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4910 if (childIndex
!= kCFNotFound
) {
4911 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4912 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4914 // sorry, the child interface does not support PPP
4918 // if the child's interface type not known, use the child entities "Type"
4919 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4922 if (childPrivate
->entity_device
!= NULL
) {
4923 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4926 if (childPrivate
->entity_device_unique
!= NULL
) {
4927 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4929 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4930 if ((childIndex
== kCFNotFound
) ||
4931 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4932 // if the child interface does not support L2TP
4935 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4936 parentPrivate
->localized_key
= CFSTR("l2tp");
4937 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4938 #pragma GCC diagnostic push
4939 #pragma GCC diagnostic ignored "-Wdeprecated"
4940 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4941 if ((childIndex
== kCFNotFound
) ||
4942 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4943 // if the child interface does not support PPTP
4946 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4947 parentPrivate
->localized_key
= CFSTR("pptp");
4948 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4949 #pragma GCC diagnostic pop
4950 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4951 if ((childIndex
== kCFNotFound
) ||
4952 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4953 // if the child interface does not support 6to4
4957 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4958 parentPrivate
->localized_key
= CFSTR("6to4");
4959 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4960 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4961 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4962 if ((childIndex
== kCFNotFound
) ||
4963 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4964 // if the child interface does not support IPSec
4967 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4968 parentPrivate
->localized_key
= CFSTR("ipsec");
4969 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4970 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4971 if (childIndex
!= kCFNotFound
) {
4972 // if not a "vendor" child interface
4976 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4977 parentPrivate
->localized_key
= CFSTR("vpn");
4978 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4979 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4980 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4981 if (childPrivate
->entity_device
!= NULL
) {
4982 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4984 if (parentPrivate
->entity_subtype
!= NULL
) {
4985 CFArrayRef components
;
4987 CFStringRef vpnType
;
4990 // the "default" interface name is derived from the VPN type
4993 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4996 vpnType
= parentPrivate
->entity_subtype
;
4997 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4998 n
= CFArrayGetCount(components
);
5000 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
5001 CFMutableStringRef str
;
5003 str
= CFStringCreateMutableCopy(NULL
,
5005 CFArrayGetValueAtIndex(components
, n
- 2));
5006 (void) CFStringFindAndReplace(str
,
5009 CFRangeMake(0, CFStringGetLength(str
)),
5011 parentPrivate
->localized_name
= str
;
5013 CFRelease(components
);
5015 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
5016 // if custom interface type
5017 pthread_mutex_lock(&lock
);
5018 if (vendor_interface_types
== NULL
) {
5019 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
5021 CFSetAddValue(vendor_interface_types
, interfaceType
);
5022 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
5023 pthread_mutex_unlock(&lock
);
5025 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
5026 // a dictionary with the same
5027 // name as the interfaceType
5029 // unknown interface type
5033 parentPrivate
->hidden
= childPrivate
->hidden
;
5035 #if TARGET_OS_IPHONE
5036 parentPrivate
->trustRequired
= childPrivate
->trustRequired
;
5037 #endif // TARGET_OS_IPHONE
5039 if (childPrivate
->overrides
!= NULL
) {
5040 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5043 // The following change handles the case where a user has both an Ethernet and
5044 // PPPoE network service. Because a PPPoE service is typically associated with
5045 // an ISP we want it to be sorted higher in the service order.
5046 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5047 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5048 if ((childPrivate
->interface_type
!= NULL
) &&
5049 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5050 parentPrivate
->sort_order
= kSortAirportPPP
;
5052 parentPrivate
->sort_order
= kSortEthernetPPP
;
5055 // set sort order of the parent to match the child interface
5056 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5059 return (SCNetworkInterfaceRef
)parentPrivate
;
5063 CFRelease(parentPrivate
);
5064 _SCErrorSet(kSCStatusInvalidArgument
);
5071 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5073 CFDictionaryRef config
= NULL
;
5074 CFStringRef defaultType
;
5075 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5077 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5078 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5080 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5081 if (defaultType
!= NULL
) {
5085 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5086 SCNetworkSetGetSetID(set
), // set
5087 interfacePrivate
->entity_device
, // interface
5088 defaultType
); // entity
5090 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5093 if (config
== NULL
) {
5094 // if the "set" does not have a saved configuration, use
5095 // the [template] "interface" configuration
5096 if (interfacePrivate
->unsaved
!= NULL
) {
5097 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5098 if (config
== (CFDictionaryRef
)kCFNull
) {
5103 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5114 static CFDictionaryRef
5115 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5116 CFStringRef extendedType
)
5118 CFDictionaryRef config
= NULL
;
5119 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5122 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5123 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5125 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5126 if (paths
!= NULL
) {
5129 path
= CFArrayGetValueAtIndex(paths
, 0);
5130 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5134 if (interfacePrivate
->unsaved
!= NULL
) {
5135 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5136 if (config
== (CFDictionaryRef
)kCFNull
) {
5142 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5151 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5153 CFDictionaryRef config
;
5154 CFStringRef defaultType
;
5156 if (!isA_SCNetworkInterface(interface
)) {
5157 _SCErrorSet(kSCStatusInvalidArgument
);
5161 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5162 if (defaultType
== NULL
) {
5166 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5167 if (config
== NULL
) {
5168 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5169 SCNetworkInterfacePrivateRef interfacePrivate
;
5172 // if AirPort interface, check for a per-service config
5173 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5174 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5175 interfacePrivate
->serviceID
, // service
5176 kSCEntNetAirPort
); // entity
5177 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5181 if (config
== NULL
) {
5182 _SCErrorSet(kSCStatusOK
);
5190 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5191 CFStringRef extendedType
)
5193 CFDictionaryRef config
;
5195 if (!isA_SCNetworkInterface(interface
)) {
5196 _SCErrorSet(kSCStatusInvalidArgument
);
5200 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5201 _SCErrorSet(kSCStatusInvalidArgument
);
5205 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5206 if (config
== NULL
) {
5207 _SCErrorSet(kSCStatusOK
);
5216 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5218 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5220 return interfacePrivate
->entity_type
;
5226 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5228 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5230 return interfacePrivate
->entity_subtype
;
5235 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5237 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5239 if (!isA_SCNetworkInterface(interface
)) {
5240 _SCErrorSet(kSCStatusInvalidArgument
);
5244 if ((interfacePrivate
->interface
!= NULL
) &&
5245 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5246 _SCErrorSet(kSCStatusOK
);
5250 return interfacePrivate
->entity_device
;
5255 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5257 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5259 if (!isA_SCNetworkInterface(interface
)) {
5260 _SCErrorSet(kSCStatusInvalidArgument
);
5264 if ((interfacePrivate
->address
!= NULL
) &&
5265 (interfacePrivate
->addressString
== NULL
)) {
5269 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5272 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5273 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5275 if (n
> sizeof(mac
)) {
5276 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5279 for (cp
= mac_p
; n
> 0; n
-= 3) {
5280 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5283 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5284 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5287 return interfacePrivate
->addressString
;
5291 SCNetworkInterfaceRef
5292 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5294 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5296 if (!isA_SCNetworkInterface(interface
)) {
5297 _SCErrorSet(kSCStatusInvalidArgument
);
5301 return interfacePrivate
->interface
;
5306 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5308 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5310 if (!isA_SCNetworkInterface(interface
)) {
5311 _SCErrorSet(kSCStatusInvalidArgument
);
5315 return interfacePrivate
->interface_type
;
5320 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5322 CFStringRef str
= NULL
;
5325 str
= CFBundleCopyLocalizedString(bundle
,
5328 NETWORKINTERFACE_LOCALIZATIONS
);
5330 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5333 NETWORKINTERFACE_LOCALIZATIONS
);
5341 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5343 static Boolean reported
= FALSE
;
5344 CFStringRef str
= NULL
;
5346 str
= copy_string_from_bundle(bundle
, key
, localized
);
5349 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5355 if (CFEqual(str
, key
) && !reported
) {
5356 const CFStringRef knownStrKey
= CFSTR("airport");
5357 CFStringRef knownStrValue
= NULL
;
5359 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5360 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5361 /* We are here because we requested for a localized/non-localized string
5362 based on the localization key, but we were given the same key/NULL back,
5363 implying a bad...bad thing!
5365 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5369 #if TARGET_OS_IPHONE
5370 /* ...and we want to know about it! */
5371 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5372 #endif //TARGET_OS_IPHONE
5376 if (knownStrValue
!= NULL
) {
5377 CFRelease(knownStrValue
);
5387 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5389 CFMutableStringRef local
;
5392 local
= CFStringCreateMutable(NULL
, 0);
5394 while (interface
!= NULL
) {
5395 Boolean added
= FALSE
;
5396 SCNetworkInterfaceRef child
= NULL
;
5397 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5399 if ((interfacePrivate
->interface
!= NULL
) &&
5400 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5401 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5402 child
= interfacePrivate
->interface
;
5405 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5407 CFStringRef key
= interfacePrivate
->localized_key
;
5409 if (oldLocalization
) {
5410 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5411 interfacePrivate
->localized_key
);
5413 fmt
= copy_interface_string(bundle
, key
, localized
);
5415 CFStringAppendFormat(local
,
5418 interfacePrivate
->localized_arg1
,
5419 interfacePrivate
->localized_arg2
);
5423 if (oldLocalization
) {
5429 (interfacePrivate
->prefs
!= NULL
) &&
5430 (interfacePrivate
->serviceID
!= NULL
) &&
5432 CFDictionaryRef entity
;
5435 // check for (and use) the name of the interface when it
5436 // was last available
5437 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5438 interfacePrivate
->serviceID
,
5439 kSCEntNetInterface
);
5440 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5442 if (isA_CFDictionary(entity
)) {
5445 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5446 if (isA_CFString(name
)) {
5447 CFStringAppend(local
, name
);
5454 // create (non-)localized name based on the interface type
5455 CFStringAppend(local
, interfacePrivate
->interface_type
);
5457 // ... and, if this is a leaf node, the interface device
5458 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5459 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5463 if (child
!= NULL
) {
5464 // if this interface is layered over another
5465 CFStringAppend(local
, CFSTR(" --> "));
5471 name
= CFStringCreateCopy(NULL
, local
);
5478 #if !TARGET_OS_IPHONE
5481 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5485 if (!isA_SCNetworkInterface(interface
)) {
5486 _SCErrorSet(kSCStatusInvalidArgument
);
5490 name
= copy_display_name(interface
, TRUE
, TRUE
);
5497 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5499 CFStringRef localized_name
;
5501 if (!isA_SCNetworkInterface(interface
)) {
5502 _SCErrorSet(kSCStatusInvalidArgument
);
5506 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5507 return localized_name
;
5509 #endif // !TARGET_OS_IPHONE
5513 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5515 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5517 if (!isA_SCNetworkInterface(interface
)) {
5523 if (interfacePrivate
->name
!= NULL
) {
5524 CFRelease(interfacePrivate
->name
);
5526 interfacePrivate
->name
= name
;
5531 if (interfacePrivate
->localized_name
!= NULL
) {
5532 CFRelease(interfacePrivate
->localized_name
);
5534 interfacePrivate
->localized_name
= name
;
5539 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5541 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5543 if (!isA_SCNetworkInterface(interface
)) {
5547 return interfacePrivate
->name
;
5553 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5555 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5557 if (!isA_SCNetworkInterface(interface
)) {
5558 _SCErrorSet(kSCStatusInvalidArgument
);
5562 if (interfacePrivate
->name
== NULL
) {
5563 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5566 return interfacePrivate
->name
;
5571 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5573 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5575 if (!isA_SCNetworkInterface(interface
)) {
5576 _SCErrorSet(kSCStatusInvalidArgument
);
5580 if (interfacePrivate
->localized_name
== NULL
) {
5581 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5584 return interfacePrivate
->localized_name
;
5590 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5592 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5593 CFDictionaryRef overrides
= NULL
;
5595 if (interfacePrivate
->overrides
!= NULL
) {
5596 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5604 SCNetworkInterfaceGetTypeID(void)
5606 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5607 return __kSCNetworkInterfaceTypeID
;
5613 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5614 SCNetworkInterfaceRef interface
,
5615 CFStringRef defaultType
,
5616 CFDictionaryRef config
,
5619 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5622 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5623 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5625 if (defaultType
== NULL
) {
5626 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5627 if (defaultType
== NULL
) {
5632 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5639 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5640 SCNetworkSetGetSetID(set
), // set
5641 interfacePrivate
->entity_device
, // interface
5642 defaultType
); // entity
5644 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5647 // if configuration has been saved
5648 if (interfacePrivate
->unsaved
!= NULL
) {
5649 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5650 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5651 CFRelease(interfacePrivate
->unsaved
);
5652 interfacePrivate
->unsaved
= NULL
;
5658 if (config
== NULL
) {
5659 // remember that we are clearing the configuration
5660 config
= (CFDictionaryRef
)kCFNull
;
5663 if (interfacePrivate
->unsaved
== NULL
) {
5664 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5666 &kCFTypeDictionaryKeyCallBacks
,
5667 &kCFTypeDictionaryValueCallBacks
);
5669 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5672 _SCErrorSet(kSCStatusNoKey
);
5683 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5684 CFStringRef extendedType
,
5685 CFDictionaryRef config
,
5688 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5692 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5693 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5695 if (extendedType
== NULL
) {
5696 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5697 if (extendedType
== NULL
) {
5702 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5706 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5707 if (paths
!= NULL
) {
5711 n
= CFArrayGetCount(paths
);
5712 for (i
= 0; i
< n
; i
++) {
5715 path
= CFArrayGetValueAtIndex(paths
, i
);
5716 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5723 // if configuration has been saved
5724 if (interfacePrivate
->unsaved
!= NULL
) {
5725 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5726 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5727 CFRelease(interfacePrivate
->unsaved
);
5728 interfacePrivate
->unsaved
= NULL
;
5736 if (config
== NULL
) {
5737 // remember that we are clearing the configuration
5738 config
= (CFDictionaryRef
)kCFNull
;
5741 if (interfacePrivate
->unsaved
== NULL
) {
5742 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5744 &kCFTypeDictionaryKeyCallBacks
,
5745 &kCFTypeDictionaryValueCallBacks
);
5747 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5750 _SCErrorSet(kSCStatusNoKey
);
5759 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5761 CFStringRef defaultType
;
5764 if (!isA_SCNetworkInterface(interface
)) {
5765 _SCErrorSet(kSCStatusInvalidArgument
);
5769 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5770 if (defaultType
== NULL
) {
5774 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5776 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5778 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5786 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5787 CFStringRef extendedType
,
5788 CFDictionaryRef config
)
5792 if (!isA_SCNetworkInterface(interface
)) {
5793 _SCErrorSet(kSCStatusInvalidArgument
);
5797 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5801 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5803 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5805 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5813 #pragma mark SCNetworkInterface [Refresh Configuration] API
5816 #ifndef kSCEntNetRefreshConfiguration
5817 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5818 #endif // kSCEntNetRefreshConfiguration
5821 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5826 if (!isA_CFString(ifName
)) {
5827 _SCErrorSet(kSCStatusInvalidArgument
);
5831 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5832 kSCDynamicStoreDomainState
,
5834 kSCEntNetRefreshConfiguration
);
5835 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5842 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5844 CFDataRef data
= NULL
;
5846 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5847 uint32_t status
= kSCStatusOK
;
5848 CFDataRef reply
= NULL
;
5850 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5851 ok
= __SCPreferencesCreate_helper(prefs
);
5857 // serialize the interface name
5858 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5863 // have the helper "refresh" the configuration
5864 status
= kSCStatusOK
;
5866 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5867 SCHELPER_MSG_INTERFACE_REFRESH
,
5871 if (data
!= NULL
) CFRelease(data
);
5876 if (status
!= kSCStatusOK
) {
5885 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5886 _SCHelperClose(&prefsPrivate
->helper_port
);
5889 status
= kSCStatusAccessError
;
5894 _SCErrorSet(status
);
5900 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5903 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5905 if (!isA_SCNetworkInterface(interface
)) {
5906 _SCErrorSet(kSCStatusInvalidArgument
);
5910 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5911 if (ifName
== NULL
) {
5912 _SCErrorSet(kSCStatusInvalidArgument
);
5916 if (interfacePrivate
->prefs
!= NULL
) {
5917 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5918 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5920 if (prefsPrivate
->authorizationData
!= NULL
) {
5921 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5925 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5929 #if !TARGET_OS_IPHONE
5931 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5933 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5935 #endif // !TARGET_OS_IPHONE
5939 #pragma mark SCNetworkInterface Password APIs
5943 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5945 CFStringRef unique_id
= NULL
;
5947 if (config
!= NULL
) {
5948 CFStringRef encryption
;
5950 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5951 if (isA_CFString(encryption
) &&
5952 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5953 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5956 if (unique_id
== NULL
) {
5957 unique_id
= serviceID
;
5965 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5967 CFMutableStringRef shared_id
= NULL
;
5969 if (config
!= NULL
) {
5970 CFStringRef encryption
;
5972 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5973 if (isA_CFString(encryption
) &&
5974 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5975 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5976 if (shared_id
!= NULL
) {
5977 CFRetain(shared_id
);
5982 if (shared_id
== NULL
) {
5983 CFStringRef unique_id
;
5985 unique_id
= getPasswordID(config
, serviceID
);
5986 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5987 CFStringAppend(shared_id
, CFSTR(".SS"));
5995 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5997 CFMutableStringRef xauth_id
= NULL
;
5999 if (config
!= NULL
) {
6000 CFStringRef encryption
;
6002 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
6003 if (isA_CFString(encryption
) &&
6004 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
6005 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
6006 if (xauth_id
!= NULL
) {
6012 if (xauth_id
== NULL
) {
6013 CFStringRef unique_id
;
6015 unique_id
= getPasswordID(config
, serviceID
);
6016 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6017 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
6025 checkInterfacePassword(SCNetworkInterfaceRef interface
,
6026 SCNetworkInterfacePasswordType passwordType
,
6027 SCPreferencesRef
*prefs
,
6028 CFStringRef
*serviceID
)
6030 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6032 if (!isA_SCNetworkInterface(interface
)) {
6036 *serviceID
= interfacePrivate
->serviceID
;
6037 if (*serviceID
== NULL
) {
6041 *prefs
= interfacePrivate
->prefs
;
6042 if (*prefs
== NULL
) {
6046 switch (passwordType
) {
6047 case kSCNetworkInterfacePasswordTypePPP
: {
6048 CFStringRef interfaceType
;
6050 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6051 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6059 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6060 CFStringRef interfaceType
;
6062 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6063 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6064 interface
= SCNetworkInterfaceGetInterface(interface
);
6065 if (interface
!= NULL
) {
6066 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6067 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6068 // if PPP->L2TP interface
6072 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6073 // if IPSec interface
6080 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6084 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6085 CFStringRef interfaceType
;
6087 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6088 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6089 // if IPSec interface
6096 case kSCNetworkInterfacePasswordTypeVPN
: {
6097 CFStringRef interfaceType
;
6099 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6100 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6116 _SCErrorSet(kSCStatusInvalidArgument
);
6122 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6123 SCNetworkInterfacePasswordType passwordType
)
6125 Boolean exists
= FALSE
;
6126 SCPreferencesRef prefs
= NULL
;
6127 CFStringRef serviceID
= NULL
;
6129 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6133 switch (passwordType
) {
6134 case kSCNetworkInterfacePasswordTypePPP
: {
6135 CFDictionaryRef config
;
6136 CFStringRef unique_id
;
6138 // get configuration
6139 config
= SCNetworkInterfaceGetConfiguration(interface
);
6142 unique_id
= getPasswordID(config
, serviceID
);
6145 exists
= __extract_password(prefs
,
6147 kSCPropNetPPPAuthPassword
,
6148 kSCPropNetPPPAuthPasswordEncryption
,
6149 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6155 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6156 CFDictionaryRef config
;
6158 CFStringRef shared_id
;
6160 // get configuration
6161 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6163 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6165 config
= SCNetworkInterfaceGetConfiguration(interface
);
6168 // get sharedSecret ID
6169 shared_id
= copySharedSecretID(config
, serviceID
);
6172 exists
= __extract_password(prefs
,
6174 kSCPropNetIPSecSharedSecret
,
6175 kSCPropNetIPSecSharedSecretEncryption
,
6176 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6179 CFRelease(shared_id
);
6183 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6184 CFDictionaryRef config
;
6185 CFStringRef unique_id
= NULL
;
6187 // get configuration
6188 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6190 // get 802.1X identifier
6191 if (config
!= NULL
) {
6192 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6194 if (!isA_CFString(unique_id
)) {
6199 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6203 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6204 CFDictionaryRef config
;
6205 CFStringRef xauth_id
;
6207 // get configuration
6208 config
= SCNetworkInterfaceGetConfiguration(interface
);
6211 xauth_id
= copyXAuthID(config
, serviceID
);
6214 exists
= __extract_password(prefs
,
6216 kSCPropNetIPSecXAuthPassword
,
6217 kSCPropNetIPSecXAuthPasswordEncryption
,
6218 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6221 CFRelease(xauth_id
);
6225 case kSCNetworkInterfacePasswordTypeVPN
: {
6226 CFDictionaryRef config
;
6229 // get configuration
6230 config
= SCNetworkInterfaceGetConfiguration(interface
);
6233 vpn_id
= getPasswordID(config
, serviceID
);
6236 exists
= __extract_password(prefs
,
6238 kSCPropNetVPNAuthPassword
,
6239 kSCPropNetVPNAuthPasswordEncryption
,
6240 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6247 _SCErrorSet(kSCStatusInvalidArgument
);
6256 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6257 SCNetworkInterfacePasswordType passwordType
)
6259 CFDataRef password
= NULL
;
6260 SCPreferencesRef prefs
= NULL
;
6261 CFStringRef serviceID
= NULL
;
6263 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6267 switch (passwordType
) {
6268 case kSCNetworkInterfacePasswordTypePPP
: {
6269 CFDictionaryRef config
;
6270 CFStringRef unique_id
;
6272 // get configuration
6273 config
= SCNetworkInterfaceGetConfiguration(interface
);
6276 unique_id
= getPasswordID(config
, serviceID
);
6279 (void) __extract_password(prefs
,
6281 kSCPropNetPPPAuthPassword
,
6282 kSCPropNetPPPAuthPasswordEncryption
,
6283 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6289 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6290 CFDictionaryRef config
;
6292 CFStringRef shared_id
;
6294 // get configuration
6295 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6297 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6299 config
= SCNetworkInterfaceGetConfiguration(interface
);
6302 // get sharedSecret ID
6303 shared_id
= copySharedSecretID(config
, serviceID
);
6306 (void) __extract_password(prefs
,
6308 kSCPropNetIPSecSharedSecret
,
6309 kSCPropNetIPSecSharedSecretEncryption
,
6310 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6314 CFRelease(shared_id
);
6318 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6319 CFDictionaryRef config
;
6320 CFStringRef unique_id
= NULL
;
6322 // get configuration
6323 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6325 // get 802.1X identifier
6326 if (config
!= NULL
) {
6327 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6329 if (!isA_CFString(unique_id
)) {
6330 _SCErrorSet(kSCStatusFailed
);
6335 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6339 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6340 CFDictionaryRef config
;
6341 CFStringRef xauth_id
;
6343 // get configuration
6344 config
= SCNetworkInterfaceGetConfiguration(interface
);
6347 xauth_id
= copyXAuthID(config
, serviceID
);
6350 (void) __extract_password(prefs
,
6352 kSCPropNetIPSecXAuthPassword
,
6353 kSCPropNetIPSecXAuthPasswordEncryption
,
6354 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6357 CFRelease(xauth_id
);
6361 case kSCNetworkInterfacePasswordTypeVPN
: {
6362 CFDictionaryRef config
;
6365 // get configuration
6366 config
= SCNetworkInterfaceGetConfiguration(interface
);
6369 vpn_id
= getPasswordID(config
, serviceID
);
6372 (void) __extract_password(prefs
,
6374 kSCPropNetVPNAuthPassword
,
6375 kSCPropNetVPNAuthPasswordEncryption
,
6376 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6383 _SCErrorSet(kSCStatusInvalidArgument
);
6392 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6393 SCNetworkInterfacePasswordType passwordType
)
6396 SCPreferencesRef prefs
= NULL
;
6397 CFStringRef serviceID
= NULL
;
6399 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6403 switch (passwordType
) {
6404 case kSCNetworkInterfacePasswordTypePPP
: {
6405 CFDictionaryRef config
;
6406 CFDictionaryRef newConfig
= NULL
;
6407 CFStringRef unique_id
;
6409 // get configuration
6410 config
= SCNetworkInterfaceGetConfiguration(interface
);
6413 unique_id
= getPasswordID(config
, serviceID
);
6416 ok
= __remove_password(prefs
,
6418 kSCPropNetPPPAuthPassword
,
6419 kSCPropNetPPPAuthPasswordEncryption
,
6420 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6424 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6425 if (newConfig
!= NULL
) CFRelease(newConfig
);
6431 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6432 CFDictionaryRef config
;
6434 CFDictionaryRef newConfig
= NULL
;
6435 CFStringRef shared_id
;
6437 // get configuration
6438 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6440 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6442 config
= SCNetworkInterfaceGetConfiguration(interface
);
6445 // get sharedSecret ID
6446 shared_id
= copySharedSecretID(config
, serviceID
);
6449 ok
= __remove_password(prefs
,
6451 kSCPropNetIPSecSharedSecret
,
6452 kSCPropNetIPSecSharedSecretEncryption
,
6453 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6458 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6462 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6465 if (newConfig
!= NULL
) CFRelease(newConfig
);
6468 CFRelease(shared_id
);
6472 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6473 CFDictionaryRef config
;
6474 CFStringRef unique_id
= NULL
;
6476 // get configuration
6477 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6479 // get 802.1X identifier
6480 if (config
!= NULL
) {
6481 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6483 if (!isA_CFString(unique_id
)) {
6484 _SCErrorSet(kSCStatusFailed
);
6489 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6493 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6494 CFDictionaryRef config
;
6495 CFDictionaryRef newConfig
= NULL
;
6496 CFStringRef xauth_id
;
6498 // get configuration
6499 config
= SCNetworkInterfaceGetConfiguration(interface
);
6502 xauth_id
= copyXAuthID(config
, serviceID
);
6505 ok
= __remove_password(prefs
,
6507 kSCPropNetIPSecXAuthPassword
,
6508 kSCPropNetIPSecXAuthPasswordEncryption
,
6509 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6513 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6514 if (newConfig
!= NULL
) CFRelease(newConfig
);
6517 CFRelease(xauth_id
);
6521 case kSCNetworkInterfacePasswordTypeVPN
: {
6522 CFDictionaryRef config
;
6523 CFDictionaryRef newConfig
= NULL
;
6526 // get configuration
6527 config
= SCNetworkInterfaceGetConfiguration(interface
);
6530 vpn_id
= getPasswordID(config
, serviceID
);
6533 ok
= __remove_password(prefs
,
6535 kSCPropNetVPNAuthPassword
,
6536 kSCPropNetVPNAuthPasswordEncryption
,
6537 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6541 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6542 if (newConfig
!= NULL
) CFRelease(newConfig
);
6548 _SCErrorSet(kSCStatusInvalidArgument
);
6557 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6558 SCNetworkInterfacePasswordType passwordType
,
6560 CFDictionaryRef options
)
6562 CFStringRef account
= NULL
;
6563 CFDictionaryRef config
;
6564 CFStringRef description
= NULL
;
6565 CFStringRef label
= NULL
;
6567 SCPreferencesRef prefs
= NULL
;
6568 CFStringRef serviceID
= NULL
;
6570 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6574 switch (passwordType
) {
6575 case kSCNetworkInterfacePasswordTypePPP
: {
6576 SCNetworkServiceRef service
= NULL
;
6577 CFStringRef unique_id
;
6579 // get configuration
6580 config
= SCNetworkInterfaceGetConfiguration(interface
);
6583 unique_id
= getPasswordID(config
, serviceID
);
6585 // get "Account", "Name", "Kind"
6586 if (config
!= NULL
) {
6587 // auth name --> keychain "Account"
6588 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6590 // PPP [user defined] "name" --> keychain "Name"
6591 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6594 if (label
== NULL
) {
6595 // service name --> keychain "Name"
6596 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6601 label
= SCNetworkServiceGetName(service
);
6602 if (label
== NULL
) {
6603 // interface name --> keychain "Name"
6604 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6608 if (bundle
!= NULL
) {
6609 // "PPP Password" --> keychain "Kind"
6610 description
= CFBundleCopyLocalizedString(bundle
,
6611 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6612 CFSTR("PPP Password"),
6617 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6619 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6620 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6625 CFMutableDictionaryRef newConfig
;
6627 if (config
!= NULL
) {
6628 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6630 newConfig
= CFDictionaryCreateMutable(NULL
,
6632 &kCFTypeDictionaryKeyCallBacks
,
6633 &kCFTypeDictionaryValueCallBacks
);
6635 CFDictionarySetValue(newConfig
,
6636 kSCPropNetPPPAuthPassword
,
6638 CFDictionarySetValue(newConfig
,
6639 kSCPropNetPPPAuthPasswordEncryption
,
6640 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6641 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6642 CFRelease(newConfig
);
6645 if (description
!= NULL
) CFRelease(description
);
6646 if (service
!= NULL
) CFRelease(service
);
6650 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6651 CFDictionaryRef baseConfig
= NULL
;
6653 SCNetworkServiceRef service
= NULL
;
6654 CFStringRef shared_id
;
6656 // get configuration
6657 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6658 config
= SCNetworkInterfaceGetConfiguration(interface
);
6660 baseConfig
= config
;
6661 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6664 // get sharedSecret ID
6665 shared_id
= copySharedSecretID(config
, serviceID
);
6667 // get "Account", "Name", "Kind"
6668 if (config
!= NULL
) {
6669 CFStringRef localIdentifier
;
6670 CFStringRef localIdentifierType
;
6672 if (CFDictionaryGetValueIfPresent(config
,
6673 kSCPropNetIPSecLocalIdentifierType
,
6674 (const void **)&localIdentifierType
)
6675 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6676 && CFDictionaryGetValueIfPresent(config
,
6677 kSCPropNetIPSecLocalIdentifier
,
6678 (const void **)&localIdentifier
)
6679 && isA_CFString(localIdentifier
)) {
6680 // local identifier --> keychain "Account"
6681 account
= localIdentifier
;
6684 // PPP [user defined] "name" --> keychain "Name"
6686 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6688 if (baseConfig
!= NULL
) {
6689 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6694 if (label
== NULL
) {
6695 // service name --> keychain "Name"
6696 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6701 label
= SCNetworkServiceGetName(service
);
6702 if (label
== NULL
) {
6703 // interface name --> keychain "Name"
6704 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6708 if (bundle
!= NULL
) {
6709 // "IPSec Shared Secret" --> keychain "Kind"
6710 description
= CFBundleCopyLocalizedString(bundle
,
6711 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6712 CFSTR("IPSec Shared Secret"),
6717 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6719 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6720 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6725 CFMutableDictionaryRef newConfig
= NULL
;
6727 if (config
!= NULL
) {
6728 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6730 newConfig
= CFDictionaryCreateMutable(NULL
,
6732 &kCFTypeDictionaryKeyCallBacks
,
6733 &kCFTypeDictionaryValueCallBacks
);
6735 CFDictionarySetValue(newConfig
,
6736 kSCPropNetIPSecSharedSecret
,
6738 CFDictionarySetValue(newConfig
,
6739 kSCPropNetIPSecSharedSecretEncryption
,
6740 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6742 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6746 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6748 CFRelease(newConfig
);
6751 if (description
!= NULL
) CFRelease(description
);
6752 if (service
!= NULL
) CFRelease(service
);
6753 CFRelease(shared_id
);
6757 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6758 CFStringRef account
= NULL
;
6759 CFStringRef unique_id
= NULL
;
6761 // get configuration
6762 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6764 // get 802.1X identifier
6765 if (config
!= NULL
) {
6766 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6767 unique_id
= isA_CFString(unique_id
);
6769 if (unique_id
!= NULL
) {
6770 CFRetain(unique_id
);
6774 uuid
= CFUUIDCreate(NULL
);
6775 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6779 // 802.1x UserName --> keychain "Account"
6780 if (config
!= NULL
) {
6781 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6784 // get "Name", "Kind"
6785 if (bundle
!= NULL
) {
6786 CFStringRef interface_name
;
6788 // "Network Connection (%@)" --> keychain "Name"
6789 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6790 if (interface_name
!= NULL
) {
6791 CFStringRef label_fmt
;
6793 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6794 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6795 CFSTR("Network Connection (%@)"),
6797 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6798 CFRelease(label_fmt
);
6800 label
= CFBundleCopyLocalizedString(bundle
,
6801 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6802 CFSTR("Network Connection"),
6806 // "802.1X Password" --> keychain "Kind"
6807 description
= CFBundleCopyLocalizedString(bundle
,
6808 CFSTR("KEYCHAIN_KIND_EAPOL"),
6809 CFSTR("802.1X Password"),
6814 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6816 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6817 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6822 CFMutableDictionaryRef newConfig
= NULL
;
6824 if (config
!= NULL
) {
6825 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6827 newConfig
= CFDictionaryCreateMutable(NULL
,
6829 &kCFTypeDictionaryKeyCallBacks
,
6830 &kCFTypeDictionaryValueCallBacks
);
6832 CFDictionarySetValue(newConfig
,
6833 kEAPClientPropUserPasswordKeychainItemID
,
6835 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6838 CFRelease(newConfig
);
6841 CFRelease(unique_id
);
6842 if (label
!= NULL
) CFRelease(label
);
6843 if (description
!= NULL
) CFRelease(description
);
6847 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6848 SCNetworkServiceRef service
= NULL
;
6849 CFStringRef xauth_id
;
6851 // get configuration
6852 config
= SCNetworkInterfaceGetConfiguration(interface
);
6855 xauth_id
= copyXAuthID(config
, serviceID
);
6857 // get "Account", "Name", "Kind"
6858 if (config
!= NULL
) {
6859 // auth name --> keychain "Account"
6860 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6862 // IPSec [user defined] "name" --> keychain "Name"
6863 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6866 if (label
== NULL
) {
6867 // service name --> keychain "Name"
6868 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6873 label
= SCNetworkServiceGetName(service
);
6874 if (label
== NULL
) {
6875 // interface name --> keychain "Name"
6876 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6880 if (bundle
!= NULL
) {
6881 // "IPSec XAuth Password" --> keychain "Kind"
6882 description
= CFBundleCopyLocalizedString(bundle
,
6883 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6884 CFSTR("IPSec XAuth Password"),
6889 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6891 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6892 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6897 CFMutableDictionaryRef newConfig
;
6899 if (config
!= NULL
) {
6900 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6902 newConfig
= CFDictionaryCreateMutable(NULL
,
6904 &kCFTypeDictionaryKeyCallBacks
,
6905 &kCFTypeDictionaryValueCallBacks
);
6907 CFDictionarySetValue(newConfig
,
6908 kSCPropNetIPSecXAuthPassword
,
6910 CFDictionarySetValue(newConfig
,
6911 kSCPropNetIPSecXAuthPasswordEncryption
,
6912 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6913 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6914 CFRelease(newConfig
);
6917 CFRelease(xauth_id
);
6918 if (description
!= NULL
) CFRelease(description
);
6919 if (service
!= NULL
) CFRelease(service
);
6923 case kSCNetworkInterfacePasswordTypeVPN
: {
6924 SCNetworkServiceRef service
= NULL
;
6927 // get configuration
6928 config
= SCNetworkInterfaceGetConfiguration(interface
);
6931 vpn_id
= getPasswordID(config
, serviceID
);
6933 // get "Account", "Name", "Kind"
6934 if (config
!= NULL
) {
6935 // auth name --> keychain "Account"
6936 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6938 // VPN [user defined] "name" --> keychain "Name"
6939 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6942 if (label
== NULL
) {
6943 // service name --> keychain "Name"
6944 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6949 label
= SCNetworkServiceGetName(service
);
6950 if (label
== NULL
) {
6951 // interface name --> keychain "Name"
6952 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6956 if (bundle
!= NULL
) {
6957 // "VPN Password" --> keychain "Kind"
6958 description
= CFBundleCopyLocalizedString(bundle
,
6959 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6960 CFSTR("VPN Password"),
6965 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6967 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6968 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6973 CFMutableDictionaryRef newConfig
;
6975 if (config
!= NULL
) {
6976 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6978 newConfig
= CFDictionaryCreateMutable(NULL
,
6980 &kCFTypeDictionaryKeyCallBacks
,
6981 &kCFTypeDictionaryValueCallBacks
);
6983 CFDictionarySetValue(newConfig
,
6984 kSCPropNetVPNAuthPassword
,
6986 CFDictionarySetValue(newConfig
,
6987 kSCPropNetVPNAuthPasswordEncryption
,
6988 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6989 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6990 CFRelease(newConfig
);
6993 if (description
!= NULL
) CFRelease(description
);
6994 if (service
!= NULL
) CFRelease(service
);
6999 _SCErrorSet(kSCStatusInvalidArgument
);
7007 #pragma mark SCNetworkInterface [Advisory] SPIs
7008 #if TARGET_OS_SIMULATOR
7010 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7011 SCNetworkInterfaceAdvisory advisory
,
7014 #pragma unused(interface, advisory, reason)
7019 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7021 #pragma unused(interface)
7026 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7028 #pragma unused(interface)
7032 #else /* TARGET_OS_SIMULATOR */
7034 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7035 SCNetworkInterfaceAdvisory advisory
,
7038 IPMonitorControlRef control
;
7039 SCNetworkInterfacePrivateRef interfacePrivate
=
7040 (SCNetworkInterfacePrivateRef
)interface
;
7043 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7044 if (ifName
== NULL
) {
7045 _SCErrorSet(kSCStatusInvalidArgument
);
7048 control
= interfacePrivate
->IPMonitorControl
;
7049 if (control
== NULL
) {
7050 control
= IPMonitorControlCreate();
7051 if (control
== NULL
) {
7052 _SCErrorSet(kSCStatusFailed
);
7055 interfacePrivate
->IPMonitorControl
= control
;
7057 return IPMonitorControlSetInterfaceAdvisory(control
,
7064 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7066 IPMonitorControlRef control
;
7067 SCNetworkInterfacePrivateRef interfacePrivate
=
7068 (SCNetworkInterfacePrivateRef
)interface
;
7071 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7072 if (ifName
== NULL
) {
7073 _SCErrorSet(kSCStatusInvalidArgument
);
7076 control
= interfacePrivate
->IPMonitorControl
;
7077 if (control
== NULL
) {
7078 control
= IPMonitorControlCreate();
7079 if (control
== NULL
) {
7080 _SCErrorSet(kSCStatusFailed
);
7083 interfacePrivate
->IPMonitorControl
= control
;
7085 return IPMonitorControlInterfaceAdvisoryIsSet(control
, ifName
);
7089 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7093 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7094 if (ifName
== NULL
) {
7095 _SCErrorSet(kSCStatusInvalidArgument
);
7098 return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName
);
7100 #endif /* TARGET_OS_SIMULATOR */
7103 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
7107 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
7109 CFMutableDictionaryRef info
;
7110 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7113 if (interface
== NULL
) {
7117 info
= CFDictionaryCreateMutable(NULL
,
7119 &kCFTypeDictionaryKeyCallBacks
,
7120 &kCFTypeDictionaryValueCallBacks
);
7122 // add non-localized interface name
7123 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
7125 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
7129 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
7130 #if !TARGET_OS_SIMULATOR
7131 if (interfacePrivate
->usb
.name
!= NULL
) {
7132 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
7134 if (interfacePrivate
->usb
.vid
!= NULL
) {
7135 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
7137 if (interfacePrivate
->usb
.pid
!= NULL
) {
7138 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
7140 #endif // !TARGET_OS_SIMULATOR
7143 if (CFDictionaryGetCount(info
) == 0) {
7144 // do not return an empty dictionary
7153 SCNetworkInterfaceRef
7154 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7156 SCNetworkInterfaceRef interface
= NULL
;
7158 /* initialize runtime */
7159 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7161 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7162 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
7163 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7164 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
7172 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7174 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7176 return interfacePrivate
->configurationAction
;
7181 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7183 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7185 return interfacePrivate
->address
;
7190 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7192 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7194 return interfacePrivate
->prefix
;
7199 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7201 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7203 return interfacePrivate
->type
;
7208 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7210 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7212 return interfacePrivate
->unit
;
7217 update_ift_family(SCNetworkInterfaceRef interface
)
7219 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7221 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7223 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7224 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7227 bzero(&ifr
, sizeof(ifr
));
7228 if ((bsdName
!= NULL
) &&
7229 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7232 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7234 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7235 ifr
.ifr_type
.ift_family
= 0;
7236 ifr
.ifr_type
.ift_subfamily
= 0;
7242 interfacePrivate
->family
= CFNumberCreate(NULL
,
7243 kCFNumberSInt32Type
,
7244 &ifr
.ifr_type
.ift_family
);
7245 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7246 kCFNumberSInt32Type
,
7247 &ifr
.ifr_type
.ift_subfamily
);
7253 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7255 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7257 // note: family not in IORegistry, fetch with ioctl()
7259 if (interfacePrivate
->family
== NULL
) {
7260 update_ift_family(interface
);
7263 return interfacePrivate
->family
;
7268 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7270 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7272 // note: subfamily not in IORegistry, fetch with ioctl()
7274 if (interfacePrivate
->subfamily
== NULL
) {
7275 update_ift_family(interface
);
7278 return interfacePrivate
->subfamily
;
7283 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7285 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7287 return interfacePrivate
->path
;
7292 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7294 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7296 return interfacePrivate
->entryID
;
7302 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7304 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7306 return interfacePrivate
->active
;
7311 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7313 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7315 return interfacePrivate
->builtin
;
7320 _SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface
)
7322 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7324 return interfacePrivate
->trustRequired
;
7329 #pragma mark SCNetworkInterface SPIs
7334 SCNetworkInterfaceRef
7335 _SCNetworkInterfaceCopyBTPANInterface(void)
7337 CFDictionaryRef dict
;
7338 SCNetworkInterfaceRef interface
= NULL
;
7341 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7342 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7346 CFStringRef if_name
;
7347 SCNetworkInterfacePrivateRef interfacePrivate
;
7349 if (isA_CFDictionary(dict
) &&
7350 CFDictionaryGetValueIfPresent(dict
,
7351 kInterfaceNamerKey_BT_PAN_Name
,
7352 (const void **)&if_name
) &&
7353 isA_CFString(if_name
)) {
7354 CFMutableDictionaryRef entity
;
7356 entity
= CFDictionaryCreateMutable(NULL
,
7358 &kCFTypeDictionaryKeyCallBacks
,
7359 &kCFTypeDictionaryValueCallBacks
);
7360 CFDictionarySetValue(entity
,
7361 kSCPropNetInterfaceType
,
7362 kSCValNetInterfaceTypeEthernet
);
7363 CFDictionarySetValue(entity
,
7364 kSCPropNetInterfaceDeviceName
,
7366 CFDictionarySetValue(entity
,
7367 kSCPropUserDefinedName
,
7368 CFSTR(BT_PAN_NAME
));
7369 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7373 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7375 if ((interfacePrivate
!= NULL
) &&
7376 (interfacePrivate
->address
== NULL
) &&
7377 CFDictionaryGetValueIfPresent(dict
,
7378 kInterfaceNamerKey_BT_PAN_Mac
,
7379 (const void **)&addr
) &&
7381 interfacePrivate
->address
= CFRetain(addr
);
7389 #endif // TARGET_OS_OSX
7393 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7395 io_registry_entry_t device
;
7396 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7397 CFStringRef device_path
= NULL
;
7398 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7400 CFStringRef match_keys
[2];
7401 CFTypeRef match_vals
[2];
7402 CFDictionaryRef match_dict
;
7403 CFDictionaryRef matching
;
7405 if (interfacePrivate
->entity_device
== NULL
) {
7409 if (interfacePrivate
->entity_device_unique
== NULL
) {
7413 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7414 match_vals
[0] = interfacePrivate
->entity_device
;
7415 match_dict
= CFDictionaryCreate(NULL
,
7416 (const void **)match_keys
,
7417 (const void **)match_vals
,
7419 &kCFTypeDictionaryKeyCallBacks
,
7420 &kCFTypeDictionaryValueCallBacks
);
7422 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7423 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7424 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7425 match_vals
[1] = match_dict
;
7426 matching
= CFDictionaryCreate(NULL
,
7427 (const void **)match_keys
,
7428 (const void **)match_vals
,
7429 sizeof(match_keys
)/sizeof(match_keys
[0]),
7430 &kCFTypeDictionaryKeyCallBacks
,
7431 &kCFTypeDictionaryValueCallBacks
);
7432 CFRelease(match_dict
);
7434 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7435 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7436 if (kr
!= kIOReturnSuccess
) {
7437 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7441 while ((device_path
== NULL
) &&
7442 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7443 CFDictionaryRef overrides
;
7445 overrides
= IORegistryEntrySearchCFProperty(device
,
7447 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7449 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7450 if (overrides
!= NULL
) {
7451 CFDictionaryRef modemOverrides
;
7453 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7454 if (modemOverrides
!= NULL
) {
7455 CFRetain(modemOverrides
);
7457 CFRelease(overrides
);
7458 overrides
= modemOverrides
;
7460 if (overrides
== NULL
) {
7461 overrides
= IORegistryEntrySearchCFProperty(device
,
7463 CFSTR("DeviceModemOverrides"),
7465 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7467 if (overrides
!= NULL
) {
7468 if (isA_CFDictionary(overrides
)) {
7469 CFStringRef matchIdentifier
;
7471 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7472 if (isA_CFString(matchIdentifier
) &&
7473 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7474 device_path
= IORegistryEntryCreateCFProperty(device
,
7475 CFSTR(kIOTTYDeviceKey
),
7480 CFRelease(overrides
);
7482 IOObjectRelease(device
);
7485 IOObjectRelease(device_iterator
);
7489 if (device_path
== NULL
) {
7490 // if we haven't found an exact match to our UniqueIdentifier
7491 // so we simply return the base name.
7492 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7493 if (device_path
!= NULL
) {
7494 CFRetain(device_path
);
7506 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7508 #if TARGET_OS_SIMULATOR
7509 #pragma unused(interface)
7510 #else // TARGET_OS_SIMULATOR
7511 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7513 if (!interfacePrivate
->hidden
) {
7514 // if not HiddenConfiguration
7518 if ((interfacePrivate
->overrides
== NULL
) ||
7519 (!CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) &&
7520 !CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7521 // if no [IPv4/IPv6] configuration overrides
7525 if (interfacePrivate
->builtin
) {
7526 // if built-in (and overrides are present)
7530 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7533 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7534 (vid
== kIOUSBVendorIDAppleComputer
)) {
7535 // if Apple interface (and overrides are present)
7539 #endif // TARGET_OS_SIMULATOR
7546 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7548 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7550 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7555 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7557 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7559 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7564 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7566 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7568 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7573 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7575 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7577 return interfacePrivate
->hidden
;
7582 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7584 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7586 return (interfacePrivate
->sort_order
== kSortTethered
);
7591 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7593 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7594 CFStringRef interfaceType
;
7596 if (!isA_SCNetworkInterface(interface
)) {
7600 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7601 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7606 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7607 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7609 // if an empty bridge
7613 for (i
= 0; i
< n
; i
++) {
7614 SCNetworkInterfaceRef member
;
7615 SCNetworkInterfacePrivateRef memberPrivate
;
7617 member
= CFArrayGetValueAtIndex(members
, i
);
7618 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7619 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7624 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7628 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7636 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7638 CFDictionaryRef policy
;
7640 if (!isA_SCNetworkInterface(interface
)) {
7641 _SCErrorSet(kSCStatusInvalidArgument
);
7645 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7646 if (policy
== NULL
) {
7647 _SCErrorSet(kSCStatusOK
);
7654 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7658 if (!isA_SCNetworkInterface(interface
)) {
7659 _SCErrorSet(kSCStatusInvalidArgument
);
7663 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7665 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7667 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7675 #pragma mark SCNetworkInterface [internal] SPIs
7679 SCNetworkInterfacePrivateRef
7680 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7681 SCNetworkInterfaceRef interface
,
7682 SCPreferencesRef prefs
,
7683 CFStringRef serviceID
)
7685 #pragma unused(allocator)
7686 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7687 SCNetworkInterfacePrivateRef newPrivate
;
7689 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7690 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7692 if (interface
== kSCNetworkInterfaceIPv4
) {
7693 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7696 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7697 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7698 if (oldPrivate
->interface
!= NULL
) {
7699 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7700 oldPrivate
->interface
, // interface
7701 prefs
, // [new] prefs
7702 serviceID
); // [new] serviceID
7704 if (oldPrivate
->name
!= NULL
) {
7705 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7707 if (oldPrivate
->prefix
!= NULL
) {
7708 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7710 if (oldPrivate
->localized_name
!= NULL
) {
7711 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7713 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7714 if (oldPrivate
->localized_arg1
!= NULL
) {
7715 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7717 if (oldPrivate
->localized_arg2
!= NULL
) {
7718 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7720 if (oldPrivate
->unsaved
!= NULL
) {
7721 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7723 if (oldPrivate
->entity_device
!= NULL
) {
7724 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7726 if (oldPrivate
->entity_device_unique
!= NULL
) {
7727 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7729 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7730 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7731 if (oldPrivate
->supported_interface_types
!= NULL
) {
7732 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7734 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7735 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7737 if (oldPrivate
->address
!= NULL
) {
7738 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7740 newPrivate
->builtin
= oldPrivate
->builtin
;
7741 if (oldPrivate
->configurationAction
!= NULL
) {
7742 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7744 newPrivate
->hidden
= oldPrivate
->hidden
;
7745 #if TARGET_OS_IPHONE
7746 newPrivate
->trustRequired
= oldPrivate
->trustRequired
;
7747 #endif // TARGET_OS_IPHONE
7748 if (oldPrivate
->location
!= NULL
) {
7749 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7751 if (oldPrivate
->path
!= NULL
) {
7752 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7754 newPrivate
->entryID
= oldPrivate
->entryID
;
7755 if (oldPrivate
->overrides
!= NULL
) {
7756 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7758 if (oldPrivate
->type
!= NULL
) {
7759 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7761 if (oldPrivate
->unit
!= NULL
) {
7762 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7764 if (oldPrivate
->family
!= NULL
) {
7765 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7767 if (oldPrivate
->subfamily
!= NULL
) {
7768 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7770 if (oldPrivate
->usb
.name
!= NULL
) {
7771 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7773 if (oldPrivate
->usb
.vid
!= NULL
) {
7774 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7776 if (oldPrivate
->usb
.pid
!= NULL
) {
7777 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7779 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7781 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7782 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7783 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7785 if (oldPrivate
->bond
.mode
!= NULL
) {
7786 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7788 if (oldPrivate
->bond
.options
!= NULL
) {
7789 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7792 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7793 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7794 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7796 if (oldPrivate
->bridge
.options
!= NULL
) {
7797 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7800 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7801 if (oldPrivate
->vlan
.interface
!= NULL
) {
7802 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7804 if (oldPrivate
->vlan
.tag
!= NULL
) {
7805 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7807 if (oldPrivate
->vlan
.options
!= NULL
) {
7808 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7817 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7819 CFMutableArrayRef configs
;
7821 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7823 while (interface
!= NULL
) {
7824 CFStringRef defaultType
;
7825 CFMutableDictionaryRef interfaceConfiguration
;
7827 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7829 &kCFTypeDictionaryKeyCallBacks
,
7830 &kCFTypeDictionaryValueCallBacks
);
7832 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7833 if (defaultType
!= NULL
) {
7834 CFDictionaryRef config
;
7835 CFArrayRef extendedTypes
;
7838 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7840 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7842 if (config
== NULL
) {
7843 config
= (CFDictionaryRef
)kCFNull
;
7845 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7847 extendedTypes
= extendedConfigurationTypes(interface
);
7848 if (extendedTypes
!= NULL
) {
7852 n
= CFArrayGetCount(extendedTypes
);
7853 for (i
= 0; i
< n
; i
++) {
7854 CFStringRef extendedType
;
7856 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7857 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7858 if (config
== NULL
) {
7859 config
= (CFDictionaryRef
)kCFNull
;
7861 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7864 CFRelease(extendedTypes
);
7868 CFArrayAppendValue(configs
, interfaceConfiguration
);
7869 CFRelease(interfaceConfiguration
);
7871 interface
= SCNetworkInterfaceGetInterface(interface
);
7878 __private_extern__ Boolean
7879 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7881 CFArrayRef interfaces
;
7882 Boolean match
= FALSE
;
7883 CFMutableSetRef members
;
7885 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7887 #if !TARGET_OS_IPHONE
7888 // add Bond [member] interfaces
7889 interfaces
= SCBondInterfaceCopyAll(prefs
);
7890 if (interfaces
!= NULL
) {
7891 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7892 CFRelease(interfaces
);
7894 #endif // !TARGET_OS_IPHONE
7896 // add Bridge [member] interfaces
7897 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7898 if (interfaces
!= NULL
) {
7899 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7900 CFRelease(interfaces
);
7903 if (CFSetGetCount(members
) == 0) {
7907 while (interface
!= NULL
) {
7908 match
= CFSetContainsValue(members
, interface
);
7910 // if the interface is a member of an
7911 // Ethernet Bond or Bridge
7915 interface
= SCNetworkInterfaceGetInterface(interface
);
7927 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7931 for (i
= 0; interface
!= NULL
; i
++) {
7932 CFStringRef defaultType
;
7933 CFDictionaryRef interfaceConfiguration
;
7936 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7938 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7939 if (defaultType
!= NULL
) {
7940 CFDictionaryRef config
;
7941 CFArrayRef extendedTypes
;
7943 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7945 if (config
== (CFDictionaryRef
)kCFNull
) {
7949 // if service is not associated with the set
7950 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
7952 // apply default configuration to this set
7953 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
7956 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7959 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7961 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7966 extendedTypes
= extendedConfigurationTypes(interface
);
7967 if (extendedTypes
!= NULL
) {
7971 n
= CFArrayGetCount(extendedTypes
);
7972 for (j
= 0; j
< n
; j
++) {
7973 CFStringRef extendedType
;
7975 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7976 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7978 if (config
== (CFDictionaryRef
)kCFNull
) {
7981 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
7983 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7986 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7988 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7994 CFRelease(extendedTypes
);
7998 interface
= SCNetworkInterfaceGetInterface(interface
);
8005 SCNetworkInterfaceRef
8006 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
8008 SCNetworkInterfaceRef interface
;
8010 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
8011 if (interface
== NULL
) {
8015 if (store
!= NULL
) {
8016 SCNetworkInterfacePrivateRef interfacePrivate
=
8017 (SCNetworkInterfacePrivateRef
)interface
;
8020 interfacePrivate
->store
= store
;
8027 #if !TARGET_OS_SIMULATOR
8028 SCNetworkServicePrimaryRank
8029 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8031 IPMonitorControlRef control
;
8032 SCNetworkInterfacePrivateRef interfacePrivate
=
8033 (SCNetworkInterfacePrivateRef
)interface
;
8034 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
8036 control
= interfacePrivate
->IPMonitorControl
;
8037 if (control
!= NULL
) {
8040 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8041 if (ifName
!= NULL
) {
8042 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
8046 _SCErrorSet(kSCStatusInvalidArgument
);
8053 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8054 SCNetworkServicePrimaryRank newRank
)
8056 IPMonitorControlRef control
;
8057 SCNetworkInterfacePrivateRef interfacePrivate
=
8058 (SCNetworkInterfacePrivateRef
)interface
;
8061 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8062 if (ifName
== NULL
) {
8063 _SCErrorSet(kSCStatusInvalidArgument
);
8066 control
= interfacePrivate
->IPMonitorControl
;
8067 if (control
== NULL
) {
8068 control
= IPMonitorControlCreate();
8069 if (control
== NULL
) {
8070 _SCErrorSet(kSCStatusFailed
);
8073 interfacePrivate
->IPMonitorControl
= control
;
8075 return IPMonitorControlSetInterfacePrimaryRank(control
,
8081 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8083 Boolean disable_until_needed
= FALSE
;
8084 CFNumberRef disable_prop
= NULL
;
8085 CFIndex interfaceIndex
;
8086 SCNetworkInterfacePrivateRef interfacePrivate
8087 = (SCNetworkInterfacePrivateRef
)interface
;
8088 CFArrayRef path_list
;
8090 if (interfacePrivate
->prefs
== NULL
) {
8091 _SCErrorSet(kSCStatusInvalidArgument
);
8094 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8095 if (interfaceIndex
== kCFNotFound
) {
8096 _SCErrorSet(kSCStatusInvalidArgument
);
8099 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8100 if (path_list
!= NULL
) {
8101 CFDictionaryRef config
;
8102 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
8104 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
8105 CFRelease(path_list
);
8106 if (config
!= NULL
) {
8109 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
8110 disable_prop
= isA_CFNumber(disable_prop
);
8111 if (disable_prop
!= NULL
) {
8112 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
8113 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
8116 /* invalid property, ignore it */
8117 disable_prop
= NULL
;
8122 if (disable_prop
== NULL
) {
8123 disable_until_needed
8124 = _SCNetworkInterfaceIsTethered(interface
);
8126 _SCErrorSet(kSCStatusOK
);
8127 return (disable_until_needed
);
8131 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8135 CFIndex interfaceIndex
;
8136 SCNetworkInterfacePrivateRef interfacePrivate
8137 = (SCNetworkInterfacePrivateRef
)interface
;
8139 CFArrayRef path_list
;
8141 if (interfacePrivate
->prefs
== NULL
) {
8142 _SCErrorSet(kSCStatusInvalidArgument
);
8145 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
8146 _SCErrorSet(kSCStatusInvalidArgument
);
8149 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8150 if (interfaceIndex
== kCFNotFound
) {
8151 _SCErrorSet(kSCStatusInvalidArgument
);
8154 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8155 if (path_list
== NULL
) {
8156 _SCErrorSet(kSCStatusInvalidArgument
);
8159 count
= CFArrayGetCount(path_list
);
8160 for (i
= 0; i
< count
; i
++) {
8161 CFDictionaryRef config
;
8162 CFMutableDictionaryRef new_config
;
8163 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
8165 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
8166 if (config
!= NULL
) {
8168 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
8171 = CFDictionaryCreateMutable(NULL
, 0,
8172 &kCFTypeDictionaryKeyCallBacks
,
8173 &kCFTypeDictionaryValueCallBacks
);
8175 if (disable
!= NULL
) {
8176 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
8178 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
8180 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
,
8182 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
8184 CFRelease(new_config
);
8189 CFRelease(path_list
);
8194 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8201 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8202 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8208 #else // !TARGET_OS_SIMULATOR
8210 SCNetworkServicePrimaryRank
8211 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8213 #pragma unused(interface)
8214 return (kSCNetworkServicePrimaryRankDefault
);
8218 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8219 SCNetworkServicePrimaryRank newRank
)
8221 #pragma unused(interface)
8222 #pragma unused(newRank)
8223 _SCErrorSet(kSCStatusInvalidArgument
);
8228 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8230 #pragma unused(interface)
8235 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8237 #pragma unused(interface)
8238 #pragma unused(disable)
8243 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8245 #pragma unused(interface)
8246 #pragma unused(disable)
8247 _SCErrorSet(kSCStatusInvalidArgument
);
8251 #endif // !TARGET_OS_SIMULATOR
8255 CFArrayRef
// SCNetworkInterfaceRef
8256 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs
)
8258 CFStringRef defaultNetworkInterfacePath
= NULL
;
8260 CFMutableArrayRef interfaceList
= NULL
;
8261 SCNetworkInterfaceRef interfaceNamer
= NULL
;
8263 /* initialize runtime */
8264 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8266 if (ni_prefs
== NULL
) {
8267 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8268 assert(defaultNetworkInterfacePath
!= NULL
);
8269 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8272 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8273 if (isA_CFArray(if_list
)) {
8275 CFIndex n
= CFArrayGetCount(if_list
);
8277 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8278 for (i
= 0; i
< n
; i
++) {
8279 CFDictionaryRef dict
;
8281 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8282 if (isA_CFDictionary(dict
) != NULL
) {
8283 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
);
8285 if (interfaceNamer
!= NULL
) {
8286 CFArrayAppendValue(interfaceList
, interfaceNamer
);
8287 CFRelease(interfaceNamer
);
8293 if (defaultNetworkInterfacePath
!= NULL
) {
8294 CFRelease(defaultNetworkInterfacePath
);
8295 // prefs were created in the function, and hence need to be released
8296 CFRelease(ni_prefs
);
8298 return interfaceList
;
8304 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
8306 CFStringRef defaultNetworkInterfacePath
= NULL
;
8307 Boolean success
= FALSE
;
8309 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
8310 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8311 assert(defaultNetworkInterfacePath
!= NULL
);
8312 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8315 if (isA_CFArray(interfacesToSave
) == NULL
) {
8316 SC_log(LOG_INFO
, "No interfaces to save");
8319 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
8322 if (defaultNetworkInterfacePath
!= NULL
) {
8323 CFRelease(defaultNetworkInterfacePath
);
8324 // prefs were created in the function, and hence need to be released
8332 SCNetworkInterfaceRef
8333 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8336 SCNetworkInterfaceRef interface
= NULL
;
8337 CFStringRef defaultNetworkInterfacePath
;
8339 /* initialize runtime */
8340 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8342 if (ni_prefs
== NULL
) {
8343 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8344 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8345 CFRelease(defaultNetworkInterfacePath
);
8351 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8353 if (isA_CFArray(if_list
) != NULL
) {
8355 CFIndex count
= CFArrayGetCount(if_list
);
8357 for (idx
= 0; idx
< count
; idx
++) {
8358 CFDictionaryRef dict
;
8359 CFStringRef tmp_bsdName
;
8361 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8362 if (isA_CFDictionary(dict
) == NULL
) {
8366 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8367 if (tmp_bsdName
== NULL
) {
8370 if (CFEqual(bsdName
, tmp_bsdName
)) {
8371 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
);
8377 CFRelease(ni_prefs
);
8383 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8385 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8386 CFStringRef bsdName
= NULL
;
8387 SCNetworkInterfaceRef interface
= NULL
;
8390 count
= CFArrayGetCount(interfaces
);
8392 SC_log(LOG_INFO
, "No interfaces");
8395 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8397 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8398 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8400 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8401 if (isA_CFString(bsdName
) == NULL
) {
8402 SC_log(LOG_INFO
, "No BSD name");
8405 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8407 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8408 CFRelease(mappingBSDToInterface
);
8409 mappingBSDToInterface
= NULL
;
8410 SC_log(LOG_INFO
, "No mappings");
8413 return mappingBSDToInterface
;
8416 __private_extern__ Boolean
8417 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8419 CFStringRef intfSubtype
;
8421 if (entity
== NULL
) {
8425 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8426 #pragma GCC diagnostic push
8427 #pragma GCC diagnostic ignored "-Wdeprecated"
8428 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8431 #pragma GCC diagnostic pop