2 * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
29 * which includes code originally authored by
30 * Robert Ulrich <rulrich@apple.com>
31 * Elizabeth Douglas <elizabeth@apple.com>
32 * Quinn <eskimo1@apple.com>
36 #include <Availability.h>
37 #include <TargetConditionals.h>
38 #include <CoreFoundation/CoreFoundation.h>
39 #include <CoreFoundation/CFRuntime.h>
40 #include "SCNetworkConfigurationInternal.h"
41 #include "SCPreferencesInternal.h"
42 #include "SCHelper_client.h"
43 #include "plugin_shared.h"
46 #include <EAP8021X/EAPClientProperties.h>
47 #else // !TARGET_OS_IPHONE
48 #ifndef kEAPClientPropUserName
49 #define kEAPClientPropUserName CFSTR("UserName")
51 #ifndef kEAPClientPropUserPasswordKeychainItemID
52 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
54 #endif // !TARGET_OS_IPHONE
56 #include <IOKit/IOKitLib.h>
57 #include <IOKit/IOCFBundle.h>
58 #include <IOKit/IOBSD.h>
59 #include <IOKit/network/IONetworkController.h>
60 #include <IOKit/network/IONetworkInterface.h>
61 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
62 #include <IOKit/serial/IOSerialKeys.h>
63 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
64 #if !TARGET_OS_SIMULATOR
65 #include <IOKit/usb/IOUSBLib.h>
66 #endif // !TARGET_OS_SIMULATOR
68 #include "dy_framework.h"
70 #ifndef kIODeviceSupportsHoldKey
71 #define kIODeviceSupportsHoldKey "V92Modem"
74 #ifndef kPCIThunderboltString
75 #define kPCIThunderboltString "PCI-Thunderbolt"
78 #ifndef kIOUserEthernetInterfaceRoleKey
79 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
82 #ifndef kIOUSBHostInterfaceClassName
83 #define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
88 #include <mach/mach.h>
90 #include <net/if_types.h>
91 #include <net/if_dl.h>
92 #include <net/route.h>
93 #include <sys/ioctl.h>
94 #include <sys/param.h>
95 #include <sys/types.h>
96 #include <sys/socket.h>
98 #include <sys/sysctl.h>
103 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
104 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
105 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
106 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
107 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
108 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
127 kSortBluetoothPAN_GN
,
128 kSortBluetoothPAN_NAP
,
138 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
139 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
140 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
141 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
142 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
143 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
144 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
145 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
146 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
147 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
148 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
149 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
150 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
151 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
152 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
153 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
154 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
155 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
157 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
159 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
160 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
161 .sort_order
= kSortUnknown
, // sort_order
164 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
166 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
167 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
168 .sort_order
= kSortUnknown
, // sort_order
171 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
173 static CFMutableSetRef vendor_interface_types
= NULL
;
176 #pragma mark SCNetworkInterface configuration details
185 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
190 #define doProxies 1<<4
191 #if !TARGET_OS_IPHONE
193 #else // !TARGET_OS_IPHONE
195 #endif // !TARGET_OS_IPHONE
197 static const struct {
198 const CFStringRef
*interface_type
;
199 const CFStringRef
*entity_hardware
;
200 Boolean per_interface_config
;
201 uint32_t supported_interfaces
;
202 const CFStringRef
*ppp_subtype
;
203 uint32_t supported_protocols
;
204 } configurations
[] = {
205 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
206 // ===================================== ==================== ========== =============== ======================================= =========================================
207 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
208 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
209 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
210 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
211 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
212 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
213 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
214 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
215 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
216 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
217 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
218 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
219 #pragma GCC diagnostic push
220 #pragma GCC diagnostic ignored "-Wdeprecated"
221 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
222 #pragma GCC diagnostic pop
223 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
224 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
225 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
226 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
227 // ===================================== =================== ========== =============== ======================================= =========================================
228 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
229 // ===================================== =================== ========== =============== ======================================= =========================================
230 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
234 #define kSCNetworkInterfaceActive "Active"
235 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
236 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
237 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
238 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
239 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
240 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
241 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
242 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
243 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
246 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
247 static CFBundleRef bundle
= NULL
;
250 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
253 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
255 "SCNetworkInterface", // className
258 __SCNetworkInterfaceDeallocate
, // dealloc
259 __SCNetworkInterfaceEqual
, // equal
260 __SCNetworkInterfaceHash
, // hash
261 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
262 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
266 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
267 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
268 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
271 static mach_port_t masterPort
= MACH_PORT_NULL
;
274 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
276 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
280 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
282 CFAllocatorRef allocator
= CFGetAllocator(cf
);
283 CFMutableStringRef result
;
284 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
286 result
= CFStringCreateMutable(allocator
, 0);
287 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
288 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
289 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
290 if (interfacePrivate
->entity_device_unique
!= NULL
) {
291 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
293 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
294 if (interfacePrivate
->entity_subtype
!= NULL
) {
295 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
297 if (interfacePrivate
->name
!= NULL
) {
298 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
300 if (interfacePrivate
->localized_name
!= NULL
) {
301 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
303 if (interfacePrivate
->localized_key
!= NULL
) {
304 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
305 if (interfacePrivate
->localized_arg1
!= NULL
) {
306 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
308 if (interfacePrivate
->localized_arg2
!= NULL
) {
309 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
313 if (interfacePrivate
->address
!= NULL
) {
318 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
320 data
= CFDataGetBytePtr(interfacePrivate
->address
);
321 dataLen
= CFDataGetLength(interfacePrivate
->address
);
322 for (i
= 0; i
< dataLen
; i
++) {
323 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
328 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
329 if (interfacePrivate
->hidden
) {
330 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
332 if (interfacePrivate
->modemIsV92
) {
333 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
335 if (interfacePrivate
->location
!= NULL
) {
336 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
338 if (interfacePrivate
->path
!= NULL
) {
339 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
341 if (interfacePrivate
->entryID
!= 0) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
344 if (interfacePrivate
->type
!= NULL
) {
345 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
347 if (interfacePrivate
->unit
!= NULL
) {
348 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
350 if (interfacePrivate
->family
!= NULL
) {
351 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
353 if (interfacePrivate
->subfamily
!= NULL
) {
354 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
356 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
360 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
361 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
364 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
365 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
369 if (interfacePrivate
->usb
.name
!= NULL
) {
370 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
371 interfacePrivate
->usb
.name
);
374 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
378 if (interfacePrivate
->configurationAction
!= NULL
) {
379 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
381 if (interfacePrivate
->overrides
!= NULL
) {
382 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
384 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
385 if (interfacePrivate
->prefs
!= NULL
) {
386 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
388 if (interfacePrivate
->serviceID
!= NULL
) {
389 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
391 if (interfacePrivate
->interface
!= NULL
) {
392 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
394 if (interfacePrivate
->unsaved
!= NULL
) {
395 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
398 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
402 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
403 for (i
= 0; i
< n
; i
++) {
404 SCNetworkInterfaceRef member
;
406 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
407 CFStringAppendFormat(result
, NULL
,
409 (i
== 0) ? ", interfaces = " : ",",
410 SCNetworkInterfaceGetBSDName(member
));
413 if (interfacePrivate
->bond
.mode
!= NULL
) {
414 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
416 if (interfacePrivate
->bond
.options
!= NULL
) {
419 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
420 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
424 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
428 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
429 for (i
= 0; i
< n
; i
++) {
430 SCNetworkInterfaceRef member
;
432 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
433 CFStringAppendFormat(result
, NULL
,
435 (i
== 0) ? ", interfaces = " : ",",
436 SCNetworkInterfaceGetBSDName(member
));
439 if (interfacePrivate
->bridge
.options
!= NULL
) {
442 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
443 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
447 if (interfacePrivate
->vlan
.interface
!= NULL
) {
448 CFStringAppendFormat(result
, NULL
,
449 CFSTR(", interface = %@"),
450 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
452 if (interfacePrivate
->vlan
.tag
!= NULL
) {
453 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
455 if (interfacePrivate
->vlan
.options
!= NULL
) {
458 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
459 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
463 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
470 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
472 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
474 /* release resources */
476 if (interfacePrivate
->name
!= NULL
)
477 CFRelease(interfacePrivate
->name
);
479 if (interfacePrivate
->localized_name
!= NULL
)
480 CFRelease(interfacePrivate
->localized_name
);
482 if (interfacePrivate
->localized_arg1
!= NULL
)
483 CFRelease(interfacePrivate
->localized_arg1
);
485 if (interfacePrivate
->localized_arg2
!= NULL
)
486 CFRelease(interfacePrivate
->localized_arg2
);
488 if (interfacePrivate
->interface
!= NULL
)
489 CFRelease(interfacePrivate
->interface
);
491 if (interfacePrivate
->prefs
!= NULL
)
492 CFRelease(interfacePrivate
->prefs
);
494 if (interfacePrivate
->store
!= NULL
)
495 CFRelease(interfacePrivate
->store
);
497 if (interfacePrivate
->serviceID
!= NULL
)
498 CFRelease(interfacePrivate
->serviceID
);
500 if (interfacePrivate
->unsaved
!= NULL
)
501 CFRelease(interfacePrivate
->unsaved
);
503 if (interfacePrivate
->entity_device
!= NULL
)
504 CFRelease(interfacePrivate
->entity_device
);
506 if (interfacePrivate
->entity_device_unique
!= NULL
)
507 CFRelease(interfacePrivate
->entity_device_unique
);
509 if (interfacePrivate
->supported_interface_types
!= NULL
)
510 CFRelease(interfacePrivate
->supported_interface_types
);
512 if (interfacePrivate
->supported_protocol_types
!= NULL
)
513 CFRelease(interfacePrivate
->supported_protocol_types
);
515 if (interfacePrivate
->address
!= NULL
)
516 CFRelease(interfacePrivate
->address
);
518 if (interfacePrivate
->addressString
!= NULL
)
519 CFRelease(interfacePrivate
->addressString
);
521 if (interfacePrivate
->configurationAction
!= NULL
)
522 CFRelease(interfacePrivate
->configurationAction
);
524 if (interfacePrivate
->location
!= NULL
)
525 CFRelease(interfacePrivate
->location
);
527 if (interfacePrivate
->path
!= NULL
)
528 CFRelease(interfacePrivate
->path
);
530 if (interfacePrivate
->overrides
!= NULL
)
531 CFRelease(interfacePrivate
->overrides
);
533 if (interfacePrivate
->prefix
!= NULL
)
534 CFRelease(interfacePrivate
->prefix
);
536 if (interfacePrivate
->type
!= NULL
)
537 CFRelease(interfacePrivate
->type
);
539 if (interfacePrivate
->unit
!= NULL
)
540 CFRelease(interfacePrivate
->unit
);
542 if (interfacePrivate
->family
!= NULL
)
543 CFRelease(interfacePrivate
->family
);
545 if (interfacePrivate
->subfamily
!= NULL
)
546 CFRelease(interfacePrivate
->subfamily
);
548 if (interfacePrivate
->usb
.name
!= NULL
)
549 CFRelease(interfacePrivate
->usb
.name
);
551 if (interfacePrivate
->usb
.pid
!= NULL
)
552 CFRelease(interfacePrivate
->usb
.pid
);
554 if (interfacePrivate
->usb
.vid
!= NULL
)
555 CFRelease(interfacePrivate
->usb
.vid
);
557 if (interfacePrivate
->bond
.interfaces
!= NULL
)
558 CFRelease(interfacePrivate
->bond
.interfaces
);
560 if (interfacePrivate
->bond
.mode
!= NULL
)
561 CFRelease(interfacePrivate
->bond
.mode
);
563 if (interfacePrivate
->bond
.options
!= NULL
)
564 CFRelease(interfacePrivate
->bond
.options
);
566 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
567 CFRelease(interfacePrivate
->bridge
.interfaces
);
569 if (interfacePrivate
->bridge
.options
!= NULL
)
570 CFRelease(interfacePrivate
->bridge
.options
);
572 if (interfacePrivate
->vlan
.interface
!= NULL
)
573 CFRelease(interfacePrivate
->vlan
.interface
);
575 if (interfacePrivate
->vlan
.tag
!= NULL
)
576 CFRelease(interfacePrivate
->vlan
.tag
);
578 if (interfacePrivate
->vlan
.options
!= NULL
)
579 CFRelease(interfacePrivate
->vlan
.options
);
580 #if !TARGET_OS_SIMULATOR
581 if (interfacePrivate
->IPMonitorControl
!= NULL
)
582 CFRelease(interfacePrivate
->IPMonitorControl
);
583 #endif // !TARGET_OS_SIMULATOR
589 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
591 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
592 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
597 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
598 return FALSE
; // if not the same interface type
601 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
602 return FALSE
; // if not the same device
605 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
606 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
607 return FALSE
; // if not the same device unique identifier
609 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
613 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
614 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
615 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
616 return FALSE
; // if same device but not the same display name
620 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
621 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
622 return FALSE
; // if not the same interfaces
624 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
625 return FALSE
; // if not the same mode
629 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
630 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
631 return FALSE
; // if not the same interfaces
635 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
636 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
637 return FALSE
; // if not the same physical interface
639 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
640 return FALSE
; // if not the same tag
644 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
645 return FALSE
; // if not the same layering
653 __SCNetworkInterfaceHash(CFTypeRef cf
)
656 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
658 if (interfacePrivate
->entity_device
!= NULL
) {
659 if (interfacePrivate
->entity_device_unique
== NULL
) {
660 hash
= CFHash(interfacePrivate
->entity_device
);
664 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
665 interfacePrivate
->entity_device
,
666 interfacePrivate
->entity_device_unique
);
677 __SCNetworkInterfaceInitialize(void)
682 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
684 // initialize __kSCNetworkInterfaceIPv4
685 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
686 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
687 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
689 // initialize __kSCNetworkInterfaceLoopback
690 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
691 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
692 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
693 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
694 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
696 // get CFBundleRef for SystemConfiguration.framework
697 bundle
= _SC_CFBundleGet();
699 // get mach port used to communication with IOKit
700 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
701 if (kr
!= kIOReturnSuccess
) {
702 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
710 SCNetworkInterfacePrivateRef
711 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
712 SCNetworkInterfaceRef interface
,
713 SCPreferencesRef prefs
,
714 CFStringRef serviceID
)
716 SCNetworkInterfacePrivateRef interfacePrivate
;
719 /* initialize runtime */
720 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
722 /* allocate target */
723 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
724 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
725 __kSCNetworkInterfaceTypeID
,
728 if (interfacePrivate
== NULL
) {
732 /* initialize non-zero/NULL members */
733 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
734 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
735 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
736 interfacePrivate
->sort_order
= kSortUnknown
;
738 return interfacePrivate
;
744 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
748 struct if_msghdr
* ifm
;
749 char * if_name
= NULL
;
750 unsigned int if_index
;
752 Boolean vlanOK
= FALSE
;
754 // get the interface index
755 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
756 if (if_name
== NULL
) {
757 return FALSE
; // if conversion error
759 if_index
= if_nametoindex(if_name
);
761 goto done
; // if unknown interface
764 // get information for the specified interface
769 mib
[4] = NET_RT_IFLIST
;
770 mib
[5] = if_index
; /* ask for exactly one interface */
772 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
773 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
776 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
777 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
778 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
782 // check the link type and hwassist flags
783 // ALIGN: buf is aligned
784 ifm
= (struct if_msghdr
*)(void *)buf
;
785 switch (ifm
->ifm_type
) {
787 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
788 struct if_data
*if_data
= &ifm
->ifm_data
;
790 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
800 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
801 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
808 __SCCopyMacAddress(CFStringRef ifname
)
810 struct ifaddrs
*ifap
;
811 char ifname_c
[IFNAMSIZ
];
813 CFDataRef macAddress
= NULL
;
815 if(_SC_cfstring_to_cstring(ifname
,
818 kCFStringEncodingUTF8
) == NULL
) {
822 if (getifaddrs(&ifap
) == -1) {
824 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
828 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
829 struct sockaddr_dl
*sdl
;
831 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
835 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
836 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
837 if (sdl
->sdl_family
!= AF_LINK
) {
841 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
850 SCNetworkInterfacePrivateRef
851 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
854 SCNetworkInterfacePrivateRef interfacePrivate
;
856 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
857 if (interfacePrivate
== NULL
) {
861 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
862 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
863 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
864 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
865 interfacePrivate
->builtin
= TRUE
;
866 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
867 interfacePrivate
->sort_order
= kSortBond
;
869 interfacePrivate
->localized_key
= CFSTR("bond");
870 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
872 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
873 // interfacePrivate->bond.mode = NULL;
874 // interfacePrivate->bond.options = NULL;
876 return interfacePrivate
;
881 SCNetworkInterfacePrivateRef
882 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
883 CFStringRef bridge_if
)
885 SCNetworkInterfacePrivateRef interfacePrivate
;
887 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
888 if (interfacePrivate
== NULL
) {
892 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
893 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
894 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
895 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
896 interfacePrivate
->builtin
= TRUE
;
897 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
898 interfacePrivate
->sort_order
= kSortBridge
;
900 interfacePrivate
->localized_key
= CFSTR("bridge");
901 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
903 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
904 // interfacePrivate->bridge.options = NULL;
906 return interfacePrivate
;
911 SCNetworkInterfacePrivateRef
912 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
915 SCNetworkInterfacePrivateRef interfacePrivate
;
917 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
918 if (interfacePrivate
== NULL
) {
922 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
923 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
924 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
925 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
926 interfacePrivate
->builtin
= TRUE
;
927 interfacePrivate
->sort_order
= kSortVLAN
;
929 interfacePrivate
->localized_key
= CFSTR("vlan");
930 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
932 // interfacePrivate->vlan.interface = NULL;
933 // interfacePrivate->vlan.tag = NULL;
934 // interfacePrivate->vlan.options = NULL;
936 return interfacePrivate
;
941 #pragma mark Interface ordering
944 static CF_RETURNS_RETAINED CFArrayRef
945 split_path(CFStringRef path
)
947 CFArrayRef components
;
948 CFMutableStringRef nPath
;
950 // turn '@'s into '/'s
951 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
952 (void) CFStringFindAndReplace(nPath
,
955 CFRangeMake(0, CFStringGetLength(nPath
)),
958 // split path into components to be compared
959 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
967 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
969 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
970 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
971 CFComparisonResult res
= kCFCompareEqualTo
;
973 /* sort by interface type */
974 if (dev1
->sort_order
!= dev2
->sort_order
) {
975 if (dev1
->sort_order
< dev2
->sort_order
) {
976 res
= kCFCompareLessThan
;
978 res
= kCFCompareGreaterThan
;
983 /* built-in interfaces sort first */
984 if (dev1
->builtin
!= dev2
->builtin
) {
986 res
= kCFCompareLessThan
;
988 res
= kCFCompareGreaterThan
;
993 /* ... and then, sort built-in interfaces by "location" */
995 if (dev1
->location
!= dev2
->location
) {
996 if (isA_CFString(dev1
->location
)) {
997 if (isA_CFString(dev2
->location
)) {
998 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1000 res
= kCFCompareLessThan
;
1003 res
= kCFCompareGreaterThan
;
1006 if (res
!= kCFCompareEqualTo
) {
1012 /* ... and, then sort by IOPathMatch */
1013 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1014 CFArrayRef elements1
;
1015 CFArrayRef elements2
;
1021 elements1
= split_path(dev1
->path
);
1022 n1
= CFArrayGetCount(elements1
);
1024 elements2
= split_path(dev2
->path
);
1025 n2
= CFArrayGetCount(elements2
);
1027 n
= (n1
<= n2
) ? n1
: n2
;
1028 for (i
= 0; i
< n
; i
++) {
1037 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1038 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1040 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1042 q1
= strtoq(str
, &end
, 16);
1043 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1044 CFAllocatorDeallocate(NULL
, str
);
1047 // if e1 is a valid numeric string
1048 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1050 q2
= strtoq(str
, &end
, 16);
1051 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1052 CFAllocatorDeallocate(NULL
, str
);
1055 // if e2 is also a valid numeric string
1058 res
= kCFCompareEqualTo
;
1060 } else if (q1
< q2
) {
1061 res
= kCFCompareLessThan
;
1063 res
= kCFCompareGreaterThan
;
1069 res
= CFStringCompare(e1
, e2
, 0);
1070 if (res
!= kCFCompareEqualTo
) {
1075 if (res
== kCFCompareEqualTo
) {
1077 res
= kCFCompareLessThan
;
1078 } else if (n1
< n2
) {
1079 res
= kCFCompareGreaterThan
;
1083 CFRelease(elements1
);
1084 CFRelease(elements2
);
1086 if (res
!= kCFCompareEqualTo
) {
1091 /* ... and, then sort by BSD interface name */
1092 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1093 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1094 if (res
!= kCFCompareEqualTo
) {
1099 /* ... and lastly, sort by BSD interface unique identifier */
1100 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1101 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1102 // if (res != kCFCompareEqualTo) {
1112 sort_interfaces(CFMutableArrayRef all_interfaces
)
1116 n
= CFArrayGetCount(all_interfaces
);
1121 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1128 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1130 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1132 return interfacePrivate
->sort_order
;
1137 #pragma mark Interface details
1141 IOCopyCFStringValue(CFTypeRef ioVal
)
1143 if (isA_CFString(ioVal
)) {
1144 return CFStringCreateCopy(NULL
, ioVal
);
1147 if (isA_CFData(ioVal
)) {
1148 return CFStringCreateWithCString(NULL
,
1149 (const char *)CFDataGetBytePtr(ioVal
),
1150 kCFStringEncodingUTF8
);
1158 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1160 CFStringRef if_bsdName
;
1161 CFStringRef if_prefix
;
1162 CFNumberRef if_unit
;
1164 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1165 if (if_bsdName
!= NULL
) {
1166 return IOCopyCFStringValue(if_bsdName
);
1169 // no BSD name, get interface prefix and unit
1170 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1171 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1172 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1173 // if both prefix and unit available, construct BSD name
1174 if_bsdName
= CFStringCreateWithFormat(NULL
,
1186 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1190 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1191 return IOCopyCFStringValue(ioVal
);
1196 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1198 Boolean match
= FALSE
;
1199 CFIndex prefixLen
= CFStringGetLength(prefix
);
1200 CFStringRef str
= NULL
;
1202 if (!isA_CFString(ioVal
)) {
1203 if (isA_CFData(ioVal
)) {
1204 str
= CFStringCreateWithCStringNoCopy(NULL
,
1205 (const char *)CFDataGetBytePtr(ioVal
),
1206 kCFStringEncodingUTF8
,
1214 if ((ioVal
!= NULL
) &&
1215 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1216 (CFStringCompareWithOptions(ioVal
,
1218 CFRangeMake(0, prefixLen
),
1219 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1223 if (str
!= NULL
) CFRelease(str
);
1228 static const struct {
1229 const CFStringRef name
;
1230 const CFStringRef slot
;
1231 } slot_mappings
[] = {
1233 { CFSTR("A1") , CFSTR("1") },
1234 { CFSTR("B1") , CFSTR("2") },
1235 { CFSTR("C1") , CFSTR("3") },
1237 // Blue&White G3, Yikes G4
1238 { CFSTR("J12"), CFSTR("1") },
1239 { CFSTR("J11"), CFSTR("2") },
1240 { CFSTR("J10"), CFSTR("3") },
1241 { CFSTR("J9"), CFSTR("4") },
1244 { CFSTR("A") , CFSTR("1") },
1245 { CFSTR("B") , CFSTR("2") },
1246 { CFSTR("C") , CFSTR("3") },
1247 { CFSTR("D") , CFSTR("4") },
1249 // Digital Audio G4 (and later models)
1250 { CFSTR("1") , CFSTR("1") },
1251 { CFSTR("2") , CFSTR("2") },
1252 { CFSTR("3") , CFSTR("3") },
1253 { CFSTR("4") , CFSTR("4") },
1254 { CFSTR("5") , CFSTR("5") }
1258 static const CFStringRef slot_prefixes
[] = {
1259 CFSTR("thunderbolt slot "),
1265 static CF_RETURNS_RETAINED CFStringRef
1266 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1269 io_registry_entry_t parent
;
1270 CFMutableStringRef slot
;
1271 CFTypeRef slot_name
;
1274 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1276 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1277 if (slot_name
!= NULL
) {
1280 slot
= CFStringCreateMutable(NULL
, 0);
1281 if (isA_CFString(slot_name
)) {
1282 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1283 CFStringAppend(slot
, slot_name
);
1284 } else if (isA_CFData(slot_name
)) {
1285 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1286 CFStringAppendCString(slot
,
1287 (const char *)CFDataGetBytePtr(slot_name
),
1288 kCFStringEncodingUTF8
);
1291 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1294 len
= CFStringGetLength(slot_prefixes
[i
]);
1295 if (CFStringGetLength(slot
) > len
) {
1296 (void) CFStringFindAndReplace(slot
,
1299 CFRangeMake(0, len
),
1300 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1304 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1305 if (CFStringCompare(slot
,
1306 slot_mappings
[i
].name
,
1307 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1309 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1314 CFRelease(slot_name
);
1317 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1319 case kIOReturnSuccess
: {
1320 CFTypeRef parent_pci_slot_name
= NULL
;
1321 CFStringRef parent_slot
;
1323 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1324 if (parent_slot
!= NULL
) {
1325 if (slot
!= NULL
) CFRelease(slot
);
1326 slot
= (CFMutableStringRef
)parent_slot
;
1328 if (pci_slot_name
!= NULL
) {
1329 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1330 *pci_slot_name
= parent_pci_slot_name
;
1332 CFRelease(parent_pci_slot_name
);
1336 IOObjectRelease(parent
);
1339 case kIOReturnNoDevice
:
1340 // if we have hit the root node
1343 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1351 static CFComparisonResult
1352 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1354 CFStringRef bsd1
= (CFStringRef
)val1
;
1355 CFStringRef bsd2
= (CFStringRef
)val2
;
1357 return CFStringCompare(bsd1
, bsd2
, 0);
1361 static CF_RETURNS_RETAINED CFStringRef
1362 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1365 CFStringRef port_name
= NULL
;
1366 CFMutableArrayRef port_names
;
1369 CFStringRef match_keys
[2];
1370 CFTypeRef match_vals
[2];
1371 CFDictionaryRef match_dict
;
1372 CFDictionaryRef matching
;
1373 io_registry_entry_t slot
;
1374 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1376 match_keys
[0] = CFSTR("AAPL,slot-name");
1377 match_vals
[0] = slot_name
;
1379 match_dict
= CFDictionaryCreate(NULL
,
1380 (const void **)match_keys
,
1381 (const void **)match_vals
,
1383 &kCFTypeDictionaryKeyCallBacks
,
1384 &kCFTypeDictionaryValueCallBacks
);
1386 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1387 match_vals
[0] = CFSTR("IOPCIDevice");
1389 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1390 match_vals
[1] = match_dict
;
1392 // note: the "matching" dictionary will be consumed by the following
1393 matching
= CFDictionaryCreate(NULL
,
1394 (const void **)match_keys
,
1395 (const void **)match_vals
,
1396 sizeof(match_keys
)/sizeof(match_keys
[0]),
1397 &kCFTypeDictionaryKeyCallBacks
,
1398 &kCFTypeDictionaryValueCallBacks
);
1399 CFRelease(match_dict
);
1401 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1402 if (kr
!= kIOReturnSuccess
) {
1403 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1404 return MACH_PORT_NULL
;
1407 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1409 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1410 io_registry_entry_t child
;
1411 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1413 kr
= IORegistryEntryCreateIterator(slot
,
1415 kIORegistryIterateRecursively
,
1417 if (kr
!= kIOReturnSuccess
) {
1418 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1419 CFRelease(port_names
);
1420 return MACH_PORT_NULL
;
1423 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1424 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1425 CFMutableDictionaryRef interface_dict
= NULL
;
1427 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1428 if (interface_dict
!= NULL
) {
1429 CFNumberRef child_if_type
;
1430 int child_ift
= ift
;
1432 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1433 if (child_if_type
!= NULL
) {
1434 if (!isA_CFNumber(child_if_type
) ||
1435 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1436 // assume that it's a match
1441 if (ift
== child_ift
) {
1442 CFStringRef if_bsdName
;
1444 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1445 if (if_bsdName
!= NULL
) {
1446 CFArrayAppendValue(port_names
, if_bsdName
);
1447 CFRelease(if_bsdName
);
1451 CFRelease(interface_dict
);
1454 IOObjectRelease(child
);
1456 IOObjectRelease(child_iterator
);
1457 IOObjectRelease(slot
);
1459 IOObjectRelease(slot_iterator
);
1461 n
= CFArrayGetCount(port_names
);
1463 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1464 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1465 if (n
!= kCFNotFound
) {
1466 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1470 CFRelease(port_names
);
1476 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1478 CFStringRef bsd_name
= NULL
;
1479 CFMutableDictionaryRef interface_dict
= NULL
;
1481 CFTypeRef pci_slot_name
;
1486 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1487 if (interface_dict
!= NULL
) {
1488 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1489 CFRelease(interface_dict
);
1492 if (bsd_name
== NULL
) {
1496 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1497 if (*slot_name
!= NULL
) {
1498 if (pci_slot_name
!= NULL
) {
1499 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1500 CFRelease(pci_slot_name
);
1505 CFRelease(bsd_name
);
1511 isBuiltin(io_registry_entry_t interface
)
1515 slot
= pci_slot(interface
, NULL
);
1517 // interfaces which have a "slot" are not built-in
1527 isBluetoothBuiltin(Boolean
*haveController
)
1529 Boolean builtin
= FALSE
;
1530 io_object_t hciController
;
1531 io_iterator_t iter
= MACH_PORT_NULL
;
1534 kr
= IOServiceGetMatchingServices(masterPort
,
1535 IOServiceMatching("IOBluetoothHCIController"),
1537 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1538 if (kr
!= kIOReturnSuccess
) {
1539 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1541 *haveController
= FALSE
;
1544 *haveController
= TRUE
;
1546 hciController
= IOIteratorNext(iter
);
1547 IOObjectRelease(iter
);
1548 if(hciController
!= MACH_PORT_NULL
) {
1549 #if !TARGET_OS_SIMULATOR
1550 CFNumberRef idVendor
;
1552 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1553 if (idVendor
!= NULL
) {
1556 if (isA_CFNumber(idVendor
) &&
1557 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1558 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1562 CFRelease(idVendor
);
1564 #endif // !TARGET_OS_SIMULATOR
1566 IOObjectRelease(hciController
);
1574 isThunderbolt(io_registry_entry_t interface
)
1578 val
= IORegistryEntrySearchCFProperty(interface
,
1580 CFSTR(kPCIThunderboltString
),
1582 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1593 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1594 io_registry_entry_t interface
,
1595 CFDictionaryRef interface_dict
,
1596 io_registry_entry_t controller
,
1597 CFDictionaryRef controller_dict
,
1598 io_registry_entry_t bus
,
1599 CFDictionaryRef bus_dict
)
1601 #if !TARGET_OS_SIMULATOR
1603 if (interfacePrivate
->usb
.name
== NULL
) {
1604 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1606 CFSTR(kUSBProductString
),
1608 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1610 if (interfacePrivate
->usb
.vid
== NULL
) {
1611 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1613 CFSTR(kUSBVendorID
),
1615 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1617 if (interfacePrivate
->usb
.pid
== NULL
) {
1618 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1620 CFSTR(kUSBProductID
),
1622 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1624 #endif // !TARGET_OS_SIMULATOR
1631 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1632 io_registry_entry_t interface
,
1635 Boolean updated
= FALSE
;
1638 // check if a "Product Name" has been provided
1639 val
= IORegistryEntrySearchCFProperty(interface
,
1641 CFSTR(kIOPropertyProductNameKey
),
1643 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1644 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1645 // else, use "USB Product Name" if available
1646 val
= CFRetain(interfacePrivate
->usb
.name
);
1649 CFStringRef productName
;
1651 productName
= IOCopyCFStringValue(val
);
1654 if (productName
!= NULL
) {
1655 if (CFStringGetLength(productName
) > 0) {
1656 // if we have a [somewhat reasonable?] product name
1657 if (interfacePrivate
->name
!= NULL
) {
1658 CFRelease(interfacePrivate
->name
);
1660 interfacePrivate
->name
= CFRetain(productName
);
1661 if (interfacePrivate
->localized_name
!= NULL
) {
1662 CFRelease(interfacePrivate
->localized_name
);
1663 interfacePrivate
->localized_name
= NULL
;
1665 if (bundle
!= NULL
) {
1666 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1672 CFRelease(productName
);
1681 #pragma mark Interface enumeration
1684 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1685 io_registry_entry_t interface
,
1686 CFDictionaryRef interface_dict
,
1687 io_registry_entry_t controller
,
1688 CFDictionaryRef controller_dict
,
1689 io_registry_entry_t bus
,
1690 CFDictionaryRef bus_dict
);
1694 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1695 io_registry_entry_t interface
,
1696 CFStringRef override
)
1701 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1702 val
= IORegistryEntrySearchCFProperty(interface
,
1706 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1709 if (isA_CFDictionary(val
)) {
1710 if (interfacePrivate
->overrides
== NULL
) {
1711 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1713 &kCFTypeDictionaryKeyCallBacks
,
1714 &kCFTypeDictionaryValueCallBacks
);
1716 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1726 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1727 io_registry_entry_t interface
,
1728 CFDictionaryRef interface_dict
,
1729 io_registry_entry_t controller
,
1730 CFDictionaryRef controller_dict
,
1731 io_registry_entry_t bus
,
1732 CFDictionaryRef bus_dict
)
1742 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1743 if (isA_CFNumber(num
) &&
1744 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1745 interfacePrivate
->type
= CFRetain(num
);
1747 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1755 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1756 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1757 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1758 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1759 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1760 interfacePrivate
->sort_order
= kSortAirPort
;
1761 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1762 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1763 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1764 interfacePrivate
->sort_order
= kSortThunderbolt
;
1765 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1766 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1767 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1768 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1769 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1770 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1771 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1772 interfacePrivate
->sort_order
= kSortTethered
;
1773 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1774 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1775 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1776 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1779 if (interfacePrivate
->interface_type
== NULL
) {
1780 val
= IORegistryEntrySearchCFProperty(interface
,
1782 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1784 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1786 if (isA_CFString(val
)) {
1787 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1788 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1789 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1790 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1791 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1792 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1793 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1794 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1795 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1796 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1797 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1798 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1806 if (interfacePrivate
->interface_type
== NULL
) {
1807 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1809 if (CFEqual(str
, CFSTR("radio"))) {
1810 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1811 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1812 interfacePrivate
->sort_order
= kSortOtherWireless
;
1819 if (interfacePrivate
->interface_type
== NULL
) {
1820 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1821 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1822 interfacePrivate
->sort_order
= kSortEthernet
;
1824 // BOND support only enabled for ethernet devices
1825 interfacePrivate
->supportsBond
= TRUE
;
1828 // enable Bridge support
1829 interfacePrivate
->supportsBridge
= TRUE
;
1832 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1834 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1837 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1839 interfacePrivate
->builtin
= isBuiltin(interface
);
1842 if (!interfacePrivate
->builtin
&&
1843 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1844 // always treat AirPort interfaces as built-in
1845 interfacePrivate
->builtin
= TRUE
;
1849 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1850 if ((interfacePrivate
->location
!= NULL
) &&
1851 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1852 CFRelease(interfacePrivate
->location
);
1853 interfacePrivate
->location
= NULL
;
1857 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1858 if (isA_CFNumber(num
) &&
1859 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1860 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1861 interfacePrivate
->supportsVLAN
= TRUE
;
1866 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1867 interfacePrivate
->localized_key
= CFSTR("airport");
1868 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1869 if ((interfacePrivate
->location
== NULL
) ||
1870 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1871 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1873 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1874 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1876 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1877 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1878 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1879 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1880 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1881 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1882 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1883 interfacePrivate
->localized_key
= CFSTR("wireless");
1884 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1885 } else if (interfacePrivate
->builtin
) {
1886 if ((interfacePrivate
->location
== NULL
) ||
1887 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1888 interfacePrivate
->localized_key
= CFSTR("ether");
1890 interfacePrivate
->localized_key
= CFSTR("multiether");
1891 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1894 CFStringRef provider
;
1896 // check provider class
1897 provider
= IORegistryEntrySearchCFProperty(interface
,
1899 CFSTR(kIOProviderClassKey
),
1901 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1902 if (provider
!= NULL
) {
1903 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1904 CFStringRef port_name
;
1905 CFStringRef slot_name
;
1907 // set interface "name"
1908 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1909 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1910 if (isThunderbolt(interface
)) {
1911 if (port_name
== NULL
) {
1912 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1913 interfacePrivate
->localized_arg1
= slot_name
;
1915 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1916 interfacePrivate
->localized_arg1
= slot_name
;
1917 interfacePrivate
->localized_arg2
= port_name
;
1921 if (port_name
== NULL
) {
1922 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1923 interfacePrivate
->localized_arg1
= slot_name
;
1925 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1926 interfacePrivate
->localized_arg1
= slot_name
;
1927 interfacePrivate
->localized_arg2
= port_name
;
1932 io_registry_entry_t node
= interface
;
1934 while (provider
!= NULL
) {
1935 #if !TARGET_OS_SIMULATOR
1936 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
1937 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
1938 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
))) {
1939 // get USB info (if available)
1940 processUSBInterface(interfacePrivate
,
1948 // set interface "name"
1949 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1950 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1951 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1955 #endif // !TARGET_OS_SIMULATOR
1957 if (node
== interface
) {
1959 } else if (node
== controller
) {
1965 CFRelease(provider
);
1966 provider
= IORegistryEntrySearchCFProperty(node
,
1968 CFSTR(kIOProviderClassKey
),
1970 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1973 if (interfacePrivate
->localized_key
== NULL
) {
1974 update_interface_name(interfacePrivate
, interface
, FALSE
);
1978 if (provider
!= NULL
) CFRelease(provider
);
1981 if (interfacePrivate
->localized_key
== NULL
) {
1982 // if no provider, not a PCI device, or no slot information
1983 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1984 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1991 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1994 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1997 interfacePrivate
->builtin
= isBuiltin(interface
);
2000 interfacePrivate
->sort_order
= kSortFireWire
;
2003 if (interfacePrivate
->builtin
) {
2004 interfacePrivate
->localized_key
= CFSTR("firewire");
2006 CFStringRef port_name
;
2007 CFStringRef slot_name
;
2009 // set interface "name"
2010 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2011 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2012 if (isThunderbolt(interface
)) {
2013 if (port_name
== NULL
) {
2014 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2015 interfacePrivate
->localized_arg1
= slot_name
;
2017 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2018 interfacePrivate
->localized_arg1
= slot_name
;
2019 interfacePrivate
->localized_arg2
= port_name
;
2022 if (port_name
== NULL
) {
2023 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2024 interfacePrivate
->localized_arg1
= slot_name
;
2026 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2027 interfacePrivate
->localized_arg1
= slot_name
;
2028 interfacePrivate
->localized_arg2
= port_name
;
2036 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2041 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2043 // Hardware (MAC) address
2044 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2045 if (isA_CFData(data
)) {
2046 interfacePrivate
->address
= CFRetain(data
);
2050 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2051 if (isA_CFString(str
)) {
2052 interfacePrivate
->prefix
= CFRetain(str
);
2056 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2057 if (isA_CFNumber(num
) &&
2058 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2059 interfacePrivate
->unit
= CFRetain(num
);
2062 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2063 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2070 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2072 CFDictionaryRef dict
;
2073 CFMutableDictionaryRef newDict
;
2075 if (interfacePrivate
->overrides
== NULL
) {
2076 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2078 &kCFTypeDictionaryKeyCallBacks
,
2079 &kCFTypeDictionaryValueCallBacks
);
2082 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2084 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2086 newDict
= CFDictionaryCreateMutable(NULL
,
2088 &kCFTypeDictionaryKeyCallBacks
,
2089 &kCFTypeDictionaryValueCallBacks
);
2091 if (script
!= NULL
) {
2092 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2094 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2096 if (CFDictionaryGetCount(newDict
) > 0) {
2097 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2099 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2103 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2104 CFRelease(interfacePrivate
->overrides
);
2105 interfacePrivate
->overrides
= NULL
;
2112 is_valid_connection_script(CFStringRef script
)
2114 char ccl
[MAXPATHLEN
];
2115 char path
[MAXPATHLEN
];
2116 sysdir_search_path_enumeration_state state
;
2118 (void) _SC_cfstring_to_cstring(script
,
2121 kCFStringEncodingUTF8
);
2123 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2124 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2125 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2127 struct stat statBuf
;
2129 if (ccl
[0] == '/') {
2130 path
[0] = '\0'; // if modemCCL is a full path
2132 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2134 strlcat(path
, ccl
, sizeof(path
));
2136 if (stat(path
, &statBuf
) != 0) {
2137 if (errno
== ENOENT
) {
2141 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2144 if (S_ISREG(statBuf
.st_mode
)) {
2145 // if we have a valid CCL script
2149 #define BUNDLE_EXT ".ccl"
2150 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2155 if ((n
<= BUNDLE_EXT_LEN
) ||
2156 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2157 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2158 if (stat(path
, &statBuf
) != 0) {
2159 if (errno
== ENOENT
) {
2163 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2167 if (S_ISDIR(statBuf
.st_mode
)) {
2168 // if we have a valid CCL bundle
2178 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2179 io_registry_entry_t interface
,
2180 CFDictionaryRef interface_dict
,
2181 io_registry_entry_t controller
,
2182 CFDictionaryRef controller_dict
,
2183 io_registry_entry_t bus
,
2184 CFDictionaryRef bus_dict
)
2186 CFStringRef base
= NULL
;
2188 Boolean isModem
= FALSE
;
2189 Boolean isWWAN
= FALSE
;
2190 CFStringRef modemCCL
= NULL
;
2194 // check if initializing
2195 val
= IORegistryEntrySearchCFProperty(interface
,
2197 kSCNetworkInterfaceInitializingKey
,
2199 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2201 Boolean initializing
;
2203 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2206 return FALSE
; // if this interface is still initializing
2211 val
= IORegistryEntrySearchCFProperty(interface
,
2215 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2217 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2222 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2223 if (interfacePrivate
->entity_device
== NULL
) {
2227 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2229 base
= CFRetain(interfacePrivate
->entity_device
);
2235 * Exclude ports named "irda" because otherwise the IrDA ports on the
2236 * original iMac (rev's A through D) show up as serial ports. Given
2237 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2238 * even support it, these ports definitely shouldn't be listed.
2240 if (CFStringCompare(base
,
2242 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2246 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2247 Boolean haveController
= FALSE
;
2250 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2251 interfacePrivate
->sort_order
= kSortBluetooth
;
2252 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2253 if (!haveController
) {
2254 // if device with no controller present
2257 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2259 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2260 interfacePrivate
->sort_order
= kSortIrDA
;
2261 } else if (isWWAN
) {
2263 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2264 interfacePrivate
->sort_order
= kSortWWAN
;
2267 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2268 interfacePrivate
->sort_order
= kSortModem
;
2271 val
= IORegistryEntrySearchCFProperty(interface
,
2273 CFSTR(kIODeviceSupportsHoldKey
),
2275 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2279 if (isA_CFNumber(val
) &&
2280 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2281 interfacePrivate
->modemIsV92
= (v92
== 1);
2288 interfacePrivate
->entity_type
= kSCEntNetModem
;
2290 // Entity (Hardware)
2291 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2292 if (!isA_CFString(ift
)) {
2296 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2300 if (CFEqual(base
, CFSTR("modem"))) {
2301 interfacePrivate
->builtin
= TRUE
;
2302 interfacePrivate
->sort_order
= kSortInternalModem
;
2303 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2304 interfacePrivate
->sort_order
= kSortUSBModem
;
2306 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2308 interfacePrivate
->sort_order
= kSortSerialPort
;
2313 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2314 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2316 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2317 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2319 // look for modem CCL, unique identifier
2320 if (interfacePrivate
->overrides
!= NULL
) {
2321 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2323 CFStringRef uniqueID
;
2325 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2326 modemCCL
= isA_CFString(modemCCL
);
2328 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2329 uniqueID
= isA_CFString(uniqueID
);
2330 if (uniqueID
!= NULL
) {
2331 // retain the device's base name and the unique id
2332 CFRelease(interfacePrivate
->entity_device
);
2333 interfacePrivate
->entity_device
= CFRetain(base
);
2334 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2339 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2340 // a bit harder for the modem CCL
2341 if (modemCCL
== NULL
) {
2342 val
= IORegistryEntrySearchCFProperty(interface
,
2346 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2348 modemCCL
= IOCopyCFStringValue(val
);
2349 if (modemCCL
!= NULL
) {
2350 set_connection_script(interfacePrivate
, modemCCL
);
2351 CFRelease(modemCCL
);
2359 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2360 interfacePrivate
->localized_key
= CFSTR("irda");
2361 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2362 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2364 CFStringRef localized
= NULL
;
2365 CFStringRef name
= NULL
;
2366 CFMutableStringRef port
;
2368 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2369 CFStringLowercase(port
, NULL
);
2372 CFStringAppend(port
, CFSTR("-port"));
2375 // set non-localized name
2376 if (bundle
!= NULL
) {
2377 name
= copy_interface_string(bundle
, port
, FALSE
);
2380 if (!CFEqual(port
, name
)) {
2381 // if [English] localization available
2382 interfacePrivate
->name
= name
;
2384 // if no [English] localization available, use TTY base name
2386 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2389 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2392 // set localized name
2393 if (bundle
!= NULL
) {
2394 localized
= copy_interface_string(bundle
, port
, TRUE
);
2396 if (localized
!= NULL
) {
2397 if (!CFEqual(port
, localized
)) {
2398 // if localization available
2399 interfacePrivate
->localized_name
= localized
;
2401 // if no localization available, use TTY base name
2402 CFRelease(localized
);
2403 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2406 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2409 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2410 // get USB info (if available)
2411 processUSBInterface(interfacePrivate
,
2419 // set interface "name"
2420 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2421 // if "ModemCCL" not provided, also check if the product/interface
2422 // name matches a CCL script
2423 if ((modemCCL
== NULL
) &&
2424 is_valid_connection_script(interfacePrivate
->name
)) {
2425 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2437 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2438 CFRelease(interfacePrivate
->entity_device
);
2439 interfacePrivate
->entity_device
= NULL
;
2441 if (base
!= NULL
) CFRelease(base
);
2448 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2451 * Create a path for a registry entry.
2455 CFStringRef str
= NULL
;
2457 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2458 if (status
== kIOReturnSuccess
) {
2459 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2460 } else if (status
== kIOReturnBadArgument
) {
2461 io_registry_entry_t parent
;
2463 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2464 if (status
== kIOReturnSuccess
) {
2465 CFStringRef str_parent
;
2467 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2468 if (str_parent
!= NULL
) {
2471 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2472 if (status
== kIOReturnSuccess
) {
2475 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2476 if (status
== kIOReturnSuccess
) {
2477 str
= CFStringCreateWithFormat(NULL
,
2484 str
= CFStringCreateWithFormat(NULL
,
2492 CFRelease(str_parent
);
2495 IOObjectRelease(parent
);
2502 static CFMutableDictionaryRef
2503 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2506 CFMutableDictionaryRef reg_dict
= NULL
;
2507 CFTypeRef value
= NULL
;
2509 reg_dict
= CFDictionaryCreateMutable(NULL
,
2511 &kCFTypeDictionaryKeyCallBacks
,
2512 &kCFTypeDictionaryValueCallBacks
);
2514 for (; idx
< numKeys
; idx
++) {
2515 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2516 if (value
!= NULL
) {
2517 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2525 static SCNetworkInterfaceRef
2526 createInterface(io_registry_entry_t interface
, processInterface func
,
2527 CFStringRef hidden_key
)
2529 io_registry_entry_t bus
= MACH_PORT_NULL
;
2530 CFMutableDictionaryRef bus_dict
= NULL
;
2531 io_registry_entry_t controller
= MACH_PORT_NULL
;
2532 CFMutableDictionaryRef controller_dict
= NULL
;
2533 uint64_t entryID
= 0;
2534 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2535 CFMutableDictionaryRef interface_dict
= NULL
;
2540 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2542 const CFStringRef interface_dict_keys
[] = {
2543 CFSTR(kIOInterfaceType
),
2545 CFSTR(kIOBSDNameKey
),
2546 CFSTR(kIOPrimaryInterface
),
2547 CFSTR(kIOInterfaceNamePrefix
),
2548 CFSTR(kIOInterfaceUnit
),
2549 CFSTR(kIOTTYDeviceKey
),
2550 CFSTR(kIOTTYBaseNameKey
),
2551 CFSTR(kIOSerialBSDTypeKey
),
2554 #endif // !TARGET_OS_SIMULATOR
2556 const CFStringRef controller_dict_keys
[] = {
2558 CFSTR(kIOMACAddress
)
2561 const CFStringRef bus_dict_keys
[] = {
2565 if (hidden_key
!= NULL
) {
2567 val
= IORegistryEntrySearchCFProperty(interface
,
2571 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2574 goto done
; // if this interface should not be exposed
2578 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2579 // get the dictionary associated with the [interface] node
2580 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2581 if (kr
!= kIOReturnSuccess
) {
2582 SC_log(LOG_INFO
, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr
);
2586 interface_dict
= copyIORegistryProperties(interface
,
2587 interface_dict_keys
,
2588 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2589 #endif // !TARGET_OS_SIMULATOR
2591 // get the controller node
2592 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2593 if (kr
!= kIOReturnSuccess
) {
2594 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2598 controller_dict
= copyIORegistryProperties(controller
,
2599 controller_dict_keys
,
2600 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2603 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2604 if (kr
!= kIOReturnSuccess
) {
2605 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2609 bus_dict
= copyIORegistryProperties(bus
,
2611 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2613 // get the registry entry ID
2614 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2615 if (kr
!= kIOReturnSuccess
) {
2616 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2620 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2621 assert(interfacePrivate
!= NULL
);
2622 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2623 interfacePrivate
->entryID
= entryID
;
2625 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2626 val
= IORegistryEntrySearchCFProperty(interface
,
2628 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2630 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2632 if (isA_CFDictionary(val
)) {
2633 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2638 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2639 // get user-notification / auto-configuration preference
2640 val
= IORegistryEntrySearchCFProperty(interface
,
2642 kSCNetworkInterfaceConfigurationActionKey
,
2644 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2646 if (isA_CFString(val
)) {
2647 interfacePrivate
->configurationAction
= CFRetain(val
);
2652 // get HiddenConfiguration preference
2653 val
= IORegistryEntrySearchCFProperty(interface
,
2655 kSCNetworkInterfaceHiddenConfigurationKey
,
2657 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2659 interfacePrivate
->hidden
= TRUE
;
2663 CFRelease(interfacePrivate
);
2664 interfacePrivate
= NULL
;
2669 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2671 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2672 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2674 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2675 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2677 return (SCNetworkInterfaceRef
)interfacePrivate
;
2681 static CF_RETURNS_RETAINED CFArrayRef
2682 findMatchingInterfaces(CFDictionaryRef matching
,
2683 processInterface func
,
2684 CFStringRef hidden_key
,
2685 Boolean keep_pre_configured
)
2687 CFMutableArrayRef interfaces
;
2688 io_registry_entry_t interface
;
2690 io_iterator_t iterator
= MACH_PORT_NULL
;
2693 * A reference to the "matching" dictionary will be consumed by the
2694 * the call to IOServiceGetMatchingServices so we bump up the retain
2699 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2700 if (kr
!= kIOReturnSuccess
) {
2701 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2705 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2707 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2708 SCNetworkInterfaceRef match
;
2710 match
= createInterface(interface
, func
, hidden_key
);
2711 if (match
!= NULL
) {
2712 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2713 CFArrayAppendValue(interfaces
, match
);
2718 IOObjectRelease(interface
);
2721 IOObjectRelease(iterator
);
2728 #pragma mark helper functions
2732 findConfiguration(CFStringRef interface_type
)
2736 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2737 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2748 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2750 CFIndex interfaceIndex
;
2751 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2753 if (interfacePrivate
->serviceID
== NULL
) {
2754 // if not associated with a service (yet)
2755 _SCErrorSet(kSCStatusInvalidArgument
);
2759 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2760 if (interfaceIndex
== kCFNotFound
) {
2761 // unknown interface type, use per-service configuration preferences
2762 return interfacePrivate
->interface_type
; // entity
2765 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2766 // if configuration information can be associated with this interface type
2767 return *configurations
[interfaceIndex
].entity_hardware
;
2770 _SCErrorSet(kSCStatusInvalidArgument
);
2777 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2778 CFStringRef extendedType
,
2779 Boolean requirePerInterface
)
2781 CFStringRef defaultType
;
2782 CFIndex extendedIndex
;
2783 CFIndex interfaceIndex
;
2784 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2785 Boolean isL2TP
= FALSE
;
2788 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2789 if (defaultType
== NULL
) {
2793 if (CFEqual(extendedType
, defaultType
)) {
2794 // extended and default configuration types cannot conflict
2798 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2799 if (interfaceIndex
== kCFNotFound
) {
2800 // configuration information for unknown interface type's
2801 // are stored along with the service and we don't allow
2802 // per-service extended configurations
2806 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2807 CFStringRef interfaceType
;
2809 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2810 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2811 SCNetworkInterfaceRef child
;
2813 child
= SCNetworkInterfaceGetInterface(interface
);
2814 if (child
!= NULL
) {
2815 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2816 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2823 if (requirePerInterface
&&
2824 !configurations
[interfaceIndex
].per_interface_config
&&
2826 // we don't allow per-service extended configurations (except
2827 // that we do allow IPSec as an extended type for PPP->L2TP)
2831 extendedIndex
= findConfiguration(extendedType
);
2832 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2833 // extended type cannot match a known interface type (except
2834 // that we do allow IPSec as an extended type for PPP->L2TP)
2840 * Should we check/match and specifically allow known extended
2841 * configuration types (e.g. EAPOL)?
2843 * Should we check/match and specifically block known internal
2844 * configuration types (e.g. QoSMarking)?
2846 * Lastly, should we ensure that any non-standard extended configuration
2847 * types be of the form com.myCompany.myType?
2856 _SCErrorSet(kSCStatusInvalidArgument
);
2863 CFStringRef defaultType
;
2864 CFMutableArrayRef types
;
2865 } extendedConfiguration
, *extendedConfigurationRef
;
2869 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2871 CFStringRef extendedType
= (CFStringRef
)key
;
2872 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2874 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2875 // do not include the default configuration type
2879 if (CFArrayContainsValue(myContextRef
->types
,
2880 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2882 // if extendedType already has already been added
2886 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2893 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2895 CFIndex interfaceIndex
;
2896 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2898 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2899 if (interfaceIndex
== kCFNotFound
) {
2900 // if per-service (not per interface) configuration
2904 if (!configurations
[interfaceIndex
].per_interface_config
) {
2905 // if per-interface configuration not allowed
2909 return interfaceIndex
;
2913 static CF_RETURNS_RETAINED CFArrayRef
2914 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2917 CFIndex interfaceIndex
;
2918 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2919 extendedConfiguration myContext
;
2920 SCNetworkServiceRef service
;
2924 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2925 if (myContext
.defaultType
== NULL
) {
2926 myContext
.types
= NULL
;
2930 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2932 if (interfacePrivate
->serviceID
== NULL
) {
2933 // if not associated with a service (yet)
2937 interfaceIndex
= findPerInterfaceConfiguration(interface
);
2938 if (interfaceIndex
== kCFNotFound
) {
2939 // if no per-interface configuration
2943 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2944 interfacePrivate
->prefs
,
2945 interfacePrivate
->serviceID
,
2948 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2949 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2951 for (i
= 0; i
< n
; i
++) {
2952 CFDictionaryRef configs
;
2955 CFArrayRef services
;
2956 SCNetworkSetRef set
;
2958 set
= CFArrayGetValueAtIndex(sets
, i
);
2959 services
= SCNetworkSetCopyServices(set
);
2960 found
= CFArrayContainsValue(services
,
2961 CFRangeMake(0, CFArrayGetCount(services
)),
2963 CFRelease(services
);
2969 // add stored extended configuration types
2970 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2971 SCNetworkSetGetSetID(set
), // set
2972 interfacePrivate
->entity_device
, // service
2974 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2976 if (isA_CFDictionary(configs
)) {
2977 CFDictionaryApplyFunction(configs
,
2978 __addExtendedConfigurationType
,
2982 // add not-yet-stored extended configuration types
2983 if (interfacePrivate
->unsaved
!= NULL
) {
2984 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2985 __addExtendedConfigurationType
,
2993 if (sets
!= NULL
) CFRelease(sets
);
2997 return myContext
.types
;
3001 stringCreateArray(CFStringRef str
)
3003 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3007 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3008 CFStringRef extendedType
)
3010 CFMutableArrayRef array
= NULL
;
3014 SCNetworkServiceRef service
;
3017 // known interface type, per-interface configuration preferences
3019 // 1. look for all sets which contain the associated service
3020 // 2. add a per-set path for the interface configuration for
3023 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3024 interfacePrivate
->prefs
,
3025 interfacePrivate
->serviceID
,
3026 (SCNetworkInterfaceRef
)interfacePrivate
);
3028 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3029 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3031 for (i
= 0; i
< n
; i
++) {
3032 CFArrayRef services
;
3033 SCNetworkSetRef set
;
3035 set
= CFArrayGetValueAtIndex(sets
, i
);
3036 services
= SCNetworkSetCopyServices(set
);
3037 if (CFArrayContainsValue(services
,
3038 CFRangeMake(0, CFArrayGetCount(services
)),
3040 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3041 SCNetworkSetGetSetID(set
), // set
3042 interfacePrivate
->entity_device
, // service
3043 extendedType
); // entity
3044 if (array
== NULL
) {
3045 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3047 CFArrayAppendValue(array
, path
);
3050 CFRelease(services
);
3054 if (sets
!= NULL
) CFRelease(sets
);
3060 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3061 CFStringRef extendedType
)
3063 CFArrayRef array
= NULL
;
3064 CFIndex interfaceIndex
;
3067 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3068 if (interfaceIndex
== kCFNotFound
) {
3069 // unknown interface type, use per-service configuration preferences
3070 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3071 interfacePrivate
->serviceID
, // service
3072 extendedType
); // entity
3073 array
= stringCreateArray(path
);
3077 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3078 // known interface type, per-service configuration preferences
3079 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3080 interfacePrivate
->serviceID
, // service
3081 extendedType
); // entity
3082 array
= stringCreateArray(path
);
3086 else if (interfacePrivate
->serviceID
!= NULL
) {
3087 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3095 #pragma mark SCNetworkInterface <--> preferences entity
3100 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3102 CFMutableDictionaryRef entity
;
3103 CFIndex interfaceIndex
;
3104 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3106 entity
= CFDictionaryCreateMutable(NULL
,
3108 &kCFTypeDictionaryKeyCallBacks
,
3109 &kCFTypeDictionaryValueCallBacks
);
3110 if (interfacePrivate
->entity_type
!= NULL
) {
3111 CFDictionarySetValue(entity
,
3112 kSCPropNetInterfaceType
,
3113 interfacePrivate
->entity_type
);
3115 if (interfacePrivate
->entity_subtype
!= NULL
) {
3116 CFDictionarySetValue(entity
,
3117 kSCPropNetInterfaceSubType
,
3118 interfacePrivate
->entity_subtype
);
3120 if (interfacePrivate
->entity_device
!= NULL
) {
3121 CFDictionarySetValue(entity
,
3122 kSCPropNetInterfaceDeviceName
,
3123 interfacePrivate
->entity_device
);
3125 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3126 CFDictionarySetValue(entity
,
3127 CFSTR("DeviceUniqueIdentifier"),
3128 interfacePrivate
->entity_device_unique
);
3130 if (interfacePrivate
->hidden
) {
3131 CFDictionarySetValue(entity
,
3132 kSCNetworkInterfaceHiddenConfigurationKey
,
3136 // match the "hardware" with the lowest layer
3138 SCNetworkInterfaceRef nextInterface
;
3140 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3141 if (nextInterface
== NULL
) {
3145 interface
= nextInterface
;
3147 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3149 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3153 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3154 if (interfaceIndex
!= kCFNotFound
) {
3155 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3156 CFDictionarySetValue(entity
,
3157 kSCPropNetInterfaceHardware
,
3158 *configurations
[interfaceIndex
].entity_hardware
);
3161 CFDictionarySetValue(entity
,
3162 kSCPropNetInterfaceHardware
,
3163 interfacePrivate
->interface_type
);
3166 // add the localized display name (which will only be used when/if the
3167 // interface is removed from the system)
3168 CFDictionarySetValue(entity
,
3169 kSCPropUserDefinedName
,
3170 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3172 // note that this is a V.92 capable modem
3173 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
3174 interfacePrivate
->modemIsV92
) {
3178 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
3179 CFDictionarySetValue(entity
,
3180 kSCPropNetInterfaceSupportsModemOnHold
,
3189 static SCNetworkInterfaceRef
3190 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3195 n
= CFArrayGetCount(interfaces
);
3196 for (i
= 0; i
< n
; i
++) {
3197 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3198 CFStringRef interfaceName
;
3200 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3201 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3202 CFRetain(interface
);
3210 #if !TARGET_OS_IPHONE
3211 static SCNetworkInterfaceRef
3212 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3215 SCNetworkInterfaceRef interface
= NULL
;
3217 if (prefs
== NULL
) {
3221 // check if the interface is an Ethernet Bond
3222 bonds
= SCBondInterfaceCopyAll(prefs
);
3223 if (bonds
!= NULL
) {
3224 interface
= findInterface(bonds
, ifDevice
);
3229 #endif // !TARGET_OS_IPHONE
3231 static SCNetworkInterfaceRef
3232 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3235 SCNetworkInterfaceRef interface
= NULL
;
3237 if (prefs
== NULL
) {
3241 // check if the interface is an bridge
3242 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3243 if (bridges
!= NULL
) {
3244 interface
= findInterface(bridges
, ifDevice
);
3250 static SCNetworkInterfaceRef
3251 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3253 SCNetworkInterfaceRef interface
= NULL
;
3256 if (prefs
== NULL
) {
3260 // check if the interface is a VLAN
3261 vlans
= SCVLANInterfaceCopyAll(prefs
);
3262 if (vlans
!= NULL
) {
3263 interface
= findInterface(vlans
, ifDevice
);
3273 static CFMutableDictionaryRef
3274 copy_ppp_entity(CFStringRef bsdName
)
3276 CFMutableDictionaryRef entity
= NULL
;
3277 CFStringRef pattern
;
3278 CFMutableArrayRef patterns
;
3279 CFDictionaryRef dict
;
3281 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3282 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3283 CFArrayAppendValue(patterns
, pattern
);
3285 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3286 CFArrayAppendValue(patterns
, pattern
);
3288 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3289 CFRelease(patterns
);
3292 const void * keys_q
[N_QUICK
];
3293 const void ** keys
= keys_q
;
3295 const void * vals_q
[N_QUICK
];
3296 const void ** vals
= vals_q
;
3298 n
= CFDictionaryGetCount(dict
);
3299 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3300 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3301 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3303 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3304 for (i
= 0; i
< n
; i
++) {
3305 CFArrayRef components
;
3306 CFStringRef interfaceKey
;
3307 CFDictionaryRef interfaceVal
;
3309 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3310 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3311 CFStringRef serviceID
;
3313 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3314 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3315 !CFEqual(bsdName
, ifName
)) {
3316 // if not matching PPP interface
3320 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3321 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3322 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3323 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3324 CFRelease(interfaceKey
);
3325 CFRelease(components
);
3326 if (interfaceVal
!= NULL
) {
3327 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3331 if (keys
!= keys_q
) {
3332 CFAllocatorDeallocate(NULL
, keys
);
3333 CFAllocatorDeallocate(NULL
, vals
);
3343 SCNetworkInterfaceRef
3344 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3345 CFStringRef bsdName
,
3348 CFMutableDictionaryRef entity
= NULL
;
3350 SCNetworkInterfaceRef interface
;
3352 bzero(&ifr
, sizeof(ifr
));
3353 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3356 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3358 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3364 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3366 entity
= copy_ppp_entity(bsdName
);
3370 if (entity
== NULL
) {
3371 entity
= CFDictionaryCreateMutable(NULL
,
3373 &kCFTypeDictionaryKeyCallBacks
,
3374 &kCFTypeDictionaryValueCallBacks
);
3375 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3378 #if !TARGET_OS_IPHONE
3379 if ((flags
& kIncludeBondInterfaces
) == 0) {
3380 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3382 #endif // !TARGET_OS_IPHONE
3384 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3385 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3388 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3389 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3392 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3400 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3402 CFMutableStringRef interfacePrefix
= NULL
;
3406 if (isA_CFString(bsdName
) == NULL
) {
3407 SC_log(LOG_DEBUG
, "no BSD name");
3411 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3412 length
= CFStringGetLength(interfacePrefix
);
3414 while (length
> 0) {
3415 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3416 if (lastChar
>= '0' && lastChar
<= '9') {
3417 CFStringDelete(interfacePrefix
,
3418 CFRangeMake(length
-1, 1));
3423 length
= CFStringGetLength(interfacePrefix
);
3426 return interfacePrefix
;
3431 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3432 CFStringRef prefix
);
3436 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3438 Boolean success
= FALSE
;
3439 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3441 if (isA_SCNetworkInterface(interface
) == NULL
) {
3442 SC_log(LOG_INFO
, "No interface");
3446 if (CFEqual(currentBSDName
, newBSDName
)) {
3451 if (interfacePrivate
->entity_device
!= NULL
) {
3452 CFRelease(interfacePrivate
->entity_device
);
3454 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3462 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3464 Boolean success
= FALSE
;
3465 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3466 CFStringRef oldPath
= NULL
;
3467 CFStringRef newPath
= NULL
;
3469 // Using the BSD Name update the path
3470 oldPath
= interfacePrivate
->path
;
3471 if (isA_CFString(oldPath
) == NULL
) {
3474 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3475 if (interfacePrivate
->path
!= NULL
) {
3476 CFRelease(interfacePrivate
->path
);
3478 interfacePrivate
->path
= CFRetain(newPath
);
3482 if (newPath
!= NULL
) {
3490 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3493 SCNetworkInterfacePrivateRef interfacePrivate
;
3495 if (isA_CFString(prefix
) == NULL
) {
3499 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3503 if (interfacePrivate
->prefix
!= NULL
) {
3504 CFRelease(interfacePrivate
->prefix
);
3507 interfacePrivate
->prefix
= prefix
;
3514 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3517 SCNetworkInterfacePrivateRef interfacePrivate
;
3518 CFStringRef newBSDName
= NULL
;
3519 CFStringRef oldBSDName
= NULL
;
3521 if (isA_CFNumber(unit
) == NULL
) {
3524 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3526 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3528 if (interfacePrivate
->prefix
== NULL
) {
3529 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3530 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3531 if (interfaceNamePrefix
== NULL
) {
3532 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3535 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3536 CFRelease(interfaceNamePrefix
);
3541 if (interfacePrivate
->prefix
!= NULL
) {
3542 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3545 // Update the BSD Name
3546 if ((newBSDName
== NULL
) ||
3547 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3548 SC_log(LOG_INFO
, "BSD name update failed");
3552 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3553 SC_log(LOG_INFO
, "IOPath update failed");
3557 if (interfacePrivate
->unit
!= NULL
) {
3558 CFRelease(interfacePrivate
->unit
);
3560 interfacePrivate
->unit
= unit
;
3563 if (newBSDName
!= NULL
) {
3564 CFRelease(newBSDName
);
3572 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3574 CFMutableDictionaryRef interface_entity
= NULL
;
3575 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3576 CFBooleanRef active
= NULL
;
3577 CFStringRef bsdName
= NULL
;
3578 CFBooleanRef builtin
= NULL
;
3579 CFStringRef interfaceNamePrefix
= NULL
;
3580 CFNumberRef interfaceType
= NULL
;
3581 CFNumberRef interfaceUnit
= NULL
;
3582 CFDataRef macAddress
= NULL
;
3583 CFStringRef pathMatch
= NULL
;
3584 CFDictionaryRef info
= NULL
;
3585 CFStringRef type
= NULL
;
3587 if (interfacePrivate
->active
) {
3588 active
= kCFBooleanTrue
;
3591 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3592 if (!isA_CFString(bsdName
)) {
3596 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3597 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3598 if (!isA_CFString(interfaceNamePrefix
)) {
3602 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3603 if (!isA_CFNumber(interfaceType
)) {
3607 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3608 if (!isA_CFNumber(interfaceUnit
)) {
3612 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3613 if (!isA_CFData(macAddress
)) {
3617 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3618 if (!isA_CFString(pathMatch
)) {
3622 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3623 if (!isA_CFDictionary(info
)) {
3627 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3628 if (!isA_CFString(type
)) {
3632 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3633 &kCFTypeDictionaryKeyCallBacks
,
3634 &kCFTypeDictionaryValueCallBacks
);
3636 if (isA_CFBoolean(active
) != NULL
) {
3637 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3640 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3641 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3642 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3643 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3644 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3645 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3646 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3647 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3648 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3653 return interface_entity
;
3658 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3659 SCNetworkServiceRef service
)
3661 SCNetworkInterfacePrivateRef interfacePrivate
;
3662 SCNetworkServicePrivateRef servicePrivate
;
3664 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3665 if (interfacePrivate
->prefs
!= NULL
) {
3666 CFRelease(interfacePrivate
->prefs
);
3667 interfacePrivate
->prefs
= NULL
;
3669 if (interfacePrivate
->serviceID
!= NULL
) {
3670 CFRelease(interfacePrivate
->serviceID
);
3671 interfacePrivate
->serviceID
= NULL
;
3674 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3675 if (servicePrivate
->prefs
!= NULL
) {
3676 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3678 if (servicePrivate
->serviceID
!= NULL
) {
3679 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3688 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3693 if (bundle
== NULL
) {
3694 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3698 if (!isA_CFString(name
)) {
3699 // if no interface "name"
3703 // check non-localized name for a match
3704 str
= copy_interface_string(bundle
, key
, FALSE
);
3706 match
= CFEqual(name
, str
);
3713 // check localized name for a match
3714 str
= copy_interface_string(bundle
, key
, TRUE
);
3716 match
= CFEqual(name
, str
);
3727 #define kInterfaceTypeEthernetValue 6
3728 #define kInterfaceTypeFirewireValue 144
3731 static SCNetworkInterfaceRef
3732 __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator
,
3733 CFDictionaryRef interface_entity
,
3734 SCPreferencesRef prefs
)
3736 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3737 CFBooleanRef active
= NULL
;
3738 CFStringRef bsdName
= NULL
;
3739 CFBooleanRef ioBuiltin
= NULL
;
3740 CFStringRef ioInterfaceNamePrefix
= NULL
;
3741 CFNumberRef ioInterfaceType
= NULL
;
3742 int ioInterfaceTypeNum
;
3743 CFNumberRef ioInterfaceUnit
= NULL
;
3744 CFDataRef ioMACAddress
= NULL
;
3745 CFStringRef ioPathMatch
= NULL
;
3746 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3747 CFStringRef userDefinedName
= NULL
;
3748 CFStringRef usbProductName
= NULL
;
3749 CFNumberRef idProduct
= NULL
;
3750 CFNumberRef idVendor
= NULL
;
3751 CFStringRef type
= NULL
;
3753 /* initialize runtime */
3754 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3756 if (isA_CFDictionary(interface_entity
) == NULL
) {
3757 SC_log(LOG_INFO
, "No interface entity");
3760 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3761 if (isA_CFBoolean(active
) == NULL
) {
3762 active
= kCFBooleanFalse
;
3764 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3765 if (isA_CFString(bsdName
) == NULL
) {
3766 SC_log(LOG_INFO
, "No BSD name");
3769 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3770 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3771 SC_log(LOG_INFO
, "No IOBuiltin property");
3774 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3775 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3776 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3777 if (ioInterfaceNamePrefix
== NULL
) {
3778 SC_log(LOG_INFO
, "No BSD interface name prefix");
3782 CFRetain(ioInterfaceNamePrefix
);
3784 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3785 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3786 SC_log(LOG_INFO
, "No IOInterfaceType");
3789 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3790 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3792 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3793 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3794 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3798 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3799 if (isA_CFData(ioMACAddress
) == NULL
) {
3800 SC_log(LOG_INFO
, "No IOMACAddress");
3803 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3804 if (isA_CFString(ioPathMatch
) == NULL
) {
3805 SC_log(LOG_INFO
, "No IOPathMatch");
3808 // Check if Path contains the BSD Name in the end
3810 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3811 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3812 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3815 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3816 #if !TARGET_OS_SIMULATOR
3817 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3818 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3819 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3820 #endif // !TARGET_OS_SIMULATOR
3822 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3823 if (isA_CFString(type
) == NULL
) {
3824 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3828 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3829 interfacePrivate
->active
= CFBooleanGetValue(active
);
3830 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3831 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3832 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3833 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3834 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3835 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3836 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3837 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3838 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3839 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3840 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3841 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3843 // Handling interface types to be seen in NetworkInterfaces.plist
3844 CFIndex interfaceIndex
;
3846 interfaceIndex
= findConfiguration(type
);
3847 if (interfaceIndex
!= kCFNotFound
) {
3848 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3850 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3853 // Extracting entity type from value of interface type
3854 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3855 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3856 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3857 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3860 if (ioInterfaceNamePrefix
!= NULL
) {
3861 CFRelease(ioInterfaceNamePrefix
);
3864 return (SCNetworkInterfaceRef
)interfacePrivate
;
3868 SCNetworkInterfaceRef
3869 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3870 CFDictionaryRef interface_entity
,
3871 SCNetworkServiceRef service
)
3873 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3874 CFStringRef ifDevice
;
3875 CFStringRef ifName
= NULL
;
3876 CFStringRef ifSubType
;
3878 CFStringRef ifUnique
;
3879 CFArrayRef matching_interfaces
= NULL
;
3880 SCPreferencesRef servicePref
= NULL
;
3881 Boolean useSystemInterfaces
= TRUE
;
3883 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3884 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3886 if (service
!= NULL
) {
3887 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3888 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3889 (__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
) == FALSE
));
3892 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3893 if (ifType
== NULL
) {
3895 * The interface "Type" was not specified. We'll make an
3896 * assumption that this is an "Ethernet" interface. If a
3897 * real interface exists with the provided interface name
3898 * then the actual type will be set accordingly. If not, we'll
3899 * end up crafting an "Ethernet" SCNetworkInterface that
3900 * will keep the rest of the configuration APIs happy.
3902 ifType
= kSCValNetInterfaceTypeEthernet
;
3905 if (!isA_CFString(ifType
)) {
3909 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3910 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3911 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3912 if (!isA_CFString(ifSubType
)) {
3917 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3918 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3920 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3921 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3922 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3923 char bsdName
[IFNAMSIZ
];
3924 CFMutableDictionaryRef matching
;
3926 if (!isA_CFString(ifDevice
)) {
3930 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3931 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3934 if (useSystemInterfaces
) {
3935 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3939 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3940 if (matching
== NULL
) {
3943 matching_interfaces
= findMatchingInterfaces(matching
,
3944 processNetworkInterface
,
3945 kSCNetworkInterfaceHiddenInterfaceKey
,
3947 CFRelease(matching
);
3949 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3950 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3951 CFDictionaryRef matching
;
3952 CFStringRef match_keys
[2];
3953 CFStringRef match_vals
[2];
3955 if (!isA_CFString(ifDevice
)) {
3959 if (useSystemInterfaces
) {
3960 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3961 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3963 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3964 match_vals
[1] = ifDevice
;
3966 matching
= CFDictionaryCreate(NULL
,
3967 (const void **)match_keys
,
3968 (const void **)match_vals
,
3969 sizeof(match_keys
)/sizeof(match_keys
[0]),
3970 &kCFTypeDictionaryKeyCallBacks
,
3971 &kCFTypeDictionaryValueCallBacks
);
3972 matching_interfaces
= findMatchingInterfaces(matching
,
3973 processSerialInterface
,
3974 kSCNetworkInterfaceHiddenPortKey
,
3976 CFRelease(matching
);
3978 if (ifUnique
== NULL
) {
3980 Boolean useDeviceName
= TRUE
;
3982 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3986 for (i
= 0; i
< n
; i
++) {
3987 SCNetworkInterfacePrivateRef scanPrivate
;
3989 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3990 if (scanPrivate
->entity_device_unique
!= NULL
) {
3991 useDeviceName
= FALSE
;
3997 if (useDeviceName
&& useSystemInterfaces
) {
3998 if (matching_interfaces
!= NULL
) {
3999 CFRelease(matching_interfaces
);
4002 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4003 matching
= CFDictionaryCreate(NULL
,
4004 (const void **)match_keys
,
4005 (const void **)match_vals
,
4006 sizeof(match_keys
)/sizeof(match_keys
[0]),
4007 &kCFTypeDictionaryKeyCallBacks
,
4008 &kCFTypeDictionaryValueCallBacks
);
4009 matching_interfaces
= findMatchingInterfaces(matching
,
4010 processSerialInterface
,
4011 kSCNetworkInterfaceHiddenPortKey
,
4013 CFRelease(matching
);
4016 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4017 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4018 kSCNetworkInterfaceTypeL2TP
);
4019 #pragma GCC diagnostic push
4020 #pragma GCC diagnostic ignored "-Wdeprecated"
4021 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4022 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4023 kSCNetworkInterfaceTypePPTP
);
4024 #pragma GCC diagnostic pop
4026 // XXX do we allow non-Apple variants of PPP??? XXX
4027 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4030 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4031 if (!isA_CFString(ifDevice
)) {
4035 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4036 kSCNetworkInterfaceType6to4
);
4037 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4038 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4039 kSCNetworkInterfaceTypeIPSec
);
4040 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4041 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4042 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4043 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4044 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4047 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4048 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4052 if (matching_interfaces
!= NULL
) {
4054 SCPreferencesRef prefs
;
4055 Boolean temp_preferences
= FALSE
;
4057 n
= CFArrayGetCount(matching_interfaces
);
4060 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4061 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4062 // if the unique ID's match
4063 CFRetain(interfacePrivate
);
4067 interfacePrivate
= NULL
;
4070 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4074 if (CFDictionaryGetValueIfPresent(interface_entity
,
4075 kSCPropUserDefinedName
,
4076 (const void **)&ifName
) &&
4077 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4081 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4082 if (prefs
== NULL
) {
4083 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4084 if (prefs
!= NULL
) {
4085 temp_preferences
= TRUE
;
4088 if (prefs
== NULL
) {
4091 #if !TARGET_OS_IPHONE
4092 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4093 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4095 #endif // !TARGET_OS_IPHONE
4096 if ((interfacePrivate
== NULL
)
4097 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4098 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4101 if ((interfacePrivate
== NULL
)
4102 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4103 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4105 if (temp_preferences
) CFRelease(prefs
);
4108 if (ifUnique
!= NULL
) {
4111 // we are looking for an interface with a unique ID
4112 // so let's try to focus our choices
4113 for (i
= 0; i
< n
; i
++) {
4114 SCNetworkInterfacePrivateRef scanPrivate
;
4116 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4117 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4118 if (interfacePrivate
!= NULL
) {
4119 // if we've matched more than one interface
4120 interfacePrivate
= NULL
;
4123 interfacePrivate
= scanPrivate
;
4126 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4127 kSCPropUserDefinedName
,
4128 (const void **)&ifName
)) {
4131 // we don't have a unique ID but do have an interface
4132 // name. If the matching interfaces do have IDs than
4133 // we can try to focus our choices using the name
4134 for (i
= 0; i
< n
; i
++) {
4135 SCNetworkInterfacePrivateRef scanPrivate
;
4137 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4138 if (scanPrivate
->entity_device_unique
!= NULL
) {
4139 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4140 CFStringRef scanName
;
4142 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4143 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4144 continue; // if not the same display name
4148 if (interfacePrivate
!= NULL
) {
4149 // if we've matched more than one interface
4150 interfacePrivate
= NULL
;
4153 interfacePrivate
= scanPrivate
;
4156 if (interfacePrivate
== NULL
) {
4157 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4158 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4160 CFRetain(interfacePrivate
);
4163 CFRelease(matching_interfaces
);
4168 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4170 * if device not present on this system
4172 if (!useSystemInterfaces
) {
4173 if (interfacePrivate
!= NULL
) {
4174 CFRelease(interfacePrivate
);
4178 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4179 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4180 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4181 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4182 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4184 // Using UserDefinedName to check the validity of preferences file
4185 // when useSystemInterfaces is FALSE
4186 if (!useSystemInterfaces
) {
4187 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4188 if (isA_CFString(userDefinedName
) != NULL
) {
4189 CFRetain(userDefinedName
);
4190 if (interfacePrivate
->name
!= NULL
) {
4191 CFRelease(interfacePrivate
->name
);
4193 interfacePrivate
->name
= userDefinedName
;
4195 CFRetain(userDefinedName
);
4196 if (interfacePrivate
->localized_name
!= NULL
) {
4197 CFRelease(interfacePrivate
->localized_name
);
4199 interfacePrivate
->localized_name
= userDefinedName
;
4203 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4204 CFStringRef entity_hardware
;
4205 SCNetworkInterfaceRef virtualInterface
;
4207 if (!useSystemInterfaces
&&
4208 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4209 #if !TARGET_OS_IPHONE
4210 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4212 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4213 CFRelease(interfacePrivate
);
4214 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4216 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4217 if (isA_CFString((entity_hardware
)) &&
4218 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4219 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4220 interfacePrivate
->localized_key
= CFSTR("airport");
4221 interfacePrivate
->sort_order
= kSortAirPort
;
4225 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4227 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4228 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4229 interfacePrivate
->localized_key
= CFSTR("iPhone");
4230 interfacePrivate
->sort_order
= kSortTethered
;
4231 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4232 interfacePrivate
->localized_key
= CFSTR("iPad");
4233 interfacePrivate
->sort_order
= kSortTethered
;
4234 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4235 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4236 interfacePrivate
->sort_order
= kSortThunderbolt
;
4237 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4238 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4239 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4240 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4241 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4242 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4243 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4244 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4245 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4247 interfacePrivate
->sort_order
= kSortEthernet
;
4251 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4252 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4253 interfacePrivate
->sort_order
= kSortFireWire
;
4254 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4255 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4256 CFStringRef entity_hardware
;
4258 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4259 if (isA_CFString((entity_hardware
)) &&
4260 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4261 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4262 interfacePrivate
->sort_order
= kSortAirPort
;
4264 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4265 interfacePrivate
->sort_order
= kSortEthernet
;
4267 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4268 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4269 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4270 interfacePrivate
->sort_order
= kSortBluetooth
;
4271 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4272 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4273 interfacePrivate
->sort_order
= kSortIrDA
;
4274 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4275 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4276 interfacePrivate
->sort_order
= kSortWWAN
;
4278 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4279 interfacePrivate
->sort_order
= kSortModem
;
4282 SCNetworkInterfaceRef child
;
4284 CFRelease(interfacePrivate
);
4285 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4286 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4287 if (interfacePrivate
== NULL
) {
4291 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4292 SCNetworkInterfaceRef child
;
4293 CFRelease(interfacePrivate
);
4294 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4295 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4296 if (interfacePrivate
== NULL
) {
4299 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4300 CFRelease(interfacePrivate
);
4301 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4302 kSCNetworkInterfaceTypeIPSec
);
4303 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4304 CFRelease(interfacePrivate
);
4305 if (!isA_CFString(ifDevice
)) {
4308 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4309 kSCNetworkInterfaceType6to4
);
4310 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4311 CFRelease(interfacePrivate
);
4312 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4313 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4314 // if vendor interface
4315 pthread_mutex_lock(&lock
);
4316 if (vendor_interface_types
== NULL
) {
4317 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4319 CFSetAddValue(vendor_interface_types
, ifType
);
4320 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4321 pthread_mutex_unlock(&lock
);
4323 // if unknown interface
4324 CFRelease(interfacePrivate
);
4325 interfacePrivate
= NULL
;
4329 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4330 interfacePrivate
->hidden
= TRUE
;
4334 if (service
!= NULL
) {
4335 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4338 #if !TARGET_OS_IPHONE
4339 // set prefs & serviceID to Bond member interfaces
4340 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4345 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4346 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4347 for (i
= 0; i
< n
; i
++) {
4348 SCNetworkInterfaceRef member
;
4350 member
= CFArrayGetValueAtIndex(members
, i
);
4351 __SCNetworkInterfaceSetService(member
, service
);
4354 #endif // !TARGET_OS_IPHONE
4356 // set prefs & serviceID to Bridge member interfaces
4357 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4362 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4363 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4364 for (i
= 0; i
< n
; i
++) {
4365 SCNetworkInterfaceRef member
;
4367 member
= CFArrayGetValueAtIndex(members
, i
);
4368 __SCNetworkInterfaceSetService(member
, service
);
4371 // set prefs & serviceID to VLAN pyhsical interface
4372 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4373 SCNetworkInterfaceRef vlan_physical
;
4375 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4376 if (vlan_physical
!= NULL
) {
4377 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4382 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4383 SCNetworkInterfaceRef parent
;
4386 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4387 kSCNetworkInterfaceTypePPP
);
4388 CFRelease(interfacePrivate
);
4389 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4390 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4391 SCNetworkInterfaceRef parent
;
4394 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4395 kSCNetworkInterfaceTypeVPN
);
4396 CFRelease(interfacePrivate
);
4397 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4400 return (SCNetworkInterfaceRef
)interfacePrivate
;
4405 #pragma mark SCNetworkInterface APIs
4410 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4412 CFDictionaryRef matching
;
4413 CFArrayRef new_interfaces
;
4415 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4417 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4418 new_interfaces
= findMatchingInterfaces(matching
,
4419 processNetworkInterface
,
4420 kSCNetworkInterfaceHiddenInterfaceKey
,
4421 keep_pre_configured
);
4422 CFRelease(matching
);
4424 return new_interfaces
;
4430 __SCNetworkInterfaceCopyAll_Modem()
4432 CFDictionaryRef matching
;
4433 CFStringRef match_keys
[2];
4434 CFStringRef match_vals
[2];
4435 CFArrayRef new_interfaces
;
4437 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4438 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4440 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4441 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4443 matching
= CFDictionaryCreate(NULL
,
4444 (const void **)match_keys
,
4445 (const void **)match_vals
,
4446 sizeof(match_keys
)/sizeof(match_keys
[0]),
4447 &kCFTypeDictionaryKeyCallBacks
,
4448 &kCFTypeDictionaryValueCallBacks
);
4449 new_interfaces
= findMatchingInterfaces(matching
,
4450 processSerialInterface
,
4451 kSCNetworkInterfaceHiddenPortKey
,
4453 CFRelease(matching
);
4455 return new_interfaces
;
4461 __SCNetworkInterfaceCopyAll_RS232()
4463 CFDictionaryRef matching
;
4464 CFStringRef match_keys
[2];
4465 CFStringRef match_vals
[2];
4466 CFArrayRef new_interfaces
;
4468 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4469 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4471 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4472 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4474 matching
= CFDictionaryCreate(NULL
,
4475 (const void **)match_keys
,
4476 (const void **)match_vals
,
4477 sizeof(match_keys
)/sizeof(match_keys
[0]),
4478 &kCFTypeDictionaryKeyCallBacks
,
4479 &kCFTypeDictionaryValueCallBacks
);
4480 new_interfaces
= findMatchingInterfaces(matching
,
4481 processSerialInterface
,
4482 kSCNetworkInterfaceHiddenPortKey
,
4484 CFRelease(matching
);
4486 return new_interfaces
;
4490 #if !TARGET_OS_IPHONE
4492 addBTPANInterface(SCPreferencesRef prefs
, CFMutableArrayRef all_interfaces
)
4495 SCNetworkInterfaceRef interface
;
4498 n
= CFArrayGetCount(all_interfaces
);
4499 for (i
= 0; i
< n
; i
++) {
4500 SCNetworkInterfaceRef interface
;
4502 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4503 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4504 // if we already have a BT-PAN interface
4509 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4510 if (interface
!= NULL
) {
4511 // include BT-PAN interface
4512 CFArrayAppendValue(all_interfaces
, interface
);
4513 CFRelease(interface
);
4518 #endif // !TARGET_OS_IPHONE
4522 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4527 n
= CFArrayGetCount(new_interfaces
);
4528 for (i
= 0; i
< n
; i
++) {
4529 CFStringRef bsdName
;
4530 SCNetworkInterfaceRef interface
;
4532 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4533 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4534 if (bsdName
!= NULL
) {
4535 CFArrayAppendValue(all_interfaces
, interface
);
4544 __waitForInterfaces()
4549 SCDynamicStoreRef store
;
4551 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4552 if (store
== NULL
) {
4556 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4557 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4558 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4561 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4566 CFArrayRef changedKeys
;
4567 CFDictionaryRef dict
;
4568 Boolean quiet
= FALSE
;
4571 dict
= SCDynamicStoreCopyValue(store
, key
);
4573 if (isA_CFDictionary(dict
) &&
4574 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4575 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4584 ok
= SCDynamicStoreNotifyWait(store
);
4586 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4590 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4591 if (changedKeys
!= NULL
) {
4592 CFRelease(changedKeys
);
4604 CFArrayRef
/* of SCNetworkInterfaceRef's */
4605 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4607 CFMutableArrayRef all_interfaces
;
4608 CFArrayRef new_interfaces
;
4609 Boolean temp_preferences
= FALSE
;
4611 /* initialize runtime */
4612 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4614 /* wait for IOKit to quiesce */
4615 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4617 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4619 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4620 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4621 if (new_interfaces
!= NULL
) {
4622 add_interfaces(all_interfaces
, new_interfaces
);
4623 CFRelease(new_interfaces
);
4626 // get Modem interfaces
4627 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4628 if (new_interfaces
!= NULL
) {
4629 add_interfaces(all_interfaces
, new_interfaces
);
4630 CFRelease(new_interfaces
);
4633 // get serial (RS232) interfaces
4634 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4635 if (new_interfaces
!= NULL
) {
4636 add_interfaces(all_interfaces
, new_interfaces
);
4637 CFRelease(new_interfaces
);
4640 // get virtual network interfaces (Bond, Bridge, VLAN)
4641 if (prefs
== NULL
) {
4642 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4643 if (prefs
!= NULL
) {
4644 temp_preferences
= TRUE
;
4647 if (prefs
!= NULL
) {
4648 #if !TARGET_OS_IPHONE
4649 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4650 if (new_interfaces
!= NULL
) {
4651 add_interfaces(all_interfaces
, new_interfaces
);
4652 CFRelease(new_interfaces
);
4654 #endif // !TARGET_OS_IPHONE
4656 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4657 if (new_interfaces
!= NULL
) {
4658 add_interfaces(all_interfaces
, new_interfaces
);
4659 CFRelease(new_interfaces
);
4662 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4663 if (new_interfaces
!= NULL
) {
4664 add_interfaces(all_interfaces
, new_interfaces
);
4665 CFRelease(new_interfaces
);
4668 #if !TARGET_OS_IPHONE
4669 // add BT-PAN interface
4670 addBTPANInterface(prefs
, all_interfaces
);
4671 #endif // !TARGET_OS_IPHONE
4673 if (temp_preferences
) CFRelease(prefs
);
4676 // all interfaces have been identified, order and return
4677 sort_interfaces(all_interfaces
);
4679 return all_interfaces
;
4683 CFArrayRef
/* of SCNetworkInterfaceRef's */
4684 SCNetworkInterfaceCopyAll()
4686 CFArrayRef all_interfaces
;
4688 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4689 return all_interfaces
;
4693 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4694 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4697 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4699 if (!isA_SCNetworkInterface(interface
)) {
4700 _SCErrorSet(kSCStatusInvalidArgument
);
4704 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4708 i
= findConfiguration(interfacePrivate
->interface_type
);
4709 if (i
!= kCFNotFound
) {
4710 if (configurations
[i
].supported_interfaces
!= doNone
) {
4711 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4712 if (configurations
[i
].supported_interfaces
& do6to4
) {
4713 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4715 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4716 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4718 if (configurations
[i
].supported_interfaces
& doPPP
) {
4719 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4721 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4722 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4726 SCNetworkInterfaceRef child
;
4728 child
= SCNetworkInterfaceGetInterface(interface
);
4729 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4730 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4731 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4737 return interfacePrivate
->supported_interface_types
;
4741 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4742 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4745 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4747 if (!isA_SCNetworkInterface(interface
)) {
4748 _SCErrorSet(kSCStatusInvalidArgument
);
4752 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4756 i
= findConfiguration(interfacePrivate
->interface_type
);
4757 if (i
!= kCFNotFound
) {
4758 if (configurations
[i
].supported_protocols
!= doNone
) {
4759 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4760 if (configurations
[i
].supported_protocols
& doDNS
) {
4761 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4763 if (configurations
[i
].supported_protocols
& doIPv4
) {
4764 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4766 if (configurations
[i
].supported_protocols
& doIPv6
) {
4767 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4769 if (configurations
[i
].supported_protocols
& doProxies
) {
4770 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4772 #if !TARGET_OS_IPHONE
4773 if (configurations
[i
].supported_protocols
& doSMB
) {
4774 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4776 #endif // !TARGET_OS_IPHONE
4782 return interfacePrivate
->supported_protocol_types
;
4786 SCNetworkInterfaceRef
4787 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4789 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4791 SCNetworkInterfacePrivateRef parentPrivate
;
4793 if (!isA_SCNetworkInterface(child
)) {
4794 _SCErrorSet(kSCStatusInvalidArgument
);
4798 if (!isA_CFString(interfaceType
)) {
4799 _SCErrorSet(kSCStatusInvalidArgument
);
4803 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4804 // can't layer on top of loopback
4805 _SCErrorSet(kSCStatusInvalidArgument
);
4809 childIndex
= findConfiguration(childPrivate
->interface_type
);
4811 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4813 childPrivate
->prefs
,
4814 childPrivate
->serviceID
);
4815 if (parentPrivate
== NULL
) {
4816 _SCErrorSet(kSCStatusFailed
);
4820 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4821 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4822 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4825 if (childIndex
!= kCFNotFound
) {
4826 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4827 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4829 // sorry, the child interface does not support PPP
4833 // if the child's interface type not known, use the child entities "Type"
4834 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4837 if (childPrivate
->entity_device
!= NULL
) {
4838 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4841 if (childPrivate
->entity_device_unique
!= NULL
) {
4842 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4844 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4845 if ((childIndex
== kCFNotFound
) ||
4846 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4847 // if the child interface does not support L2TP
4850 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4851 parentPrivate
->localized_key
= CFSTR("l2tp");
4852 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4853 #pragma GCC diagnostic push
4854 #pragma GCC diagnostic ignored "-Wdeprecated"
4855 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4856 if ((childIndex
== kCFNotFound
) ||
4857 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4858 // if the child interface does not support PPTP
4861 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4862 parentPrivate
->localized_key
= CFSTR("pptp");
4863 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4864 #pragma GCC diagnostic pop
4865 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4866 if ((childIndex
== kCFNotFound
) ||
4867 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4868 // if the child interface does not support 6to4
4872 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4873 parentPrivate
->localized_key
= CFSTR("6to4");
4874 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4875 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4876 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4877 if ((childIndex
== kCFNotFound
) ||
4878 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4879 // if the child interface does not support IPSec
4882 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4883 parentPrivate
->localized_key
= CFSTR("ipsec");
4884 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4885 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4886 if (childIndex
!= kCFNotFound
) {
4887 // if not a "vendor" child interface
4891 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4892 parentPrivate
->localized_key
= CFSTR("vpn");
4893 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4894 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4895 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4896 if (childPrivate
->entity_device
!= NULL
) {
4897 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4899 if (parentPrivate
->entity_subtype
!= NULL
) {
4900 CFArrayRef components
;
4902 CFStringRef vpnType
;
4905 // the "default" interface name is derived from the VPN type
4908 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4911 vpnType
= parentPrivate
->entity_subtype
;
4912 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4913 n
= CFArrayGetCount(components
);
4915 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4916 CFMutableStringRef str
;
4918 str
= CFStringCreateMutableCopy(NULL
,
4920 CFArrayGetValueAtIndex(components
, n
- 2));
4921 (void) CFStringFindAndReplace(str
,
4924 CFRangeMake(0, CFStringGetLength(str
)),
4926 parentPrivate
->localized_name
= str
;
4928 CFRelease(components
);
4930 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4931 // if custom interface type
4932 pthread_mutex_lock(&lock
);
4933 if (vendor_interface_types
== NULL
) {
4934 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4936 CFSetAddValue(vendor_interface_types
, interfaceType
);
4937 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4938 pthread_mutex_unlock(&lock
);
4940 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4941 // a dictionary with the same
4942 // name as the interfaceType
4944 // unknown interface type
4948 parentPrivate
->hidden
= childPrivate
->hidden
;
4950 if (childPrivate
->overrides
!= NULL
) {
4951 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
4954 // The following change handles the case where a user has both an Ethernet and
4955 // PPPoE network service. Because a PPPoE service is typically associated with
4956 // an ISP we want it to be sorted higher in the service order.
4957 if ((parentPrivate
->entity_subtype
!= NULL
) &&
4958 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
4959 if ((childPrivate
->interface_type
!= NULL
) &&
4960 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
4961 parentPrivate
->sort_order
= kSortAirportPPP
;
4963 parentPrivate
->sort_order
= kSortEthernetPPP
;
4966 // set sort order of the parent to match the child interface
4967 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4970 return (SCNetworkInterfaceRef
)parentPrivate
;
4974 CFRelease(parentPrivate
);
4975 _SCErrorSet(kSCStatusInvalidArgument
);
4982 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4984 CFDictionaryRef config
= NULL
;
4985 CFStringRef defaultType
;
4986 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4988 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4989 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4991 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4992 if (defaultType
!= NULL
) {
4996 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4997 SCNetworkSetGetSetID(set
), // set
4998 interfacePrivate
->entity_device
, // interface
4999 defaultType
); // entity
5001 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5004 if (config
== NULL
) {
5005 // if the "set" does not have a saved configuration, use
5006 // the [template] "interface" configuration
5007 if (interfacePrivate
->unsaved
!= NULL
) {
5008 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5009 if (config
== (CFDictionaryRef
)kCFNull
) {
5014 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5025 static CFDictionaryRef
5026 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5027 CFStringRef extendedType
)
5029 CFDictionaryRef config
= NULL
;
5030 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5033 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5034 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5036 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5037 if (paths
!= NULL
) {
5040 path
= CFArrayGetValueAtIndex(paths
, 0);
5041 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5045 if (interfacePrivate
->unsaved
!= NULL
) {
5046 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5047 if (config
== (CFDictionaryRef
)kCFNull
) {
5053 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5062 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5064 CFDictionaryRef config
;
5065 CFStringRef defaultType
;
5067 if (!isA_SCNetworkInterface(interface
)) {
5068 _SCErrorSet(kSCStatusInvalidArgument
);
5072 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5073 if (defaultType
== NULL
) {
5077 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5078 if (config
== NULL
) {
5079 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5080 SCNetworkInterfacePrivateRef interfacePrivate
;
5083 // if AirPort interface, check for a per-service config
5084 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5085 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5086 interfacePrivate
->serviceID
, // service
5087 kSCEntNetAirPort
); // entity
5088 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5092 if (config
== NULL
) {
5093 _SCErrorSet(kSCStatusOK
);
5101 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5102 CFStringRef extendedType
)
5104 CFDictionaryRef config
;
5106 if (!isA_SCNetworkInterface(interface
)) {
5107 _SCErrorSet(kSCStatusInvalidArgument
);
5111 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5112 _SCErrorSet(kSCStatusInvalidArgument
);
5116 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5117 if (config
== NULL
) {
5118 _SCErrorSet(kSCStatusOK
);
5127 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5129 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5131 return interfacePrivate
->entity_type
;
5137 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5139 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5141 return interfacePrivate
->entity_subtype
;
5146 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5148 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5150 if (!isA_SCNetworkInterface(interface
)) {
5151 _SCErrorSet(kSCStatusInvalidArgument
);
5155 if ((interfacePrivate
->interface
!= NULL
) &&
5156 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5157 _SCErrorSet(kSCStatusOK
);
5161 return interfacePrivate
->entity_device
;
5166 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5168 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5170 if (!isA_SCNetworkInterface(interface
)) {
5171 _SCErrorSet(kSCStatusInvalidArgument
);
5175 if ((interfacePrivate
->address
!= NULL
) &&
5176 (interfacePrivate
->addressString
== NULL
)) {
5180 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5183 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5184 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5186 if (n
> sizeof(mac
)) {
5187 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5190 for (cp
= mac_p
; n
> 0; n
-= 3) {
5191 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5194 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5195 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5198 return interfacePrivate
->addressString
;
5202 SCNetworkInterfaceRef
5203 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5205 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5207 if (!isA_SCNetworkInterface(interface
)) {
5208 _SCErrorSet(kSCStatusInvalidArgument
);
5212 return interfacePrivate
->interface
;
5217 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5219 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5221 if (!isA_SCNetworkInterface(interface
)) {
5222 _SCErrorSet(kSCStatusInvalidArgument
);
5226 return interfacePrivate
->interface_type
;
5231 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5233 CFStringRef str
= NULL
;
5236 str
= CFBundleCopyLocalizedString(bundle
,
5239 NETWORKINTERFACE_LOCALIZATIONS
);
5241 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5244 NETWORKINTERFACE_LOCALIZATIONS
);
5252 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5254 static Boolean reported
= FALSE
;
5255 CFStringRef str
= NULL
;
5257 str
= copy_string_from_bundle(bundle
, key
, localized
);
5260 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5266 if (CFEqual(str
, key
) && !reported
) {
5267 const CFStringRef knownStrKey
= CFSTR("airport");
5268 CFStringRef knownStrValue
= NULL
;
5270 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5271 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5272 /* We are here because we requested for a localized/non-localized string
5273 based on the localization key, but we were given the same key/NULL back,
5274 implying a bad...bad thing!
5276 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5280 #if TARGET_OS_IPHONE
5281 /* ...and we want to know about it! */
5282 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5283 #endif //TARGET_OS_IPHONE
5287 if (knownStrValue
!= NULL
) {
5288 CFRelease(knownStrValue
);
5298 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5300 CFMutableStringRef local
;
5303 local
= CFStringCreateMutable(NULL
, 0);
5305 while (interface
!= NULL
) {
5306 Boolean added
= FALSE
;
5307 SCNetworkInterfaceRef child
= NULL
;
5308 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5310 if ((interfacePrivate
->interface
!= NULL
) &&
5311 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5312 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5313 child
= interfacePrivate
->interface
;
5316 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5318 CFStringRef key
= interfacePrivate
->localized_key
;
5320 if (oldLocalization
) {
5321 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5322 interfacePrivate
->localized_key
);
5324 fmt
= copy_interface_string(bundle
, key
, localized
);
5326 CFStringAppendFormat(local
,
5329 interfacePrivate
->localized_arg1
,
5330 interfacePrivate
->localized_arg2
);
5334 if (oldLocalization
) {
5340 (interfacePrivate
->prefs
!= NULL
) &&
5341 (interfacePrivate
->serviceID
!= NULL
) &&
5343 CFDictionaryRef entity
;
5346 // check for (and use) the name of the interface when it
5347 // was last available
5348 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5349 interfacePrivate
->serviceID
,
5350 kSCEntNetInterface
);
5351 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5353 if (isA_CFDictionary(entity
)) {
5356 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5357 if (isA_CFString(name
)) {
5358 CFStringAppend(local
, name
);
5365 // create (non-)localized name based on the interface type
5366 CFStringAppend(local
, interfacePrivate
->interface_type
);
5368 // ... and, if this is a leaf node, the interface device
5369 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5370 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5374 if (child
!= NULL
) {
5375 // if this interface is layered over another
5376 CFStringAppend(local
, CFSTR(" --> "));
5382 name
= CFStringCreateCopy(NULL
, local
);
5389 #if !TARGET_OS_IPHONE
5392 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5396 if (!isA_SCNetworkInterface(interface
)) {
5397 _SCErrorSet(kSCStatusInvalidArgument
);
5401 name
= copy_display_name(interface
, TRUE
, TRUE
);
5408 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5410 CFStringRef localized_name
;
5412 if (!isA_SCNetworkInterface(interface
)) {
5413 _SCErrorSet(kSCStatusInvalidArgument
);
5417 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5418 return localized_name
;
5420 #endif // !TARGET_OS_IPHONE
5424 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5426 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5428 if (!isA_SCNetworkInterface(interface
)) {
5434 if (interfacePrivate
->name
!= NULL
) {
5435 CFRelease(interfacePrivate
->name
);
5437 interfacePrivate
->name
= name
;
5442 if (interfacePrivate
->localized_name
!= NULL
) {
5443 CFRelease(interfacePrivate
->localized_name
);
5445 interfacePrivate
->localized_name
= name
;
5450 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5452 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5454 if (!isA_SCNetworkInterface(interface
)) {
5458 return interfacePrivate
->name
;
5464 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5466 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5468 if (!isA_SCNetworkInterface(interface
)) {
5469 _SCErrorSet(kSCStatusInvalidArgument
);
5473 if (interfacePrivate
->name
== NULL
) {
5474 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5477 return interfacePrivate
->name
;
5482 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5484 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5486 if (!isA_SCNetworkInterface(interface
)) {
5487 _SCErrorSet(kSCStatusInvalidArgument
);
5491 if (interfacePrivate
->localized_name
== NULL
) {
5492 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5495 return interfacePrivate
->localized_name
;
5501 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5503 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5504 CFDictionaryRef overrides
= NULL
;
5506 if (interfacePrivate
->overrides
!= NULL
) {
5507 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5515 SCNetworkInterfaceGetTypeID(void)
5517 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5518 return __kSCNetworkInterfaceTypeID
;
5524 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5525 SCNetworkInterfaceRef interface
,
5526 CFStringRef defaultType
,
5527 CFDictionaryRef config
,
5530 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5533 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5534 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5536 if (defaultType
== NULL
) {
5537 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5538 if (defaultType
== NULL
) {
5543 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5550 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5551 SCNetworkSetGetSetID(set
), // set
5552 interfacePrivate
->entity_device
, // interface
5553 defaultType
); // entity
5555 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5558 // if configuration has been saved
5559 if (interfacePrivate
->unsaved
!= NULL
) {
5560 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5561 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5562 CFRelease(interfacePrivate
->unsaved
);
5563 interfacePrivate
->unsaved
= NULL
;
5569 if (config
== NULL
) {
5570 // remember that we are clearing the configuration
5571 config
= (CFDictionaryRef
)kCFNull
;
5574 if (interfacePrivate
->unsaved
== NULL
) {
5575 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5577 &kCFTypeDictionaryKeyCallBacks
,
5578 &kCFTypeDictionaryValueCallBacks
);
5580 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5583 _SCErrorSet(kSCStatusNoKey
);
5594 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5595 CFStringRef extendedType
,
5596 CFDictionaryRef config
,
5599 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5603 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5604 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5606 if (extendedType
== NULL
) {
5607 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5608 if (extendedType
== NULL
) {
5613 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5617 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5618 if (paths
!= NULL
) {
5622 n
= CFArrayGetCount(paths
);
5623 for (i
= 0; i
< n
; i
++) {
5626 path
= CFArrayGetValueAtIndex(paths
, i
);
5627 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5634 // if configuration has been saved
5635 if (interfacePrivate
->unsaved
!= NULL
) {
5636 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5637 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5638 CFRelease(interfacePrivate
->unsaved
);
5639 interfacePrivate
->unsaved
= NULL
;
5647 if (config
== NULL
) {
5648 // remember that we are clearing the configuration
5649 config
= (CFDictionaryRef
)kCFNull
;
5652 if (interfacePrivate
->unsaved
== NULL
) {
5653 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5655 &kCFTypeDictionaryKeyCallBacks
,
5656 &kCFTypeDictionaryValueCallBacks
);
5658 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5661 _SCErrorSet(kSCStatusNoKey
);
5670 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5672 CFStringRef defaultType
;
5675 if (!isA_SCNetworkInterface(interface
)) {
5676 _SCErrorSet(kSCStatusInvalidArgument
);
5680 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5681 if (defaultType
== NULL
) {
5685 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5687 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5689 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5697 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5698 CFStringRef extendedType
,
5699 CFDictionaryRef config
)
5703 if (!isA_SCNetworkInterface(interface
)) {
5704 _SCErrorSet(kSCStatusInvalidArgument
);
5708 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5712 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5714 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5716 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5724 #pragma mark SCNetworkInterface [Refresh Configuration] API
5727 #ifndef kSCEntNetRefreshConfiguration
5728 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5729 #endif // kSCEntNetRefreshConfiguration
5732 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5737 if (!isA_CFString(ifName
)) {
5738 _SCErrorSet(kSCStatusInvalidArgument
);
5742 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5743 kSCDynamicStoreDomainState
,
5745 kSCEntNetRefreshConfiguration
);
5746 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5753 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5755 CFDataRef data
= NULL
;
5757 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5758 uint32_t status
= kSCStatusOK
;
5759 CFDataRef reply
= NULL
;
5761 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5762 ok
= __SCPreferencesCreate_helper(prefs
);
5768 // serialize the interface name
5769 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5774 // have the helper "refresh" the configuration
5775 status
= kSCStatusOK
;
5777 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5778 SCHELPER_MSG_INTERFACE_REFRESH
,
5782 if (data
!= NULL
) CFRelease(data
);
5787 if (status
!= kSCStatusOK
) {
5796 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5797 _SCHelperClose(&prefsPrivate
->helper_port
);
5800 status
= kSCStatusAccessError
;
5805 _SCErrorSet(status
);
5811 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5814 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5816 if (!isA_SCNetworkInterface(interface
)) {
5817 _SCErrorSet(kSCStatusInvalidArgument
);
5821 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5822 if (ifName
== NULL
) {
5823 _SCErrorSet(kSCStatusInvalidArgument
);
5827 if (interfacePrivate
->prefs
!= NULL
) {
5828 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5829 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5831 if (prefsPrivate
->authorizationData
!= NULL
) {
5832 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5836 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5841 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5843 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5848 #pragma mark SCNetworkInterface Password APIs
5852 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5854 CFStringRef unique_id
= NULL
;
5856 if (config
!= NULL
) {
5857 CFStringRef encryption
;
5859 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5860 if (isA_CFString(encryption
) &&
5861 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5862 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5865 if (unique_id
== NULL
) {
5866 unique_id
= serviceID
;
5874 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5876 CFMutableStringRef shared_id
= NULL
;
5878 if (config
!= NULL
) {
5879 CFStringRef encryption
;
5881 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5882 if (isA_CFString(encryption
) &&
5883 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5884 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5885 if (shared_id
!= NULL
) {
5886 CFRetain(shared_id
);
5891 if (shared_id
== NULL
) {
5892 CFStringRef unique_id
;
5894 unique_id
= getPasswordID(config
, serviceID
);
5895 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5896 CFStringAppend(shared_id
, CFSTR(".SS"));
5904 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5906 CFMutableStringRef xauth_id
= NULL
;
5908 if (config
!= NULL
) {
5909 CFStringRef encryption
;
5911 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
5912 if (isA_CFString(encryption
) &&
5913 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
5914 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
5915 if (xauth_id
!= NULL
) {
5921 if (xauth_id
== NULL
) {
5922 CFStringRef unique_id
;
5924 unique_id
= getPasswordID(config
, serviceID
);
5925 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5926 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
5934 checkInterfacePassword(SCNetworkInterfaceRef interface
,
5935 SCNetworkInterfacePasswordType passwordType
,
5936 SCPreferencesRef
*prefs
,
5937 CFStringRef
*serviceID
)
5939 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5941 if (!isA_SCNetworkInterface(interface
)) {
5945 *serviceID
= interfacePrivate
->serviceID
;
5946 if (*serviceID
== NULL
) {
5950 *prefs
= interfacePrivate
->prefs
;
5951 if (*prefs
== NULL
) {
5955 switch (passwordType
) {
5956 case kSCNetworkInterfacePasswordTypePPP
: {
5957 CFStringRef interfaceType
;
5959 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5960 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5968 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5969 CFStringRef interfaceType
;
5971 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5972 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5973 interface
= SCNetworkInterfaceGetInterface(interface
);
5974 if (interface
!= NULL
) {
5975 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5976 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
5977 // if PPP->L2TP interface
5981 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5982 // if IPSec interface
5989 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5993 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5994 CFStringRef interfaceType
;
5996 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5997 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5998 // if IPSec interface
6005 case kSCNetworkInterfacePasswordTypeVPN
: {
6006 CFStringRef interfaceType
;
6008 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6009 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6025 _SCErrorSet(kSCStatusInvalidArgument
);
6031 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6032 SCNetworkInterfacePasswordType passwordType
)
6034 Boolean exists
= FALSE
;
6035 SCPreferencesRef prefs
= NULL
;
6036 CFStringRef serviceID
= NULL
;
6038 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6042 switch (passwordType
) {
6043 case kSCNetworkInterfacePasswordTypePPP
: {
6044 CFDictionaryRef config
;
6045 CFStringRef unique_id
;
6047 // get configuration
6048 config
= SCNetworkInterfaceGetConfiguration(interface
);
6051 unique_id
= getPasswordID(config
, serviceID
);
6054 exists
= __extract_password(prefs
,
6056 kSCPropNetPPPAuthPassword
,
6057 kSCPropNetPPPAuthPasswordEncryption
,
6058 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6064 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6065 CFDictionaryRef config
;
6067 CFStringRef shared_id
;
6069 // get configuration
6070 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6072 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6074 config
= SCNetworkInterfaceGetConfiguration(interface
);
6077 // get sharedSecret ID
6078 shared_id
= copySharedSecretID(config
, serviceID
);
6081 exists
= __extract_password(prefs
,
6083 kSCPropNetIPSecSharedSecret
,
6084 kSCPropNetIPSecSharedSecretEncryption
,
6085 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6088 CFRelease(shared_id
);
6092 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6093 CFDictionaryRef config
;
6094 CFStringRef unique_id
= NULL
;
6096 // get configuration
6097 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6099 // get 802.1X identifier
6100 if (config
!= NULL
) {
6101 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6103 if (!isA_CFString(unique_id
)) {
6108 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6112 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6113 CFDictionaryRef config
;
6114 CFStringRef xauth_id
;
6116 // get configuration
6117 config
= SCNetworkInterfaceGetConfiguration(interface
);
6120 xauth_id
= copyXAuthID(config
, serviceID
);
6123 exists
= __extract_password(prefs
,
6125 kSCPropNetIPSecXAuthPassword
,
6126 kSCPropNetIPSecXAuthPasswordEncryption
,
6127 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6130 CFRelease(xauth_id
);
6134 case kSCNetworkInterfacePasswordTypeVPN
: {
6135 CFDictionaryRef config
;
6138 // get configuration
6139 config
= SCNetworkInterfaceGetConfiguration(interface
);
6142 vpn_id
= getPasswordID(config
, serviceID
);
6145 exists
= __extract_password(prefs
,
6147 kSCPropNetVPNAuthPassword
,
6148 kSCPropNetVPNAuthPasswordEncryption
,
6149 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6156 _SCErrorSet(kSCStatusInvalidArgument
);
6165 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6166 SCNetworkInterfacePasswordType passwordType
)
6168 CFDataRef password
= NULL
;
6169 SCPreferencesRef prefs
= NULL
;
6170 CFStringRef serviceID
= NULL
;
6172 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6176 switch (passwordType
) {
6177 case kSCNetworkInterfacePasswordTypePPP
: {
6178 CFDictionaryRef config
;
6179 CFStringRef unique_id
;
6181 // get configuration
6182 config
= SCNetworkInterfaceGetConfiguration(interface
);
6185 unique_id
= getPasswordID(config
, serviceID
);
6188 (void) __extract_password(prefs
,
6190 kSCPropNetPPPAuthPassword
,
6191 kSCPropNetPPPAuthPasswordEncryption
,
6192 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6198 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6199 CFDictionaryRef config
;
6201 CFStringRef shared_id
;
6203 // get configuration
6204 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6206 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6208 config
= SCNetworkInterfaceGetConfiguration(interface
);
6211 // get sharedSecret ID
6212 shared_id
= copySharedSecretID(config
, serviceID
);
6215 (void) __extract_password(prefs
,
6217 kSCPropNetIPSecSharedSecret
,
6218 kSCPropNetIPSecSharedSecretEncryption
,
6219 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6223 CFRelease(shared_id
);
6227 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6228 CFDictionaryRef config
;
6229 CFStringRef unique_id
= NULL
;
6231 // get configuration
6232 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6234 // get 802.1X identifier
6235 if (config
!= NULL
) {
6236 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6238 if (!isA_CFString(unique_id
)) {
6239 _SCErrorSet(kSCStatusFailed
);
6244 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6248 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6249 CFDictionaryRef config
;
6250 CFStringRef xauth_id
;
6252 // get configuration
6253 config
= SCNetworkInterfaceGetConfiguration(interface
);
6256 xauth_id
= copyXAuthID(config
, serviceID
);
6259 (void) __extract_password(prefs
,
6261 kSCPropNetIPSecXAuthPassword
,
6262 kSCPropNetIPSecXAuthPasswordEncryption
,
6263 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6266 CFRelease(xauth_id
);
6270 case kSCNetworkInterfacePasswordTypeVPN
: {
6271 CFDictionaryRef config
;
6274 // get configuration
6275 config
= SCNetworkInterfaceGetConfiguration(interface
);
6278 vpn_id
= getPasswordID(config
, serviceID
);
6281 (void) __extract_password(prefs
,
6283 kSCPropNetVPNAuthPassword
,
6284 kSCPropNetVPNAuthPasswordEncryption
,
6285 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6292 _SCErrorSet(kSCStatusInvalidArgument
);
6301 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6302 SCNetworkInterfacePasswordType passwordType
)
6305 SCPreferencesRef prefs
= NULL
;
6306 CFStringRef serviceID
= NULL
;
6308 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6312 switch (passwordType
) {
6313 case kSCNetworkInterfacePasswordTypePPP
: {
6314 CFDictionaryRef config
;
6315 CFDictionaryRef newConfig
= NULL
;
6316 CFStringRef unique_id
;
6318 // get configuration
6319 config
= SCNetworkInterfaceGetConfiguration(interface
);
6322 unique_id
= getPasswordID(config
, serviceID
);
6325 ok
= __remove_password(prefs
,
6327 kSCPropNetPPPAuthPassword
,
6328 kSCPropNetPPPAuthPasswordEncryption
,
6329 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6333 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6334 if (newConfig
!= NULL
) CFRelease(newConfig
);
6340 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6341 CFDictionaryRef config
;
6343 CFDictionaryRef newConfig
= NULL
;
6344 CFStringRef shared_id
;
6346 // get configuration
6347 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6349 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6351 config
= SCNetworkInterfaceGetConfiguration(interface
);
6354 // get sharedSecret ID
6355 shared_id
= copySharedSecretID(config
, serviceID
);
6358 ok
= __remove_password(prefs
,
6360 kSCPropNetIPSecSharedSecret
,
6361 kSCPropNetIPSecSharedSecretEncryption
,
6362 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6367 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6371 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6374 if (newConfig
!= NULL
) CFRelease(newConfig
);
6377 CFRelease(shared_id
);
6381 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6382 CFDictionaryRef config
;
6383 CFStringRef unique_id
= NULL
;
6385 // get configuration
6386 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6388 // get 802.1X identifier
6389 if (config
!= NULL
) {
6390 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6392 if (!isA_CFString(unique_id
)) {
6393 _SCErrorSet(kSCStatusFailed
);
6398 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6402 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6403 CFDictionaryRef config
;
6404 CFDictionaryRef newConfig
= NULL
;
6405 CFStringRef xauth_id
;
6407 // get configuration
6408 config
= SCNetworkInterfaceGetConfiguration(interface
);
6411 xauth_id
= copyXAuthID(config
, serviceID
);
6414 ok
= __remove_password(prefs
,
6416 kSCPropNetIPSecXAuthPassword
,
6417 kSCPropNetIPSecXAuthPasswordEncryption
,
6418 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6422 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6423 if (newConfig
!= NULL
) CFRelease(newConfig
);
6426 CFRelease(xauth_id
);
6430 case kSCNetworkInterfacePasswordTypeVPN
: {
6431 CFDictionaryRef config
;
6432 CFDictionaryRef newConfig
= NULL
;
6435 // get configuration
6436 config
= SCNetworkInterfaceGetConfiguration(interface
);
6439 vpn_id
= getPasswordID(config
, serviceID
);
6442 ok
= __remove_password(prefs
,
6444 kSCPropNetVPNAuthPassword
,
6445 kSCPropNetVPNAuthPasswordEncryption
,
6446 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6450 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6451 if (newConfig
!= NULL
) CFRelease(newConfig
);
6457 _SCErrorSet(kSCStatusInvalidArgument
);
6466 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6467 SCNetworkInterfacePasswordType passwordType
,
6469 CFDictionaryRef options
)
6471 CFStringRef account
= NULL
;
6472 CFDictionaryRef config
;
6473 CFStringRef description
= NULL
;
6474 CFStringRef label
= NULL
;
6476 SCPreferencesRef prefs
= NULL
;
6477 CFStringRef serviceID
= NULL
;
6479 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6483 switch (passwordType
) {
6484 case kSCNetworkInterfacePasswordTypePPP
: {
6485 SCNetworkServiceRef service
= NULL
;
6486 CFStringRef unique_id
;
6488 // get configuration
6489 config
= SCNetworkInterfaceGetConfiguration(interface
);
6492 unique_id
= getPasswordID(config
, serviceID
);
6494 // get "Account", "Name", "Kind"
6495 if (config
!= NULL
) {
6496 // auth name --> keychain "Account"
6497 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6499 // PPP [user defined] "name" --> keychain "Name"
6500 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6503 if (label
== NULL
) {
6504 // service name --> keychain "Name"
6505 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6510 label
= SCNetworkServiceGetName(service
);
6511 if (label
== NULL
) {
6512 // interface name --> keychain "Name"
6513 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6517 if (bundle
!= NULL
) {
6518 // "PPP Password" --> keychain "Kind"
6519 description
= CFBundleCopyLocalizedString(bundle
,
6520 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6521 CFSTR("PPP Password"),
6526 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6528 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6529 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6534 CFMutableDictionaryRef newConfig
;
6536 if (config
!= NULL
) {
6537 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6539 newConfig
= CFDictionaryCreateMutable(NULL
,
6541 &kCFTypeDictionaryKeyCallBacks
,
6542 &kCFTypeDictionaryValueCallBacks
);
6544 CFDictionarySetValue(newConfig
,
6545 kSCPropNetPPPAuthPassword
,
6547 CFDictionarySetValue(newConfig
,
6548 kSCPropNetPPPAuthPasswordEncryption
,
6549 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6550 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6551 CFRelease(newConfig
);
6554 if (description
!= NULL
) CFRelease(description
);
6555 if (service
!= NULL
) CFRelease(service
);
6559 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6560 CFDictionaryRef baseConfig
= NULL
;
6562 SCNetworkServiceRef service
= NULL
;
6563 CFStringRef shared_id
;
6565 // get configuration
6566 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6567 config
= SCNetworkInterfaceGetConfiguration(interface
);
6569 baseConfig
= config
;
6570 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6573 // get sharedSecret ID
6574 shared_id
= copySharedSecretID(config
, serviceID
);
6576 // get "Account", "Name", "Kind"
6577 if (config
!= NULL
) {
6578 CFStringRef localIdentifier
;
6579 CFStringRef localIdentifierType
;
6581 if (CFDictionaryGetValueIfPresent(config
,
6582 kSCPropNetIPSecLocalIdentifierType
,
6583 (const void **)&localIdentifierType
)
6584 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6585 && CFDictionaryGetValueIfPresent(config
,
6586 kSCPropNetIPSecLocalIdentifier
,
6587 (const void **)&localIdentifier
)
6588 && isA_CFString(localIdentifier
)) {
6589 // local identifier --> keychain "Account"
6590 account
= localIdentifier
;
6593 // PPP [user defined] "name" --> keychain "Name"
6595 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6597 if (baseConfig
!= NULL
) {
6598 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6603 if (label
== NULL
) {
6604 // service name --> keychain "Name"
6605 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6610 label
= SCNetworkServiceGetName(service
);
6611 if (label
== NULL
) {
6612 // interface name --> keychain "Name"
6613 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6617 if (bundle
!= NULL
) {
6618 // "IPSec Shared Secret" --> keychain "Kind"
6619 description
= CFBundleCopyLocalizedString(bundle
,
6620 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6621 CFSTR("IPSec Shared Secret"),
6626 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6628 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6629 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6634 CFMutableDictionaryRef newConfig
= NULL
;
6636 if (config
!= NULL
) {
6637 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6639 newConfig
= CFDictionaryCreateMutable(NULL
,
6641 &kCFTypeDictionaryKeyCallBacks
,
6642 &kCFTypeDictionaryValueCallBacks
);
6644 CFDictionarySetValue(newConfig
,
6645 kSCPropNetIPSecSharedSecret
,
6647 CFDictionarySetValue(newConfig
,
6648 kSCPropNetIPSecSharedSecretEncryption
,
6649 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6651 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6655 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6657 CFRelease(newConfig
);
6660 if (description
!= NULL
) CFRelease(description
);
6661 if (service
!= NULL
) CFRelease(service
);
6662 CFRelease(shared_id
);
6666 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6667 CFStringRef account
= NULL
;
6668 CFStringRef unique_id
= NULL
;
6670 // get configuration
6671 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6673 // get 802.1X identifier
6674 if (config
!= NULL
) {
6675 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6676 unique_id
= isA_CFString(unique_id
);
6678 if (unique_id
!= NULL
) {
6679 CFRetain(unique_id
);
6683 uuid
= CFUUIDCreate(NULL
);
6684 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6688 // 802.1x UserName --> keychain "Account"
6689 if (config
!= NULL
) {
6690 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6693 // get "Name", "Kind"
6694 if (bundle
!= NULL
) {
6695 CFStringRef interface_name
;
6697 // "Network Connection (%@)" --> keychain "Name"
6698 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6699 if (interface_name
!= NULL
) {
6700 CFStringRef label_fmt
;
6702 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6703 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6704 CFSTR("Network Connection (%@)"),
6706 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6707 CFRelease(label_fmt
);
6709 label
= CFBundleCopyLocalizedString(bundle
,
6710 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6711 CFSTR("Network Connection"),
6715 // "802.1X Password" --> keychain "Kind"
6716 description
= CFBundleCopyLocalizedString(bundle
,
6717 CFSTR("KEYCHAIN_KIND_EAPOL"),
6718 CFSTR("802.1X Password"),
6723 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6725 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6726 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6731 CFMutableDictionaryRef newConfig
= NULL
;
6733 if (config
!= NULL
) {
6734 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6736 newConfig
= CFDictionaryCreateMutable(NULL
,
6738 &kCFTypeDictionaryKeyCallBacks
,
6739 &kCFTypeDictionaryValueCallBacks
);
6741 CFDictionarySetValue(newConfig
,
6742 kEAPClientPropUserPasswordKeychainItemID
,
6744 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6747 CFRelease(newConfig
);
6750 CFRelease(unique_id
);
6751 if (label
!= NULL
) CFRelease(label
);
6752 if (description
!= NULL
) CFRelease(description
);
6756 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6757 SCNetworkServiceRef service
= NULL
;
6758 CFStringRef xauth_id
;
6760 // get configuration
6761 config
= SCNetworkInterfaceGetConfiguration(interface
);
6764 xauth_id
= copyXAuthID(config
, serviceID
);
6766 // get "Account", "Name", "Kind"
6767 if (config
!= NULL
) {
6768 // auth name --> keychain "Account"
6769 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6771 // IPSec [user defined] "name" --> keychain "Name"
6772 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6775 if (label
== NULL
) {
6776 // service name --> keychain "Name"
6777 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6782 label
= SCNetworkServiceGetName(service
);
6783 if (label
== NULL
) {
6784 // interface name --> keychain "Name"
6785 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6789 if (bundle
!= NULL
) {
6790 // "IPSec XAuth Password" --> keychain "Kind"
6791 description
= CFBundleCopyLocalizedString(bundle
,
6792 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6793 CFSTR("IPSec XAuth Password"),
6798 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6800 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6801 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6806 CFMutableDictionaryRef newConfig
;
6808 if (config
!= NULL
) {
6809 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6811 newConfig
= CFDictionaryCreateMutable(NULL
,
6813 &kCFTypeDictionaryKeyCallBacks
,
6814 &kCFTypeDictionaryValueCallBacks
);
6816 CFDictionarySetValue(newConfig
,
6817 kSCPropNetIPSecXAuthPassword
,
6819 CFDictionarySetValue(newConfig
,
6820 kSCPropNetIPSecXAuthPasswordEncryption
,
6821 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6822 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6823 CFRelease(newConfig
);
6826 CFRelease(xauth_id
);
6827 if (description
!= NULL
) CFRelease(description
);
6828 if (service
!= NULL
) CFRelease(service
);
6832 case kSCNetworkInterfacePasswordTypeVPN
: {
6833 SCNetworkServiceRef service
= NULL
;
6836 // get configuration
6837 config
= SCNetworkInterfaceGetConfiguration(interface
);
6840 vpn_id
= getPasswordID(config
, serviceID
);
6842 // get "Account", "Name", "Kind"
6843 if (config
!= NULL
) {
6844 // auth name --> keychain "Account"
6845 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6847 // VPN [user defined] "name" --> keychain "Name"
6848 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6851 if (label
== NULL
) {
6852 // service name --> keychain "Name"
6853 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6858 label
= SCNetworkServiceGetName(service
);
6859 if (label
== NULL
) {
6860 // interface name --> keychain "Name"
6861 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6865 if (bundle
!= NULL
) {
6866 // "VPN Password" --> keychain "Kind"
6867 description
= CFBundleCopyLocalizedString(bundle
,
6868 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6869 CFSTR("VPN Password"),
6874 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6876 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6877 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6882 CFMutableDictionaryRef newConfig
;
6884 if (config
!= NULL
) {
6885 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6887 newConfig
= CFDictionaryCreateMutable(NULL
,
6889 &kCFTypeDictionaryKeyCallBacks
,
6890 &kCFTypeDictionaryValueCallBacks
);
6892 CFDictionarySetValue(newConfig
,
6893 kSCPropNetVPNAuthPassword
,
6895 CFDictionarySetValue(newConfig
,
6896 kSCPropNetVPNAuthPasswordEncryption
,
6897 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6898 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6899 CFRelease(newConfig
);
6902 if (description
!= NULL
) CFRelease(description
);
6903 if (service
!= NULL
) CFRelease(service
);
6908 _SCErrorSet(kSCStatusInvalidArgument
);
6917 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
6921 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
6923 CFMutableDictionaryRef info
;
6924 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6927 if (interface
== NULL
) {
6931 info
= CFDictionaryCreateMutable(NULL
,
6933 &kCFTypeDictionaryKeyCallBacks
,
6934 &kCFTypeDictionaryValueCallBacks
);
6936 // add non-localized interface name
6937 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
6939 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
6943 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
6944 #if !TARGET_OS_SIMULATOR
6945 if (interfacePrivate
->usb
.name
!= NULL
) {
6946 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
6948 if (interfacePrivate
->usb
.vid
!= NULL
) {
6949 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
6951 if (interfacePrivate
->usb
.pid
!= NULL
) {
6952 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
6954 #endif // !TARGET_OS_SIMULATOR
6957 if (CFDictionaryGetCount(info
) == 0) {
6958 // do not return an empty dictionary
6967 SCNetworkInterfaceRef
6968 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
6970 SCNetworkInterfaceRef interface
= NULL
;
6972 /* initialize runtime */
6973 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6975 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
6976 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
6977 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
6978 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
6986 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
6988 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6990 return interfacePrivate
->configurationAction
;
6995 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
6997 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6999 return interfacePrivate
->address
;
7004 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7006 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7008 return interfacePrivate
->prefix
;
7013 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7015 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7017 return interfacePrivate
->type
;
7022 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7024 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7026 return interfacePrivate
->unit
;
7031 update_ift_family(SCNetworkInterfaceRef interface
)
7033 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7035 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7037 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7038 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7041 bzero(&ifr
, sizeof(ifr
));
7042 if ((bsdName
!= NULL
) &&
7043 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7046 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7048 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7049 ifr
.ifr_type
.ift_family
= 0;
7050 ifr
.ifr_type
.ift_subfamily
= 0;
7056 interfacePrivate
->family
= CFNumberCreate(NULL
,
7057 kCFNumberSInt32Type
,
7058 &ifr
.ifr_type
.ift_family
);
7059 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7060 kCFNumberSInt32Type
,
7061 &ifr
.ifr_type
.ift_subfamily
);
7067 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7069 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7071 // note: family not in IORegistry, fetch with ioctl()
7073 if (interfacePrivate
->family
== NULL
) {
7074 update_ift_family(interface
);
7077 return interfacePrivate
->family
;
7082 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7084 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7086 // note: subfamily not in IORegistry, fetch with ioctl()
7088 if (interfacePrivate
->subfamily
== NULL
) {
7089 update_ift_family(interface
);
7092 return interfacePrivate
->subfamily
;
7097 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7099 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7101 return interfacePrivate
->path
;
7106 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7108 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7110 return interfacePrivate
->entryID
;
7116 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7118 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7120 return interfacePrivate
->active
;
7125 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7127 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7129 return interfacePrivate
->builtin
;
7134 #pragma mark SCNetworkInterface SPIs
7137 #if !TARGET_OS_EMBEDDED
7139 SCNetworkInterfaceRef
7140 _SCNetworkInterfaceCopyBTPANInterface(void)
7142 CFDictionaryRef dict
;
7143 SCNetworkInterfaceRef interface
= NULL
;
7146 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7147 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7151 CFStringRef if_name
;
7152 SCNetworkInterfacePrivateRef interfacePrivate
;
7154 if (isA_CFDictionary(dict
) &&
7155 CFDictionaryGetValueIfPresent(dict
,
7156 kInterfaceNamerKey_BT_PAN_Name
,
7157 (const void **)&if_name
) &&
7158 isA_CFString(if_name
)) {
7159 CFMutableDictionaryRef entity
;
7161 entity
= CFDictionaryCreateMutable(NULL
,
7163 &kCFTypeDictionaryKeyCallBacks
,
7164 &kCFTypeDictionaryValueCallBacks
);
7165 CFDictionarySetValue(entity
,
7166 kSCPropNetInterfaceType
,
7167 kSCValNetInterfaceTypeEthernet
);
7168 CFDictionarySetValue(entity
,
7169 kSCPropNetInterfaceDeviceName
,
7171 CFDictionarySetValue(entity
,
7172 kSCPropUserDefinedName
,
7173 CFSTR(BT_PAN_NAME
));
7174 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7178 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7180 if ((interfacePrivate
!= NULL
) &&
7181 (interfacePrivate
->address
== NULL
) &&
7182 CFDictionaryGetValueIfPresent(dict
,
7183 kInterfaceNamerKey_BT_PAN_Mac
,
7184 (const void **)&addr
) &&
7186 interfacePrivate
->address
= CFRetain(addr
);
7194 #endif // !TARGET_OS_EMBEDDED
7198 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7200 io_registry_entry_t device
;
7201 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7202 CFStringRef device_path
= NULL
;
7203 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7205 CFStringRef match_keys
[2];
7206 CFTypeRef match_vals
[2];
7207 CFDictionaryRef match_dict
;
7208 CFDictionaryRef matching
;
7210 if (interfacePrivate
->entity_device
== NULL
) {
7214 if (interfacePrivate
->entity_device_unique
== NULL
) {
7218 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7219 match_vals
[0] = interfacePrivate
->entity_device
;
7220 match_dict
= CFDictionaryCreate(NULL
,
7221 (const void **)match_keys
,
7222 (const void **)match_vals
,
7224 &kCFTypeDictionaryKeyCallBacks
,
7225 &kCFTypeDictionaryValueCallBacks
);
7227 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7228 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7229 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7230 match_vals
[1] = match_dict
;
7231 matching
= CFDictionaryCreate(NULL
,
7232 (const void **)match_keys
,
7233 (const void **)match_vals
,
7234 sizeof(match_keys
)/sizeof(match_keys
[0]),
7235 &kCFTypeDictionaryKeyCallBacks
,
7236 &kCFTypeDictionaryValueCallBacks
);
7237 CFRelease(match_dict
);
7239 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7240 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7241 if (kr
!= kIOReturnSuccess
) {
7242 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7246 while ((device_path
== NULL
) &&
7247 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7248 CFDictionaryRef overrides
;
7250 overrides
= IORegistryEntrySearchCFProperty(device
,
7252 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7254 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7255 if (overrides
!= NULL
) {
7256 CFDictionaryRef modemOverrides
;
7258 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7259 if (modemOverrides
!= NULL
) {
7260 CFRetain(modemOverrides
);
7262 CFRelease(overrides
);
7263 overrides
= modemOverrides
;
7265 if (overrides
== NULL
) {
7266 overrides
= IORegistryEntrySearchCFProperty(device
,
7268 CFSTR("DeviceModemOverrides"),
7270 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7272 if (overrides
!= NULL
) {
7273 if (isA_CFDictionary(overrides
)) {
7274 CFStringRef matchIdentifier
;
7276 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7277 if (isA_CFString(matchIdentifier
) &&
7278 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7279 device_path
= IORegistryEntryCreateCFProperty(device
,
7280 CFSTR(kIOTTYDeviceKey
),
7285 CFRelease(overrides
);
7287 IOObjectRelease(device
);
7290 IOObjectRelease(device_iterator
);
7294 if (device_path
== NULL
) {
7295 // if we haven't found an exact match to our UniqueIdentifier
7296 // so we simply return the base name.
7297 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7298 if (device_path
!= NULL
) {
7299 CFRetain(device_path
);
7311 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7313 #if !TARGET_OS_SIMULATOR
7314 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7316 if (!interfacePrivate
->hidden
) {
7317 // if not HiddenConfiguration
7321 if ((interfacePrivate
->overrides
== NULL
) ||
7322 (!CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) &&
7323 !CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7324 // if no [IPv4/IPv6] configuration overrides
7328 if (interfacePrivate
->builtin
) {
7329 // if built-in (and overrides are present)
7333 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7336 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7337 (vid
== kIOUSBVendorIDAppleComputer
)) {
7338 // if Apple interface (and overrides are present)
7342 #endif // !TARGET_OS_SIMULATOR
7349 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7351 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7353 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7358 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7360 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7362 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7367 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7369 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7371 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7376 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7378 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7380 return interfacePrivate
->hidden
;
7385 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
7387 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7389 return interfacePrivate
->modemIsV92
;
7394 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7396 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7398 return (interfacePrivate
->sort_order
== kSortTethered
);
7403 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7405 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7406 CFStringRef interfaceType
;
7408 if (!isA_SCNetworkInterface(interface
)) {
7412 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7413 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7418 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7419 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7421 // if an empty bridge
7425 for (i
= 0; i
< n
; i
++) {
7426 SCNetworkInterfaceRef member
;
7427 SCNetworkInterfacePrivateRef memberPrivate
;
7429 member
= CFArrayGetValueAtIndex(members
, i
);
7430 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7431 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7436 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7440 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7448 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7450 CFDictionaryRef policy
;
7452 if (!isA_SCNetworkInterface(interface
)) {
7453 _SCErrorSet(kSCStatusInvalidArgument
);
7457 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7458 if (policy
== NULL
) {
7459 _SCErrorSet(kSCStatusOK
);
7466 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7470 if (!isA_SCNetworkInterface(interface
)) {
7471 _SCErrorSet(kSCStatusInvalidArgument
);
7475 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7477 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7479 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7487 #pragma mark SCNetworkInterface [internal] SPIs
7491 SCNetworkInterfacePrivateRef
7492 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7493 SCNetworkInterfaceRef interface
,
7494 SCPreferencesRef prefs
,
7495 CFStringRef serviceID
)
7497 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7498 SCNetworkInterfacePrivateRef newPrivate
;
7500 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7501 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7503 if (interface
== kSCNetworkInterfaceIPv4
) {
7504 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7507 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7508 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7509 if (oldPrivate
->interface
!= NULL
) {
7510 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7511 oldPrivate
->interface
, // interface
7512 prefs
, // [new] prefs
7513 serviceID
); // [new] serviceID
7515 if (oldPrivate
->name
!= NULL
) {
7516 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7518 if (oldPrivate
->prefix
!= NULL
) {
7519 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7521 if (oldPrivate
->localized_name
!= NULL
) {
7522 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7524 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7525 if (oldPrivate
->localized_arg1
!= NULL
) {
7526 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7528 if (oldPrivate
->localized_arg2
!= NULL
) {
7529 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7531 if (oldPrivate
->unsaved
!= NULL
) {
7532 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7534 if (oldPrivate
->entity_device
!= NULL
) {
7535 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7537 if (oldPrivate
->entity_device_unique
!= NULL
) {
7538 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7540 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7541 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7542 if (oldPrivate
->supported_interface_types
!= NULL
) {
7543 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7545 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7546 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7548 if (oldPrivate
->address
!= NULL
) {
7549 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7551 newPrivate
->builtin
= oldPrivate
->builtin
;
7552 if (oldPrivate
->configurationAction
!= NULL
) {
7553 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7555 newPrivate
->hidden
= oldPrivate
->hidden
;
7556 if (oldPrivate
->location
!= NULL
) {
7557 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7559 if (oldPrivate
->path
!= NULL
) {
7560 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7562 newPrivate
->entryID
= oldPrivate
->entryID
;
7563 if (oldPrivate
->overrides
!= NULL
) {
7564 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7566 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
7567 if (oldPrivate
->type
!= NULL
) {
7568 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7570 if (oldPrivate
->unit
!= NULL
) {
7571 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7573 if (oldPrivate
->family
!= NULL
) {
7574 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7576 if (oldPrivate
->subfamily
!= NULL
) {
7577 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7579 if (oldPrivate
->usb
.name
!= NULL
) {
7580 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7582 if (oldPrivate
->usb
.vid
!= NULL
) {
7583 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7585 if (oldPrivate
->usb
.pid
!= NULL
) {
7586 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7588 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7590 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7591 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7592 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7594 if (oldPrivate
->bond
.mode
!= NULL
) {
7595 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7597 if (oldPrivate
->bond
.options
!= NULL
) {
7598 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7601 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7602 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7603 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7605 if (oldPrivate
->bridge
.options
!= NULL
) {
7606 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7609 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7610 if (oldPrivate
->vlan
.interface
!= NULL
) {
7611 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7613 if (oldPrivate
->vlan
.tag
!= NULL
) {
7614 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7616 if (oldPrivate
->vlan
.options
!= NULL
) {
7617 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7626 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7628 CFMutableArrayRef configs
;
7630 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7632 while (interface
!= NULL
) {
7633 CFStringRef defaultType
;
7634 CFMutableDictionaryRef interfaceConfiguration
;
7636 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7638 &kCFTypeDictionaryKeyCallBacks
,
7639 &kCFTypeDictionaryValueCallBacks
);
7641 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7642 if (defaultType
!= NULL
) {
7643 CFDictionaryRef config
;
7644 CFArrayRef extendedTypes
;
7647 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7649 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7651 if (config
== NULL
) {
7652 config
= (CFDictionaryRef
)kCFNull
;
7654 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7656 extendedTypes
= extendedConfigurationTypes(interface
);
7657 if (extendedTypes
!= NULL
) {
7661 n
= CFArrayGetCount(extendedTypes
);
7662 for (i
= 0; i
< n
; i
++) {
7663 CFStringRef extendedType
;
7665 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7666 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7667 if (config
== NULL
) {
7668 config
= (CFDictionaryRef
)kCFNull
;
7670 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7673 CFRelease(extendedTypes
);
7677 CFArrayAppendValue(configs
, interfaceConfiguration
);
7678 CFRelease(interfaceConfiguration
);
7680 interface
= SCNetworkInterfaceGetInterface(interface
);
7687 __private_extern__ Boolean
7688 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7690 CFArrayRef interfaces
;
7691 Boolean match
= FALSE
;
7692 CFMutableSetRef members
;
7694 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7696 #if !TARGET_OS_IPHONE
7697 // add Bond [member] interfaces
7698 interfaces
= SCBondInterfaceCopyAll(prefs
);
7699 if (interfaces
!= NULL
) {
7700 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7701 CFRelease(interfaces
);
7703 #endif // !TARGET_OS_IPHONE
7705 // add Bridge [member] interfaces
7706 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7707 if (interfaces
!= NULL
) {
7708 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7709 CFRelease(interfaces
);
7712 if (CFSetGetCount(members
) == 0) {
7716 while (interface
!= NULL
) {
7717 match
= CFSetContainsValue(members
, interface
);
7719 // if the interface is a member of an
7720 // Ethernet Bond or Bridge
7724 interface
= SCNetworkInterfaceGetInterface(interface
);
7736 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7740 for (i
= 0; interface
!= NULL
; i
++) {
7741 CFStringRef defaultType
;
7742 CFDictionaryRef interfaceConfiguration
;
7745 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7747 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7748 if (defaultType
!= NULL
) {
7749 CFDictionaryRef config
;
7750 CFArrayRef extendedTypes
;
7752 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7754 if (config
== (CFDictionaryRef
)kCFNull
) {
7758 // if service is not associated with the set
7759 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
7761 // apply default configuration to this set
7762 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
7765 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7768 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7770 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7775 extendedTypes
= extendedConfigurationTypes(interface
);
7776 if (extendedTypes
!= NULL
) {
7780 n
= CFArrayGetCount(extendedTypes
);
7781 for (j
= 0; j
< n
; j
++) {
7782 CFStringRef extendedType
;
7784 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7785 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7787 if (config
== (CFDictionaryRef
)kCFNull
) {
7790 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
7792 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7795 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7797 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7803 CFRelease(extendedTypes
);
7807 interface
= SCNetworkInterfaceGetInterface(interface
);
7814 SCNetworkInterfaceRef
7815 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
7817 SCNetworkInterfaceRef interface
;
7819 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
7820 if (interface
== NULL
) {
7824 if (store
!= NULL
) {
7825 SCNetworkInterfacePrivateRef interfacePrivate
=
7826 (SCNetworkInterfacePrivateRef
)interface
;
7829 interfacePrivate
->store
= store
;
7836 #if !TARGET_OS_SIMULATOR
7837 SCNetworkServicePrimaryRank
7838 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7840 IPMonitorControlRef control
;
7841 SCNetworkInterfacePrivateRef interfacePrivate
=
7842 (SCNetworkInterfacePrivateRef
)interface
;
7843 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
7845 control
= interfacePrivate
->IPMonitorControl
;
7846 if (control
!= NULL
) {
7849 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7850 if (ifName
!= NULL
) {
7851 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
7855 _SCErrorSet(kSCStatusInvalidArgument
);
7862 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7863 SCNetworkServicePrimaryRank newRank
)
7865 IPMonitorControlRef control
;
7866 SCNetworkInterfacePrivateRef interfacePrivate
=
7867 (SCNetworkInterfacePrivateRef
)interface
;
7870 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7871 if (ifName
== NULL
) {
7872 _SCErrorSet(kSCStatusInvalidArgument
);
7875 control
= interfacePrivate
->IPMonitorControl
;
7876 if (control
== NULL
) {
7877 control
= IPMonitorControlCreate();
7878 if (control
== NULL
) {
7879 _SCErrorSet(kSCStatusFailed
);
7882 interfacePrivate
->IPMonitorControl
= control
;
7884 return IPMonitorControlSetInterfacePrimaryRank(control
,
7890 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7892 Boolean disable_until_needed
= FALSE
;
7893 CFNumberRef disable_prop
= NULL
;
7894 CFIndex interfaceIndex
;
7895 SCNetworkInterfacePrivateRef interfacePrivate
7896 = (SCNetworkInterfacePrivateRef
)interface
;
7897 CFArrayRef path_list
;
7899 if (interfacePrivate
->prefs
== NULL
) {
7900 _SCErrorSet(kSCStatusInvalidArgument
);
7903 interfaceIndex
= findPerInterfaceConfiguration(interface
);
7904 if (interfaceIndex
== kCFNotFound
) {
7905 _SCErrorSet(kSCStatusInvalidArgument
);
7908 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7909 if (path_list
!= NULL
) {
7910 CFDictionaryRef config
;
7911 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
7913 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7914 CFRelease(path_list
);
7915 if (config
!= NULL
) {
7918 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
7919 disable_prop
= isA_CFNumber(disable_prop
);
7920 if (disable_prop
!= NULL
) {
7921 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
7922 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
7925 /* invalid property, ignore it */
7926 disable_prop
= NULL
;
7931 if (disable_prop
== NULL
) {
7932 disable_until_needed
7933 = _SCNetworkInterfaceIsTethered(interface
);
7935 _SCErrorSet(kSCStatusOK
);
7936 return (disable_until_needed
);
7940 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
7944 CFIndex interfaceIndex
;
7945 SCNetworkInterfacePrivateRef interfacePrivate
7946 = (SCNetworkInterfacePrivateRef
)interface
;
7948 CFArrayRef path_list
;
7950 if (interfacePrivate
->prefs
== NULL
) {
7951 _SCErrorSet(kSCStatusInvalidArgument
);
7954 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
7955 _SCErrorSet(kSCStatusInvalidArgument
);
7958 interfaceIndex
= findPerInterfaceConfiguration(interface
);
7959 if (interfaceIndex
== kCFNotFound
) {
7960 _SCErrorSet(kSCStatusInvalidArgument
);
7963 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7964 if (path_list
== NULL
) {
7965 _SCErrorSet(kSCStatusInvalidArgument
);
7968 count
= CFArrayGetCount(path_list
);
7969 for (i
= 0; i
< count
; i
++) {
7970 CFDictionaryRef config
;
7971 CFMutableDictionaryRef new_config
;
7972 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
7974 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7975 if (config
!= NULL
) {
7977 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7980 = CFDictionaryCreateMutable(NULL
, 0,
7981 &kCFTypeDictionaryKeyCallBacks
,
7982 &kCFTypeDictionaryValueCallBacks
);
7984 if (disable
!= NULL
) {
7985 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
7987 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
7989 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
,
7991 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
7993 CFRelease(new_config
);
7998 CFRelease(path_list
);
8003 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8010 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8011 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8017 #else // !TARGET_OS_SIMULATOR
8019 SCNetworkServicePrimaryRank
8020 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8022 return (kSCNetworkServicePrimaryRankDefault
);
8026 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8027 SCNetworkServicePrimaryRank newRank
)
8029 _SCErrorSet(kSCStatusInvalidArgument
);
8034 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8040 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8046 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8048 _SCErrorSet(kSCStatusInvalidArgument
);
8052 #endif // !TARGET_OS_SIMULATOR
8056 CFArrayRef
// SCNetworkInterfaceRef
8057 __SCNetworkInterfaceCopyStoredWithPreferences (SCPreferencesRef ni_prefs
)
8059 CFMutableArrayRef interfaceList
= NULL
;
8061 SCNetworkInterfaceRef interfaceNamer
= NULL
;
8062 CFStringRef defaultNetworkInterfacePath
= NULL
;
8064 /* initialize runtime */
8065 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8067 if (ni_prefs
== NULL
) {
8068 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8069 assert(defaultNetworkInterfacePath
!= NULL
);
8070 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8073 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8075 if (isA_CFArray(if_list
) != NULL
) {
8077 CFIndex n
= CFArrayGetCount(if_list
);
8079 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8080 for (i
= 0; i
< n
; i
++) {
8081 CFDictionaryRef dict
;
8083 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8084 if (isA_CFDictionary(dict
) != NULL
) {
8085 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
, ni_prefs
);
8087 if (interfaceNamer
!= NULL
) {
8088 CFArrayAppendValue(interfaceList
, interfaceNamer
);
8089 CFRelease(interfaceNamer
);
8095 if (defaultNetworkInterfacePath
!= NULL
) {
8096 CFRelease(defaultNetworkInterfacePath
);
8097 // prefs were created in the function, and hence need to be released
8098 CFRelease(ni_prefs
);
8100 return interfaceList
;
8106 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
8108 CFStringRef defaultNetworkInterfacePath
= NULL
;
8109 Boolean success
= FALSE
;
8111 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
8112 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8113 assert(defaultNetworkInterfacePath
!= NULL
);
8114 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8117 if (isA_CFArray(interfacesToSave
) == NULL
) {
8118 SC_log(LOG_INFO
, "No interfaces to save");
8121 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
8124 if (defaultNetworkInterfacePath
!= NULL
) {
8125 CFRelease(defaultNetworkInterfacePath
);
8126 // prefs were created in the function, and hence need to be released
8134 SCNetworkInterfaceRef
8135 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8138 SCNetworkInterfaceRef interface
= NULL
;
8139 CFStringRef defaultNetworkInterfacePath
;
8141 /* initialize runtime */
8142 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8144 if (ni_prefs
== NULL
) {
8145 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8146 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8147 CFRelease(defaultNetworkInterfacePath
);
8153 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8155 if (isA_CFArray(if_list
) != NULL
) {
8157 CFIndex count
= CFArrayGetCount(if_list
);
8159 for (idx
= 0; idx
< count
; idx
++) {
8160 CFDictionaryRef dict
;
8161 CFStringRef tmp_bsdName
;
8163 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8164 if (isA_CFDictionary(dict
) == NULL
) {
8168 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8169 if (tmp_bsdName
== NULL
) {
8172 if (CFEqual(bsdName
, tmp_bsdName
)) {
8173 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
, ni_prefs
);
8179 CFRelease(ni_prefs
);
8185 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8187 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8188 CFStringRef bsdName
= NULL
;
8189 SCNetworkInterfaceRef interface
= NULL
;
8192 count
= CFArrayGetCount(interfaces
);
8194 SC_log(LOG_INFO
, "No interfaces");
8197 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8199 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8200 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8202 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8203 if (isA_CFString(bsdName
) == NULL
) {
8204 SC_log(LOG_INFO
, "No BSD name");
8207 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8209 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8210 CFRelease(mappingBSDToInterface
);
8211 mappingBSDToInterface
= NULL
;
8212 SC_log(LOG_INFO
, "No mappings");
8215 return mappingBSDToInterface
;
8218 __private_extern__ Boolean
8219 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8221 CFStringRef intfSubtype
;
8223 if (entity
== NULL
) {
8227 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8228 #pragma GCC diagnostic push
8229 #pragma GCC diagnostic ignored "-Wdeprecated"
8230 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8233 #pragma GCC diagnostic pop