2 * Copyright (c) 2004-2016 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"
45 #include <EAP8021X/EAPClientProperties.h>
46 #else // !TARGET_OS_IPHONE
47 #ifndef kEAPClientPropUserName
48 #define kEAPClientPropUserName CFSTR("UserName")
50 #ifndef kEAPClientPropUserPasswordKeychainItemID
51 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
53 #endif // !TARGET_OS_IPHONE
55 #include <IOKit/IOKitLib.h>
56 #include <IOKit/IOCFBundle.h>
57 #include <IOKit/IOBSD.h>
58 #include <IOKit/network/IONetworkController.h>
59 #include <IOKit/network/IONetworkInterface.h>
60 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
61 #include <IOKit/serial/IOSerialKeys.h>
62 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
63 #if !TARGET_OS_SIMULATOR
64 #include <IOKit/usb/IOUSBLib.h>
65 #endif // !TARGET_OS_SIMULATOR
67 #include "dy_framework.h"
69 #ifndef kIODeviceSupportsHoldKey
70 #define kIODeviceSupportsHoldKey "V92Modem"
73 #ifndef kPCIThunderboltString
74 #define kPCIThunderboltString "PCI-Thunderbolt"
77 #ifndef kIOUserEthernetInterfaceRoleKey
78 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
83 #include <mach/mach.h>
85 #include <net/if_types.h>
86 #include <net/if_dl.h>
87 #include <net/route.h>
88 #include <sys/ioctl.h>
89 #include <sys/param.h>
90 #include <sys/types.h>
91 #include <sys/socket.h>
93 #include <sys/sysctl.h>
98 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
99 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
100 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
101 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
102 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
103 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
122 kSortBluetoothPAN_GN
,
123 kSortBluetoothPAN_NAP
,
133 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
134 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
135 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
136 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
137 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
138 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
139 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
140 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
141 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
142 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
143 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
144 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
145 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
146 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
147 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
148 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
149 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
150 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
152 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
154 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
155 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
156 .sort_order
= kSortUnknown
, // sort_order
159 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
161 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
162 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
163 .sort_order
= kSortUnknown
, // sort_order
166 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
168 static CFMutableSetRef vendor_interface_types
= NULL
;
171 #pragma mark SCNetworkInterface configuration details
180 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
185 #define doProxies 1<<4
186 #if !TARGET_OS_IPHONE
188 #else // !TARGET_OS_IPHONE
190 #endif // !TARGET_OS_IPHONE
192 static const struct {
193 const CFStringRef
*interface_type
;
194 const CFStringRef
*entity_hardware
;
195 Boolean per_interface_config
;
196 uint32_t supported_interfaces
;
197 const CFStringRef
*ppp_subtype
;
198 uint32_t supported_protocols
;
199 } configurations
[] = {
200 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
201 // ===================================== ==================== ========== =============== ======================================= =========================================
202 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
203 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
204 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
205 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
206 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
207 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
208 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
209 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
210 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
211 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
212 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
213 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
214 #pragma GCC diagnostic push
215 #pragma GCC diagnostic ignored "-Wdeprecated"
216 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
217 #pragma GCC diagnostic pop
218 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
219 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
220 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
221 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
222 // ===================================== =================== ========== =============== ======================================= =========================================
223 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
224 // ===================================== =================== ========== =============== ======================================= =========================================
225 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
229 #define kSCNetworkInterfaceActive "Active"
230 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
231 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
232 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
233 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
234 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
235 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
236 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
237 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
238 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
241 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
242 static CFBundleRef bundle
= NULL
;
245 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
248 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
250 "SCNetworkInterface", // className
253 __SCNetworkInterfaceDeallocate
, // dealloc
254 __SCNetworkInterfaceEqual
, // equal
255 __SCNetworkInterfaceHash
, // hash
256 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
257 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
261 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
262 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
263 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
266 static mach_port_t masterPort
= MACH_PORT_NULL
;
269 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
271 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
275 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
277 CFAllocatorRef allocator
= CFGetAllocator(cf
);
278 CFMutableStringRef result
;
279 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
281 result
= CFStringCreateMutable(allocator
, 0);
282 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
283 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
284 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
285 if (interfacePrivate
->entity_device_unique
!= NULL
) {
286 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
288 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
289 if (interfacePrivate
->entity_subtype
!= NULL
) {
290 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
292 if (interfacePrivate
->name
!= NULL
) {
293 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
295 if (interfacePrivate
->localized_name
!= NULL
) {
296 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
298 if (interfacePrivate
->localized_key
!= NULL
) {
299 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
300 if (interfacePrivate
->localized_arg1
!= NULL
) {
301 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
303 if (interfacePrivate
->localized_arg2
!= NULL
) {
304 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
308 if (interfacePrivate
->address
!= NULL
) {
313 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
315 data
= CFDataGetBytePtr(interfacePrivate
->address
);
316 dataLen
= CFDataGetLength(interfacePrivate
->address
);
317 for (i
= 0; i
< dataLen
; i
++) {
318 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
323 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
324 if (interfacePrivate
->hidden
) {
325 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
327 if (interfacePrivate
->modemIsV92
) {
328 CFStringAppendFormat(result
, NULL
, CFSTR(", v.92"));
330 if (interfacePrivate
->location
!= NULL
) {
331 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
333 if (interfacePrivate
->path
!= NULL
) {
334 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
336 if (interfacePrivate
->entryID
!= 0) {
337 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
339 if (interfacePrivate
->type
!= NULL
) {
340 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
342 if (interfacePrivate
->unit
!= NULL
) {
343 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
345 if (interfacePrivate
->family
!= NULL
) {
346 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
348 if (interfacePrivate
->subfamily
!= NULL
) {
349 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
351 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
355 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
356 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
359 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
360 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
364 if (interfacePrivate
->usb
.name
!= NULL
) {
365 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
366 interfacePrivate
->usb
.name
);
369 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
373 if (interfacePrivate
->configurationAction
!= NULL
) {
374 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
376 if (interfacePrivate
->overrides
!= NULL
) {
377 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %p"), interfacePrivate
->overrides
);
379 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d"), interfacePrivate
->sort_order
);
380 if (interfacePrivate
->prefs
!= NULL
) {
381 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
383 if (interfacePrivate
->serviceID
!= NULL
) {
384 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
386 if (interfacePrivate
->interface
!= NULL
) {
387 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
389 if (interfacePrivate
->unsaved
!= NULL
) {
390 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
393 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
397 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
398 for (i
= 0; i
< n
; i
++) {
399 SCNetworkInterfaceRef member
;
401 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
402 CFStringAppendFormat(result
, NULL
,
404 (i
== 0) ? ", interfaces = " : ",",
405 SCNetworkInterfaceGetBSDName(member
));
408 if (interfacePrivate
->bond
.mode
!= NULL
) {
409 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
411 if (interfacePrivate
->bond
.options
!= NULL
) {
414 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
415 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
419 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
423 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
424 for (i
= 0; i
< n
; i
++) {
425 SCNetworkInterfaceRef member
;
427 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
428 CFStringAppendFormat(result
, NULL
,
430 (i
== 0) ? ", interfaces = " : ",",
431 SCNetworkInterfaceGetBSDName(member
));
434 if (interfacePrivate
->bridge
.options
!= NULL
) {
437 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
438 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
442 if (interfacePrivate
->vlan
.interface
!= NULL
) {
443 CFStringAppendFormat(result
, NULL
,
444 CFSTR(", interface = %@"),
445 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
447 if (interfacePrivate
->vlan
.tag
!= NULL
) {
448 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
450 if (interfacePrivate
->vlan
.options
!= NULL
) {
453 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
454 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
458 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
465 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
467 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
469 /* release resources */
471 if (interfacePrivate
->name
!= NULL
)
472 CFRelease(interfacePrivate
->name
);
474 if (interfacePrivate
->localized_name
!= NULL
)
475 CFRelease(interfacePrivate
->localized_name
);
477 if (interfacePrivate
->localized_arg1
!= NULL
)
478 CFRelease(interfacePrivate
->localized_arg1
);
480 if (interfacePrivate
->localized_arg2
!= NULL
)
481 CFRelease(interfacePrivate
->localized_arg2
);
483 if (interfacePrivate
->interface
!= NULL
)
484 CFRelease(interfacePrivate
->interface
);
486 if (interfacePrivate
->prefs
!= NULL
)
487 CFRelease(interfacePrivate
->prefs
);
489 if (interfacePrivate
->store
!= NULL
)
490 CFRelease(interfacePrivate
->store
);
492 if (interfacePrivate
->serviceID
!= NULL
)
493 CFRelease(interfacePrivate
->serviceID
);
495 if (interfacePrivate
->unsaved
!= NULL
)
496 CFRelease(interfacePrivate
->unsaved
);
498 if (interfacePrivate
->entity_device
!= NULL
)
499 CFRelease(interfacePrivate
->entity_device
);
501 if (interfacePrivate
->entity_device_unique
!= NULL
)
502 CFRelease(interfacePrivate
->entity_device_unique
);
504 if (interfacePrivate
->supported_interface_types
!= NULL
)
505 CFRelease(interfacePrivate
->supported_interface_types
);
507 if (interfacePrivate
->supported_protocol_types
!= NULL
)
508 CFRelease(interfacePrivate
->supported_protocol_types
);
510 if (interfacePrivate
->address
!= NULL
)
511 CFRelease(interfacePrivate
->address
);
513 if (interfacePrivate
->addressString
!= NULL
)
514 CFRelease(interfacePrivate
->addressString
);
516 if (interfacePrivate
->configurationAction
!= NULL
)
517 CFRelease(interfacePrivate
->configurationAction
);
519 if (interfacePrivate
->location
!= NULL
)
520 CFRelease(interfacePrivate
->location
);
522 if (interfacePrivate
->path
!= NULL
)
523 CFRelease(interfacePrivate
->path
);
525 if (interfacePrivate
->overrides
!= NULL
)
526 CFRelease(interfacePrivate
->overrides
);
528 if (interfacePrivate
->prefix
!= NULL
)
529 CFRelease(interfacePrivate
->prefix
);
531 if (interfacePrivate
->type
!= NULL
)
532 CFRelease(interfacePrivate
->type
);
534 if (interfacePrivate
->unit
!= NULL
)
535 CFRelease(interfacePrivate
->unit
);
537 if (interfacePrivate
->family
!= NULL
)
538 CFRelease(interfacePrivate
->family
);
540 if (interfacePrivate
->subfamily
!= NULL
)
541 CFRelease(interfacePrivate
->subfamily
);
543 if (interfacePrivate
->usb
.name
!= NULL
)
544 CFRelease(interfacePrivate
->usb
.name
);
546 if (interfacePrivate
->usb
.pid
!= NULL
)
547 CFRelease(interfacePrivate
->usb
.pid
);
549 if (interfacePrivate
->usb
.vid
!= NULL
)
550 CFRelease(interfacePrivate
->usb
.vid
);
552 if (interfacePrivate
->bond
.interfaces
!= NULL
)
553 CFRelease(interfacePrivate
->bond
.interfaces
);
555 if (interfacePrivate
->bond
.mode
!= NULL
)
556 CFRelease(interfacePrivate
->bond
.mode
);
558 if (interfacePrivate
->bond
.options
!= NULL
)
559 CFRelease(interfacePrivate
->bond
.options
);
561 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
562 CFRelease(interfacePrivate
->bridge
.interfaces
);
564 if (interfacePrivate
->bridge
.options
!= NULL
)
565 CFRelease(interfacePrivate
->bridge
.options
);
567 if (interfacePrivate
->vlan
.interface
!= NULL
)
568 CFRelease(interfacePrivate
->vlan
.interface
);
570 if (interfacePrivate
->vlan
.tag
!= NULL
)
571 CFRelease(interfacePrivate
->vlan
.tag
);
573 if (interfacePrivate
->vlan
.options
!= NULL
)
574 CFRelease(interfacePrivate
->vlan
.options
);
575 #if !TARGET_OS_SIMULATOR
576 if (interfacePrivate
->IPMonitorControl
!= NULL
)
577 CFRelease(interfacePrivate
->IPMonitorControl
);
578 #endif // !TARGET_OS_SIMULATOR
584 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
586 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
587 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
592 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
593 return FALSE
; // if not the same interface type
596 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
597 return FALSE
; // if not the same device
600 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
601 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
602 return FALSE
; // if not the same device unique identifier
604 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
608 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
609 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
610 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
611 return FALSE
; // if same device but not the same display name
615 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
616 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
617 return FALSE
; // if not the same interfaces
619 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
620 return FALSE
; // if not the same mode
624 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
625 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
626 return FALSE
; // if not the same interfaces
630 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
631 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
632 return FALSE
; // if not the same physical interface
634 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
635 return FALSE
; // if not the same tag
639 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
640 return FALSE
; // if not the same layering
648 __SCNetworkInterfaceHash(CFTypeRef cf
)
651 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
653 if (interfacePrivate
->entity_device
!= NULL
) {
654 if (interfacePrivate
->entity_device_unique
== NULL
) {
655 hash
= CFHash(interfacePrivate
->entity_device
);
659 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
660 interfacePrivate
->entity_device
,
661 interfacePrivate
->entity_device_unique
);
672 __SCNetworkInterfaceInitialize(void)
677 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
679 // initialize __kSCNetworkInterfaceIPv4
680 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
681 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
682 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
684 // initialize __kSCNetworkInterfaceLoopback
685 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
686 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
687 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
688 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
689 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
691 // get CFBundleRef for SystemConfiguration.framework
692 bundle
= _SC_CFBundleGet();
694 // get mach port used to communication with IOKit
695 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
696 if (kr
!= kIOReturnSuccess
) {
697 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
705 SCNetworkInterfacePrivateRef
706 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
707 SCNetworkInterfaceRef interface
,
708 SCPreferencesRef prefs
,
709 CFStringRef serviceID
)
711 SCNetworkInterfacePrivateRef interfacePrivate
;
714 /* initialize runtime */
715 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
717 /* allocate target */
718 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
719 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
720 __kSCNetworkInterfaceTypeID
,
723 if (interfacePrivate
== NULL
) {
727 /* initialize non-zero/NULL members */
728 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
729 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
730 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
731 interfacePrivate
->sort_order
= kSortUnknown
;
733 return interfacePrivate
;
739 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
743 struct if_msghdr
* ifm
;
744 char * if_name
= NULL
;
745 unsigned int if_index
;
747 Boolean vlanOK
= FALSE
;
749 // get the interface index
750 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
751 if (if_name
== NULL
) {
752 return FALSE
; // if conversion error
754 if_index
= if_nametoindex(if_name
);
756 goto done
; // if unknown interface
759 // get information for the specified interface
764 mib
[4] = NET_RT_IFLIST
;
765 mib
[5] = if_index
; /* ask for exactly one interface */
767 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
768 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
771 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
772 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
773 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
777 // check the link type and hwassist flags
778 // ALIGN: buf is aligned
779 ifm
= (struct if_msghdr
*)(void *)buf
;
780 switch (ifm
->ifm_type
) {
782 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
783 struct if_data
*if_data
= &ifm
->ifm_data
;
785 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
795 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
796 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
803 __SCCopyMacAddress(CFStringRef ifname
)
805 struct ifaddrs
*ifap
;
806 char ifname_c
[IFNAMSIZ
];
808 CFDataRef macAddress
= NULL
;
810 if(_SC_cfstring_to_cstring(ifname
,
813 kCFStringEncodingUTF8
) == NULL
) {
817 if (getifaddrs(&ifap
) == -1) {
819 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
823 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
824 struct sockaddr_dl
*sdl
;
826 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
830 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
831 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
832 if (sdl
->sdl_family
!= AF_LINK
) {
836 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
845 SCNetworkInterfacePrivateRef
846 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
849 SCNetworkInterfacePrivateRef interfacePrivate
;
851 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
852 if (interfacePrivate
== NULL
) {
856 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
857 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
858 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
859 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
860 interfacePrivate
->builtin
= TRUE
;
861 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
862 interfacePrivate
->sort_order
= kSortBond
;
864 interfacePrivate
->localized_key
= CFSTR("bond");
865 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
867 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
868 // interfacePrivate->bond.mode = NULL;
869 // interfacePrivate->bond.options = NULL;
871 return interfacePrivate
;
876 SCNetworkInterfacePrivateRef
877 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
878 CFStringRef bridge_if
)
880 SCNetworkInterfacePrivateRef interfacePrivate
;
882 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
883 if (interfacePrivate
== NULL
) {
887 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
888 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
889 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
890 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
891 interfacePrivate
->builtin
= TRUE
;
892 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
893 interfacePrivate
->sort_order
= kSortBridge
;
895 interfacePrivate
->localized_key
= CFSTR("bridge");
896 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
898 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
899 // interfacePrivate->bridge.options = NULL;
901 return interfacePrivate
;
906 SCNetworkInterfacePrivateRef
907 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
910 SCNetworkInterfacePrivateRef interfacePrivate
;
912 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
913 if (interfacePrivate
== NULL
) {
917 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
918 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
919 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
920 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
921 interfacePrivate
->builtin
= TRUE
;
922 interfacePrivate
->sort_order
= kSortVLAN
;
924 interfacePrivate
->localized_key
= CFSTR("vlan");
925 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
927 // interfacePrivate->vlan.interface = NULL;
928 // interfacePrivate->vlan.tag = NULL;
929 // interfacePrivate->vlan.options = NULL;
931 return interfacePrivate
;
936 #pragma mark Interface ordering
939 static CF_RETURNS_RETAINED CFArrayRef
940 split_path(CFStringRef path
)
942 CFArrayRef components
;
943 CFMutableStringRef nPath
;
945 // turn '@'s into '/'s
946 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
947 (void) CFStringFindAndReplace(nPath
,
950 CFRangeMake(0, CFStringGetLength(nPath
)),
953 // split path into components to be compared
954 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
962 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
964 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
965 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
966 CFComparisonResult res
= kCFCompareEqualTo
;
968 /* sort by interface type */
969 if (dev1
->sort_order
!= dev2
->sort_order
) {
970 if (dev1
->sort_order
< dev2
->sort_order
) {
971 res
= kCFCompareLessThan
;
973 res
= kCFCompareGreaterThan
;
978 /* built-in interfaces sort first */
979 if (dev1
->builtin
!= dev2
->builtin
) {
981 res
= kCFCompareLessThan
;
983 res
= kCFCompareGreaterThan
;
988 /* ... and then, sort built-in interfaces by "location" */
990 if (dev1
->location
!= dev2
->location
) {
991 if (isA_CFString(dev1
->location
)) {
992 if (isA_CFString(dev2
->location
)) {
993 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
995 res
= kCFCompareLessThan
;
998 res
= kCFCompareGreaterThan
;
1001 if (res
!= kCFCompareEqualTo
) {
1007 /* ... and, then sort by IOPathMatch */
1008 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1009 CFArrayRef elements1
;
1010 CFArrayRef elements2
;
1016 elements1
= split_path(dev1
->path
);
1017 n1
= CFArrayGetCount(elements1
);
1019 elements2
= split_path(dev2
->path
);
1020 n2
= CFArrayGetCount(elements2
);
1022 n
= (n1
<= n2
) ? n1
: n2
;
1023 for (i
= 0; i
< n
; i
++) {
1032 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1033 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1035 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1037 q1
= strtoq(str
, &end
, 16);
1038 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1039 CFAllocatorDeallocate(NULL
, str
);
1042 // if e1 is a valid numeric string
1043 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1045 q2
= strtoq(str
, &end
, 16);
1046 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1047 CFAllocatorDeallocate(NULL
, str
);
1050 // if e2 is also a valid numeric string
1053 res
= kCFCompareEqualTo
;
1055 } else if (q1
< q2
) {
1056 res
= kCFCompareLessThan
;
1058 res
= kCFCompareGreaterThan
;
1064 res
= CFStringCompare(e1
, e2
, 0);
1065 if (res
!= kCFCompareEqualTo
) {
1070 if (res
== kCFCompareEqualTo
) {
1072 res
= kCFCompareLessThan
;
1073 } else if (n1
< n2
) {
1074 res
= kCFCompareGreaterThan
;
1078 CFRelease(elements1
);
1079 CFRelease(elements2
);
1081 if (res
!= kCFCompareEqualTo
) {
1086 /* ... and, then sort by BSD interface name */
1087 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1088 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1089 if (res
!= kCFCompareEqualTo
) {
1094 /* ... and lastly, sort by BSD interface unique identifier */
1095 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1096 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1097 // if (res != kCFCompareEqualTo) {
1107 sort_interfaces(CFMutableArrayRef all_interfaces
)
1111 n
= CFArrayGetCount(all_interfaces
);
1116 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1123 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1125 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1127 return interfacePrivate
->sort_order
;
1132 #pragma mark Interface details
1136 IOCopyCFStringValue(CFTypeRef ioVal
)
1138 if (isA_CFString(ioVal
)) {
1139 return CFStringCreateCopy(NULL
, ioVal
);
1142 if (isA_CFData(ioVal
)) {
1143 return CFStringCreateWithCString(NULL
,
1144 (const char *)CFDataGetBytePtr(ioVal
),
1145 kCFStringEncodingUTF8
);
1153 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1155 CFStringRef if_bsdName
;
1156 CFStringRef if_prefix
;
1157 CFNumberRef if_unit
;
1159 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1160 if (if_bsdName
!= NULL
) {
1161 return IOCopyCFStringValue(if_bsdName
);
1164 // no BSD name, get interface prefix and unit
1165 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1166 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1167 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1168 // if both prefix and unit available, construct BSD name
1169 if_bsdName
= CFStringCreateWithFormat(NULL
,
1181 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1185 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1186 return IOCopyCFStringValue(ioVal
);
1191 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1193 Boolean match
= FALSE
;
1194 CFIndex prefixLen
= CFStringGetLength(prefix
);
1195 CFStringRef str
= NULL
;
1197 if (!isA_CFString(ioVal
)) {
1198 if (isA_CFData(ioVal
)) {
1199 str
= CFStringCreateWithCStringNoCopy(NULL
,
1200 (const char *)CFDataGetBytePtr(ioVal
),
1201 kCFStringEncodingUTF8
,
1209 if ((ioVal
!= NULL
) &&
1210 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1211 (CFStringCompareWithOptions(ioVal
,
1213 CFRangeMake(0, prefixLen
),
1214 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1218 if (str
!= NULL
) CFRelease(str
);
1223 static const struct {
1224 const CFStringRef name
;
1225 const CFStringRef slot
;
1226 } slot_mappings
[] = {
1228 { CFSTR("A1") , CFSTR("1") },
1229 { CFSTR("B1") , CFSTR("2") },
1230 { CFSTR("C1") , CFSTR("3") },
1232 // Blue&White G3, Yikes G4
1233 { CFSTR("J12"), CFSTR("1") },
1234 { CFSTR("J11"), CFSTR("2") },
1235 { CFSTR("J10"), CFSTR("3") },
1236 { CFSTR("J9"), CFSTR("4") },
1239 { CFSTR("A") , CFSTR("1") },
1240 { CFSTR("B") , CFSTR("2") },
1241 { CFSTR("C") , CFSTR("3") },
1242 { CFSTR("D") , CFSTR("4") },
1244 // Digital Audio G4 (and later models)
1245 { CFSTR("1") , CFSTR("1") },
1246 { CFSTR("2") , CFSTR("2") },
1247 { CFSTR("3") , CFSTR("3") },
1248 { CFSTR("4") , CFSTR("4") },
1249 { CFSTR("5") , CFSTR("5") }
1253 static const CFStringRef slot_prefixes
[] = {
1254 CFSTR("thunderbolt slot "),
1260 static CF_RETURNS_RETAINED CFStringRef
1261 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1264 io_registry_entry_t parent
;
1265 CFMutableStringRef slot
;
1266 CFTypeRef slot_name
;
1269 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1271 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1272 if (slot_name
!= NULL
) {
1275 slot
= CFStringCreateMutable(NULL
, 0);
1276 if (isA_CFString(slot_name
)) {
1277 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1278 CFStringAppend(slot
, slot_name
);
1279 } else if (isA_CFData(slot_name
)) {
1280 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1281 CFStringAppendCString(slot
,
1282 (const char *)CFDataGetBytePtr(slot_name
),
1283 kCFStringEncodingUTF8
);
1286 for (i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1289 len
= CFStringGetLength(slot_prefixes
[i
]);
1290 if (CFStringGetLength(slot
) > len
) {
1291 (void) CFStringFindAndReplace(slot
,
1294 CFRangeMake(0, len
),
1295 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1299 for (i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1300 if (CFStringCompare(slot
,
1301 slot_mappings
[i
].name
,
1302 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1304 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1309 CFRelease(slot_name
);
1312 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1314 case kIOReturnSuccess
: {
1315 CFTypeRef parent_pci_slot_name
= NULL
;
1316 CFStringRef parent_slot
;
1318 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1319 if (parent_slot
!= NULL
) {
1320 if (slot
!= NULL
) CFRelease(slot
);
1321 slot
= (CFMutableStringRef
)parent_slot
;
1323 if (pci_slot_name
!= NULL
) {
1324 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1325 *pci_slot_name
= parent_pci_slot_name
;
1327 CFRelease(parent_pci_slot_name
);
1331 IOObjectRelease(parent
);
1334 case kIOReturnNoDevice
:
1335 // if we have hit the root node
1338 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1346 static CFComparisonResult
1347 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1349 CFStringRef bsd1
= (CFStringRef
)val1
;
1350 CFStringRef bsd2
= (CFStringRef
)val2
;
1352 return CFStringCompare(bsd1
, bsd2
, 0);
1356 static CF_RETURNS_RETAINED CFStringRef
1357 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1360 CFStringRef port_name
= NULL
;
1361 CFMutableArrayRef port_names
;
1364 CFStringRef match_keys
[2];
1365 CFTypeRef match_vals
[2];
1366 CFDictionaryRef match_dict
;
1367 CFDictionaryRef matching
;
1368 io_registry_entry_t slot
;
1369 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1371 match_keys
[0] = CFSTR("AAPL,slot-name");
1372 match_vals
[0] = slot_name
;
1374 match_dict
= CFDictionaryCreate(NULL
,
1375 (const void **)match_keys
,
1376 (const void **)match_vals
,
1378 &kCFTypeDictionaryKeyCallBacks
,
1379 &kCFTypeDictionaryValueCallBacks
);
1381 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1382 match_vals
[0] = CFSTR("IOPCIDevice");
1384 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1385 match_vals
[1] = match_dict
;
1387 // note: the "matching" dictionary will be consumed by the following
1388 matching
= CFDictionaryCreate(NULL
,
1389 (const void **)match_keys
,
1390 (const void **)match_vals
,
1391 sizeof(match_keys
)/sizeof(match_keys
[0]),
1392 &kCFTypeDictionaryKeyCallBacks
,
1393 &kCFTypeDictionaryValueCallBacks
);
1394 CFRelease(match_dict
);
1396 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1397 if (kr
!= kIOReturnSuccess
) {
1398 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1399 return MACH_PORT_NULL
;
1402 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1404 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1405 io_registry_entry_t child
;
1406 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1408 kr
= IORegistryEntryCreateIterator(slot
,
1410 kIORegistryIterateRecursively
,
1412 if (kr
!= kIOReturnSuccess
) {
1413 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1414 CFRelease(port_names
);
1415 return MACH_PORT_NULL
;
1418 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1419 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1420 CFMutableDictionaryRef interface_dict
= NULL
;
1422 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1423 if (interface_dict
!= NULL
) {
1424 CFNumberRef child_if_type
;
1425 int child_ift
= ift
;
1427 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1428 if (child_if_type
!= NULL
) {
1429 if (!isA_CFNumber(child_if_type
) ||
1430 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1431 // assume that it's a match
1436 if (ift
== child_ift
) {
1437 CFStringRef if_bsdName
;
1439 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1440 if (if_bsdName
!= NULL
) {
1441 CFArrayAppendValue(port_names
, if_bsdName
);
1442 CFRelease(if_bsdName
);
1446 CFRelease(interface_dict
);
1449 IOObjectRelease(child
);
1451 IOObjectRelease(child_iterator
);
1452 IOObjectRelease(slot
);
1454 IOObjectRelease(slot_iterator
);
1456 n
= CFArrayGetCount(port_names
);
1458 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1459 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1460 if (n
!= kCFNotFound
) {
1461 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1465 CFRelease(port_names
);
1471 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1473 CFStringRef bsd_name
= NULL
;
1474 CFMutableDictionaryRef interface_dict
= NULL
;
1476 CFTypeRef pci_slot_name
;
1481 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1482 if (interface_dict
!= NULL
) {
1483 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1484 CFRelease(interface_dict
);
1487 if (bsd_name
== NULL
) {
1491 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1492 if (*slot_name
!= NULL
) {
1493 if (pci_slot_name
!= NULL
) {
1494 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1495 CFRelease(pci_slot_name
);
1500 CFRelease(bsd_name
);
1506 isBuiltin(io_registry_entry_t interface
)
1510 slot
= pci_slot(interface
, NULL
);
1512 // interfaces which have a "slot" are not built-in
1522 isBluetoothBuiltin(Boolean
*haveController
)
1524 Boolean builtin
= FALSE
;
1525 io_object_t hciController
;
1526 io_iterator_t iter
= MACH_PORT_NULL
;
1529 kr
= IOServiceGetMatchingServices(masterPort
,
1530 IOServiceMatching("IOBluetoothHCIController"),
1532 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1533 if (kr
!= kIOReturnSuccess
) {
1534 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1536 *haveController
= FALSE
;
1539 *haveController
= TRUE
;
1541 hciController
= IOIteratorNext(iter
);
1542 IOObjectRelease(iter
);
1543 if(hciController
!= MACH_PORT_NULL
) {
1544 #if !TARGET_OS_SIMULATOR
1545 CFNumberRef idVendor
;
1547 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1548 if (idVendor
!= NULL
) {
1551 if (isA_CFNumber(idVendor
) &&
1552 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1553 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1557 CFRelease(idVendor
);
1559 #endif // !TARGET_OS_SIMULATOR
1561 IOObjectRelease(hciController
);
1569 isThunderbolt(io_registry_entry_t interface
)
1573 val
= IORegistryEntrySearchCFProperty(interface
,
1575 CFSTR(kPCIThunderboltString
),
1577 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1588 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1589 io_registry_entry_t interface
,
1590 CFDictionaryRef interface_dict
,
1591 io_registry_entry_t controller
,
1592 CFDictionaryRef controller_dict
,
1593 io_registry_entry_t bus
,
1594 CFDictionaryRef bus_dict
)
1596 #if !TARGET_OS_SIMULATOR
1598 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1600 CFSTR(kUSBProductString
),
1602 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1603 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1605 CFSTR(kUSBVendorID
),
1607 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1608 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1610 CFSTR(kUSBProductID
),
1612 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1613 #endif // !TARGET_OS_SIMULATOR
1620 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1621 io_registry_entry_t interface
,
1624 Boolean updated
= FALSE
;
1627 // check if a "Product Name" has been provided
1628 val
= IORegistryEntrySearchCFProperty(interface
,
1630 CFSTR(kIOPropertyProductNameKey
),
1632 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1633 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1634 // else, use "USB Product Name" if available
1635 val
= CFRetain(interfacePrivate
->usb
.name
);
1638 CFStringRef productName
;
1640 productName
= IOCopyCFStringValue(val
);
1643 if (productName
!= NULL
) {
1644 if (CFStringGetLength(productName
) > 0) {
1645 // if we have a [somewhat reasonable?] product name
1646 if (interfacePrivate
->name
!= NULL
) {
1647 CFRelease(interfacePrivate
->name
);
1649 interfacePrivate
->name
= CFRetain(productName
);
1650 if (interfacePrivate
->localized_name
!= NULL
) {
1651 CFRelease(interfacePrivate
->localized_name
);
1652 interfacePrivate
->localized_name
= NULL
;
1654 if (bundle
!= NULL
) {
1655 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1661 CFRelease(productName
);
1670 #pragma mark Interface enumeration
1673 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1674 io_registry_entry_t interface
,
1675 CFDictionaryRef interface_dict
,
1676 io_registry_entry_t controller
,
1677 CFDictionaryRef controller_dict
,
1678 io_registry_entry_t bus
,
1679 CFDictionaryRef bus_dict
);
1683 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1684 io_registry_entry_t interface
,
1685 CFStringRef override
)
1690 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1691 val
= IORegistryEntrySearchCFProperty(interface
,
1695 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1698 if (isA_CFDictionary(val
)) {
1699 if (interfacePrivate
->overrides
== NULL
) {
1700 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1702 &kCFTypeDictionaryKeyCallBacks
,
1703 &kCFTypeDictionaryValueCallBacks
);
1705 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1714 #define BT_PAN_NAME "Bluetooth PAN"
1715 #define BT_PAN_MAC BT_PAN_NAME " (MAC)"
1718 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1719 io_registry_entry_t interface
,
1720 CFDictionaryRef interface_dict
,
1721 io_registry_entry_t controller
,
1722 CFDictionaryRef controller_dict
,
1723 io_registry_entry_t bus
,
1724 CFDictionaryRef bus_dict
)
1734 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1735 if (isA_CFNumber(num
) &&
1736 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1737 interfacePrivate
->type
= CFRetain(num
);
1739 SC_log(LOG_INFO
, "no interface type");
1747 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1748 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1749 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1750 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1751 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1752 interfacePrivate
->sort_order
= kSortAirPort
;
1753 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1754 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1755 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1756 interfacePrivate
->sort_order
= kSortThunderbolt
;
1757 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1758 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1759 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1760 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1761 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1762 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1763 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1764 interfacePrivate
->sort_order
= kSortTethered
;
1765 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1766 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1767 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1768 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1771 if (interfacePrivate
->interface_type
== NULL
) {
1772 val
= IORegistryEntrySearchCFProperty(interface
,
1774 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1776 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1778 if (isA_CFString(val
)) {
1779 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1780 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1781 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1782 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1783 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1784 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1785 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1786 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1787 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1788 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1789 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1790 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1798 if (interfacePrivate
->interface_type
== NULL
) {
1799 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1801 if (CFEqual(str
, CFSTR("radio"))) {
1802 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1803 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1804 interfacePrivate
->sort_order
= kSortOtherWireless
;
1811 if (interfacePrivate
->interface_type
== NULL
) {
1812 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1813 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1814 interfacePrivate
->sort_order
= kSortEthernet
;
1816 // BOND support only enabled for ethernet devices
1817 interfacePrivate
->supportsBond
= TRUE
;
1820 // enable Bridge support
1821 interfacePrivate
->supportsBridge
= TRUE
;
1824 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1826 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1829 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1831 interfacePrivate
->builtin
= isBuiltin(interface
);
1834 if (!interfacePrivate
->builtin
&&
1835 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1836 // always treat AirPort interfaces as built-in
1837 interfacePrivate
->builtin
= TRUE
;
1841 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1842 if ((interfacePrivate
->location
!= NULL
) &&
1843 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1844 CFRelease(interfacePrivate
->location
);
1845 interfacePrivate
->location
= NULL
;
1849 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1850 if (isA_CFNumber(num
) &&
1851 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1852 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1853 interfacePrivate
->supportsVLAN
= TRUE
;
1858 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1859 interfacePrivate
->localized_key
= CFSTR("airport");
1860 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1861 if ((interfacePrivate
->location
== NULL
) ||
1862 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1863 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1865 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1866 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1868 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1869 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1870 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1871 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1872 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1873 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1874 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1875 interfacePrivate
->localized_key
= CFSTR("wireless");
1876 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1877 } else if (interfacePrivate
->builtin
) {
1878 if ((interfacePrivate
->location
== NULL
) ||
1879 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1880 interfacePrivate
->localized_key
= CFSTR("ether");
1882 interfacePrivate
->localized_key
= CFSTR("multiether");
1883 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1886 CFStringRef provider
;
1888 // check provider class
1889 provider
= IORegistryEntrySearchCFProperty(interface
,
1891 CFSTR(kIOProviderClassKey
),
1893 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1894 if (provider
!= NULL
) {
1895 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1896 CFStringRef port_name
;
1897 CFStringRef slot_name
;
1899 // set interface "name"
1900 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1901 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1902 if (isThunderbolt(interface
)) {
1903 if (port_name
== NULL
) {
1904 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1905 interfacePrivate
->localized_arg1
= slot_name
;
1907 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1908 interfacePrivate
->localized_arg1
= slot_name
;
1909 interfacePrivate
->localized_arg2
= port_name
;
1913 if (port_name
== NULL
) {
1914 interfacePrivate
->localized_key
= CFSTR("pci-ether");
1915 interfacePrivate
->localized_arg1
= slot_name
;
1917 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
1918 interfacePrivate
->localized_arg1
= slot_name
;
1919 interfacePrivate
->localized_arg2
= port_name
;
1924 io_registry_entry_t node
= interface
;
1926 while (provider
!= NULL
) {
1927 #if !TARGET_OS_SIMULATOR
1928 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
1929 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
))) {
1930 // get USB info (if available)
1931 processUSBInterface(interfacePrivate
,
1939 // set interface "name"
1940 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
1941 interfacePrivate
->localized_key
= CFSTR("usb-ether");
1942 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1946 #endif // !TARGET_OS_SIMULATOR
1948 if (node
== interface
) {
1950 } else if (node
== controller
) {
1956 CFRelease(provider
);
1957 provider
= IORegistryEntrySearchCFProperty(node
,
1959 CFSTR(kIOProviderClassKey
),
1961 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1964 if (interfacePrivate
->localized_key
== NULL
) {
1965 update_interface_name(interfacePrivate
, interface
, FALSE
);
1969 if (provider
!= NULL
) CFRelease(provider
);
1972 if (interfacePrivate
->localized_key
== NULL
) {
1973 // if no provider, not a PCI device, or no slot information
1974 interfacePrivate
->localized_key
= CFSTR("generic-ether");
1975 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
1982 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
1985 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
1988 interfacePrivate
->builtin
= isBuiltin(interface
);
1991 interfacePrivate
->sort_order
= kSortFireWire
;
1994 if (interfacePrivate
->builtin
) {
1995 interfacePrivate
->localized_key
= CFSTR("firewire");
1997 CFStringRef port_name
;
1998 CFStringRef slot_name
;
2000 // set interface "name"
2001 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2002 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2003 if (isThunderbolt(interface
)) {
2004 if (port_name
== NULL
) {
2005 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2006 interfacePrivate
->localized_arg1
= slot_name
;
2008 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2009 interfacePrivate
->localized_arg1
= slot_name
;
2010 interfacePrivate
->localized_arg2
= port_name
;
2013 if (port_name
== NULL
) {
2014 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2015 interfacePrivate
->localized_arg1
= slot_name
;
2017 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2018 interfacePrivate
->localized_arg1
= slot_name
;
2019 interfacePrivate
->localized_arg2
= port_name
;
2027 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2032 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2034 // Hardware (MAC) address
2035 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2036 if (isA_CFData(data
)) {
2037 interfacePrivate
->address
= CFRetain(data
);
2041 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2042 if (isA_CFString(str
)) {
2043 interfacePrivate
->prefix
= CFRetain(str
);
2047 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2048 if (isA_CFNumber(num
) &&
2049 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2050 interfacePrivate
->unit
= CFRetain(num
);
2053 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2054 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2061 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2063 CFDictionaryRef dict
;
2064 CFMutableDictionaryRef newDict
;
2066 if (interfacePrivate
->overrides
== NULL
) {
2067 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2069 &kCFTypeDictionaryKeyCallBacks
,
2070 &kCFTypeDictionaryValueCallBacks
);
2073 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2075 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2077 newDict
= CFDictionaryCreateMutable(NULL
,
2079 &kCFTypeDictionaryKeyCallBacks
,
2080 &kCFTypeDictionaryValueCallBacks
);
2082 if (script
!= NULL
) {
2083 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2085 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2087 if (CFDictionaryGetCount(newDict
) > 0) {
2088 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2090 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2094 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2095 CFRelease(interfacePrivate
->overrides
);
2096 interfacePrivate
->overrides
= NULL
;
2103 is_valid_connection_script(CFStringRef script
)
2105 char ccl
[MAXPATHLEN
];
2106 char path
[MAXPATHLEN
];
2107 sysdir_search_path_enumeration_state state
;
2109 (void) _SC_cfstring_to_cstring(script
,
2112 kCFStringEncodingUTF8
);
2114 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2115 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2116 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2118 struct stat statBuf
;
2120 if (ccl
[0] == '/') {
2121 path
[0] = '\0'; // if modemCCL is a full path
2123 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2125 strlcat(path
, ccl
, sizeof(path
));
2127 if (stat(path
, &statBuf
) != 0) {
2128 if (errno
== ENOENT
) {
2132 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2135 if (S_ISREG(statBuf
.st_mode
)) {
2136 // if we have a valid CCL script
2140 #define BUNDLE_EXT ".ccl"
2141 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2146 if ((n
<= BUNDLE_EXT_LEN
) ||
2147 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2148 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2149 if (stat(path
, &statBuf
) != 0) {
2150 if (errno
== ENOENT
) {
2154 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2158 if (S_ISDIR(statBuf
.st_mode
)) {
2159 // if we have a valid CCL bundle
2169 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2170 io_registry_entry_t interface
,
2171 CFDictionaryRef interface_dict
,
2172 io_registry_entry_t controller
,
2173 CFDictionaryRef controller_dict
,
2174 io_registry_entry_t bus
,
2175 CFDictionaryRef bus_dict
)
2177 CFStringRef base
= NULL
;
2179 Boolean isModem
= FALSE
;
2180 Boolean isWWAN
= FALSE
;
2181 CFStringRef modemCCL
= NULL
;
2185 // check if initializing
2186 val
= IORegistryEntrySearchCFProperty(interface
,
2188 kSCNetworkInterfaceInitializingKey
,
2190 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2192 Boolean initializing
;
2194 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2197 return FALSE
; // if this interface is still initializing
2202 val
= IORegistryEntrySearchCFProperty(interface
,
2206 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2208 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2213 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2214 if (interfacePrivate
->entity_device
== NULL
) {
2218 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2220 base
= CFRetain(interfacePrivate
->entity_device
);
2226 * Exclude ports named "irda" because otherwise the IrDA ports on the
2227 * original iMac (rev's A through D) show up as serial ports. Given
2228 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2229 * even support it, these ports definitely shouldn't be listed.
2231 if (CFStringCompare(base
,
2233 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2237 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2238 Boolean haveController
= FALSE
;
2241 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2242 interfacePrivate
->sort_order
= kSortBluetooth
;
2243 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2244 if (!haveController
) {
2245 // if device with no controller present
2248 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2250 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2251 interfacePrivate
->sort_order
= kSortIrDA
;
2252 } else if (isWWAN
) {
2254 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2255 interfacePrivate
->sort_order
= kSortWWAN
;
2258 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2259 interfacePrivate
->sort_order
= kSortModem
;
2262 val
= IORegistryEntrySearchCFProperty(interface
,
2264 CFSTR(kIODeviceSupportsHoldKey
),
2266 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2270 if (isA_CFNumber(val
) &&
2271 CFNumberGetValue(val
, kCFNumberSInt32Type
, &v92
)) {
2272 interfacePrivate
->modemIsV92
= (v92
== 1);
2279 interfacePrivate
->entity_type
= kSCEntNetModem
;
2281 // Entity (Hardware)
2282 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2283 if (!isA_CFString(ift
)) {
2287 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2291 if (CFEqual(base
, CFSTR("modem"))) {
2292 interfacePrivate
->builtin
= TRUE
;
2293 interfacePrivate
->sort_order
= kSortInternalModem
;
2294 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2295 interfacePrivate
->sort_order
= kSortUSBModem
;
2297 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2299 interfacePrivate
->sort_order
= kSortSerialPort
;
2304 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2305 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2307 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2308 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2310 // look for modem CCL, unique identifier
2311 if (interfacePrivate
->overrides
!= NULL
) {
2312 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2314 CFStringRef uniqueID
;
2316 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2317 modemCCL
= isA_CFString(modemCCL
);
2319 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2320 uniqueID
= isA_CFString(uniqueID
);
2321 if (uniqueID
!= NULL
) {
2322 // retain the device's base name and the unique id
2323 CFRelease(interfacePrivate
->entity_device
);
2324 interfacePrivate
->entity_device
= CFRetain(base
);
2325 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2330 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2331 // a bit harder for the modem CCL
2332 if (modemCCL
== NULL
) {
2333 val
= IORegistryEntrySearchCFProperty(interface
,
2337 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2339 modemCCL
= IOCopyCFStringValue(val
);
2340 if (modemCCL
!= NULL
) {
2341 set_connection_script(interfacePrivate
, modemCCL
);
2342 CFRelease(modemCCL
);
2350 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2351 interfacePrivate
->localized_key
= CFSTR("irda");
2352 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2353 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2355 CFStringRef localized
= NULL
;
2356 CFStringRef name
= NULL
;
2357 CFMutableStringRef port
;
2359 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2360 CFStringLowercase(port
, NULL
);
2363 CFStringAppend(port
, CFSTR("-port"));
2366 // set non-localized name
2367 if (bundle
!= NULL
) {
2368 name
= copy_interface_string(bundle
, port
, FALSE
);
2371 if (!CFEqual(port
, name
)) {
2372 // if [English] localization available
2373 interfacePrivate
->name
= name
;
2375 // if no [English] localization available, use TTY base name
2377 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2380 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2383 // set localized name
2384 if (bundle
!= NULL
) {
2385 localized
= copy_interface_string(bundle
, port
, TRUE
);
2387 if (localized
!= NULL
) {
2388 if (!CFEqual(port
, localized
)) {
2389 // if localization available
2390 interfacePrivate
->localized_name
= localized
;
2392 // if no localization available, use TTY base name
2393 CFRelease(localized
);
2394 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2397 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2400 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2401 // get USB info (if available)
2402 processUSBInterface(interfacePrivate
,
2410 // set interface "name"
2411 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2412 // if "ModemCCL" not provided, also check if the product/interface
2413 // name matches a CCL script
2414 if ((modemCCL
== NULL
) &&
2415 is_valid_connection_script(interfacePrivate
->name
)) {
2416 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2428 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2429 CFRelease(interfacePrivate
->entity_device
);
2430 interfacePrivate
->entity_device
= NULL
;
2432 if (base
!= NULL
) CFRelease(base
);
2439 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2442 * Create a path for a registry entry.
2446 CFStringRef str
= NULL
;
2448 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2449 if (status
== kIOReturnSuccess
) {
2450 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2451 } else if (status
== kIOReturnBadArgument
) {
2452 io_registry_entry_t parent
;
2454 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2455 if (status
== kIOReturnSuccess
) {
2456 CFStringRef str_parent
;
2458 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2459 if (str_parent
!= NULL
) {
2462 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2463 if (status
== kIOReturnSuccess
) {
2466 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2467 if (status
== kIOReturnSuccess
) {
2468 str
= CFStringCreateWithFormat(NULL
,
2475 str
= CFStringCreateWithFormat(NULL
,
2483 CFRelease(str_parent
);
2486 IOObjectRelease(parent
);
2493 static CFMutableDictionaryRef
2494 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2497 CFMutableDictionaryRef reg_dict
= NULL
;
2498 CFTypeRef value
= NULL
;
2500 reg_dict
= CFDictionaryCreateMutable(NULL
,
2502 &kCFTypeDictionaryKeyCallBacks
,
2503 &kCFTypeDictionaryValueCallBacks
);
2505 for (; idx
< numKeys
; idx
++) {
2506 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2507 if (value
!= NULL
) {
2508 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2516 static SCNetworkInterfaceRef
2517 createInterface(io_registry_entry_t interface
, processInterface func
,
2518 CFStringRef hidden_key
)
2520 io_registry_entry_t bus
= MACH_PORT_NULL
;
2521 CFMutableDictionaryRef bus_dict
= NULL
;
2522 io_registry_entry_t controller
= MACH_PORT_NULL
;
2523 CFMutableDictionaryRef controller_dict
= NULL
;
2524 uint64_t entryID
= 0;
2525 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2526 CFMutableDictionaryRef interface_dict
= NULL
;
2531 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2533 const CFStringRef interface_dict_keys
[] = {
2534 CFSTR(kIOInterfaceType
),
2536 CFSTR(kIOBSDNameKey
),
2537 CFSTR(kIOPrimaryInterface
),
2538 CFSTR(kIOInterfaceNamePrefix
),
2539 CFSTR(kIOInterfaceUnit
),
2540 CFSTR(kIOTTYDeviceKey
),
2541 CFSTR(kIOTTYBaseNameKey
),
2542 CFSTR(kIOSerialBSDTypeKey
),
2545 #endif // !TARGET_OS_SIMULATOR
2547 const CFStringRef controller_dict_keys
[] = {
2549 CFSTR(kIOMACAddress
)
2552 const CFStringRef bus_dict_keys
[] = {
2556 if (hidden_key
!= NULL
) {
2558 val
= IORegistryEntrySearchCFProperty(interface
,
2562 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2565 goto done
; // if this interface should not be exposed
2569 #if TARGET_OS_SIMULATOR || 1 // while waiting for rdar://19431723
2570 // get the dictionary associated with the [interface] node
2571 kr
= IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
2572 if (kr
!= kIOReturnSuccess
) {
2573 SC_log(LOG_INFO
, "IORegistryEntryCreateCFProperties() failed, kr = 0x%x", kr
);
2577 interface_dict
= copyIORegistryProperties(interface
,
2578 interface_dict_keys
,
2579 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2580 #endif // !TARGET_OS_SIMULATOR
2582 // get the controller node
2583 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2584 if (kr
!= kIOReturnSuccess
) {
2585 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2589 controller_dict
= copyIORegistryProperties(controller
,
2590 controller_dict_keys
,
2591 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2594 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2595 if (kr
!= kIOReturnSuccess
) {
2596 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2600 bus_dict
= copyIORegistryProperties(bus
,
2602 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2604 // get the registry entry ID
2605 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2606 if (kr
!= kIOReturnSuccess
) {
2607 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2611 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2612 assert(interfacePrivate
!= NULL
);
2613 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2614 interfacePrivate
->entryID
= entryID
;
2616 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2617 val
= IORegistryEntrySearchCFProperty(interface
,
2619 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2621 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2623 if (isA_CFDictionary(val
)) {
2624 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2629 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2630 // get user-notification / auto-configuration preference
2631 val
= IORegistryEntrySearchCFProperty(interface
,
2633 kSCNetworkInterfaceConfigurationActionKey
,
2635 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2637 if (isA_CFString(val
)) {
2638 interfacePrivate
->configurationAction
= CFRetain(val
);
2643 // get HiddenConfiguration preference
2644 val
= IORegistryEntrySearchCFProperty(interface
,
2646 kSCNetworkInterfaceHiddenConfigurationKey
,
2648 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2650 interfacePrivate
->hidden
= TRUE
;
2654 CFRelease(interfacePrivate
);
2655 interfacePrivate
= NULL
;
2660 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2662 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2663 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2665 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2666 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2668 return (SCNetworkInterfaceRef
)interfacePrivate
;
2672 static CF_RETURNS_RETAINED CFArrayRef
2673 findMatchingInterfaces(CFDictionaryRef matching
, processInterface func
,
2674 CFStringRef hidden_key
)
2676 CFMutableArrayRef interfaces
;
2677 io_registry_entry_t interface
;
2679 io_iterator_t iterator
= MACH_PORT_NULL
;
2682 * A reference to the "matching" dictionary will be consumed by the
2683 * the call to IOServiceGetMatchingServices so we bump up the retain
2688 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2689 if (kr
!= kIOReturnSuccess
) {
2690 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2694 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2696 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2697 SCNetworkInterfaceRef match
;
2699 match
= createInterface(interface
, func
, hidden_key
);
2700 if (match
!= NULL
) {
2701 CFArrayAppendValue(interfaces
, match
);
2705 IOObjectRelease(interface
);
2708 IOObjectRelease(iterator
);
2715 #pragma mark helper functions
2719 findConfiguration(CFStringRef interface_type
)
2723 for (i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2724 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2735 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2737 CFIndex interfaceIndex
;
2738 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2740 if (interfacePrivate
->serviceID
== NULL
) {
2741 // if not associated with a service (yet)
2742 _SCErrorSet(kSCStatusInvalidArgument
);
2746 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2747 if (interfaceIndex
== kCFNotFound
) {
2748 // unknown interface type, use per-service configuration preferences
2749 return interfacePrivate
->interface_type
; // entity
2752 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2753 // if configuration information can be associated with this interface type
2754 return *configurations
[interfaceIndex
].entity_hardware
;
2757 _SCErrorSet(kSCStatusInvalidArgument
);
2764 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2765 CFStringRef extendedType
,
2766 Boolean requirePerInterface
)
2768 CFStringRef defaultType
;
2769 CFIndex extendedIndex
;
2770 CFIndex interfaceIndex
;
2771 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2772 Boolean isL2TP
= FALSE
;
2775 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2776 if (defaultType
== NULL
) {
2780 if (CFEqual(extendedType
, defaultType
)) {
2781 // extended and default configuration types cannot conflict
2785 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2786 if (interfaceIndex
== kCFNotFound
) {
2787 // configuration information for unknown interface type's
2788 // are stored along with the service and we don't allow
2789 // per-service extended configurations
2793 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2794 CFStringRef interfaceType
;
2796 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2797 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2798 SCNetworkInterfaceRef child
;
2800 child
= SCNetworkInterfaceGetInterface(interface
);
2801 if (child
!= NULL
) {
2802 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2803 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2810 if (requirePerInterface
&&
2811 !configurations
[interfaceIndex
].per_interface_config
&&
2813 // we don't allow per-service extended configurations (except
2814 // that we do allow IPSec as an extended type for PPP->L2TP)
2818 extendedIndex
= findConfiguration(extendedType
);
2819 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2820 // extended type cannot match a known interface type (except
2821 // that we do allow IPSec as an extended type for PPP->L2TP)
2827 * Should we check/match and specifically allow known extended
2828 * configuration types (e.g. EAPOL)?
2830 * Should we check/match and specifically block known internal
2831 * configuration types (e.g. QoSMarking)?
2833 * Lastly, should we ensure that any non-standard extended configuration
2834 * types be of the form com.myCompany.myType?
2843 _SCErrorSet(kSCStatusInvalidArgument
);
2850 CFStringRef defaultType
;
2851 CFMutableArrayRef types
;
2852 } extendedConfiguration
, *extendedConfigurationRef
;
2856 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2858 CFStringRef extendedType
= (CFStringRef
)key
;
2859 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2861 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2862 // do not include the default configuration type
2866 if (CFArrayContainsValue(myContextRef
->types
,
2867 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2869 // if extendedType already has already been added
2873 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2880 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2882 CFIndex interfaceIndex
;
2883 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2885 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2886 if (interfaceIndex
== kCFNotFound
) {
2887 // if per-service (not per interface) configuration
2891 if (!configurations
[interfaceIndex
].per_interface_config
) {
2892 // if per-interface configuration not allowed
2896 return interfaceIndex
;
2900 static CF_RETURNS_RETAINED CFArrayRef
2901 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2904 CFIndex interfaceIndex
;
2905 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2906 extendedConfiguration myContext
;
2907 SCNetworkServiceRef service
;
2911 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2912 if (myContext
.defaultType
== NULL
) {
2913 myContext
.types
= NULL
;
2917 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2919 if (interfacePrivate
->serviceID
== NULL
) {
2920 // if not associated with a service (yet)
2924 interfaceIndex
= findPerInterfaceConfiguration(interface
);
2925 if (interfaceIndex
== kCFNotFound
) {
2926 // if no per-interface configuration
2930 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
2931 interfacePrivate
->prefs
,
2932 interfacePrivate
->serviceID
,
2935 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
2936 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
2938 for (i
= 0; i
< n
; i
++) {
2939 CFDictionaryRef configs
;
2942 CFArrayRef services
;
2943 SCNetworkSetRef set
;
2945 set
= CFArrayGetValueAtIndex(sets
, i
);
2946 services
= SCNetworkSetCopyServices(set
);
2947 found
= CFArrayContainsValue(services
,
2948 CFRangeMake(0, CFArrayGetCount(services
)),
2950 CFRelease(services
);
2956 // add stored extended configuration types
2957 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
2958 SCNetworkSetGetSetID(set
), // set
2959 interfacePrivate
->entity_device
, // service
2961 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
2963 if (isA_CFDictionary(configs
)) {
2964 CFDictionaryApplyFunction(configs
,
2965 __addExtendedConfigurationType
,
2969 // add not-yet-stored extended configuration types
2970 if (interfacePrivate
->unsaved
!= NULL
) {
2971 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
2972 __addExtendedConfigurationType
,
2980 if (sets
!= NULL
) CFRelease(sets
);
2984 return myContext
.types
;
2988 stringCreateArray(CFStringRef str
)
2990 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
2994 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
2995 CFStringRef extendedType
)
2997 CFMutableArrayRef array
= NULL
;
3001 SCNetworkServiceRef service
;
3004 // known interface type, per-interface configuration preferences
3006 // 1. look for all sets which contain the associated service
3007 // 2. add a per-set path for the interface configuration for
3010 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3011 interfacePrivate
->prefs
,
3012 interfacePrivate
->serviceID
,
3013 (SCNetworkInterfaceRef
)interfacePrivate
);
3015 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3016 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3018 for (i
= 0; i
< n
; i
++) {
3019 CFArrayRef services
;
3020 SCNetworkSetRef set
;
3022 set
= CFArrayGetValueAtIndex(sets
, i
);
3023 services
= SCNetworkSetCopyServices(set
);
3024 if (CFArrayContainsValue(services
,
3025 CFRangeMake(0, CFArrayGetCount(services
)),
3027 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3028 SCNetworkSetGetSetID(set
), // set
3029 interfacePrivate
->entity_device
, // service
3030 extendedType
); // entity
3031 if (array
== NULL
) {
3032 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3034 CFArrayAppendValue(array
, path
);
3037 CFRelease(services
);
3041 if (sets
!= NULL
) CFRelease(sets
);
3047 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3048 CFStringRef extendedType
)
3050 CFArrayRef array
= NULL
;
3051 CFIndex interfaceIndex
;
3054 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3055 if (interfaceIndex
== kCFNotFound
) {
3056 // unknown interface type, use per-service configuration preferences
3057 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3058 interfacePrivate
->serviceID
, // service
3059 extendedType
); // entity
3060 array
= stringCreateArray(path
);
3064 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3065 // known interface type, per-service configuration preferences
3066 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3067 interfacePrivate
->serviceID
, // service
3068 extendedType
); // entity
3069 array
= stringCreateArray(path
);
3073 else if (interfacePrivate
->serviceID
!= NULL
) {
3074 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3082 #pragma mark SCNetworkInterface <--> preferences entity
3087 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3089 CFMutableDictionaryRef entity
;
3090 CFIndex interfaceIndex
;
3091 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3093 entity
= CFDictionaryCreateMutable(NULL
,
3095 &kCFTypeDictionaryKeyCallBacks
,
3096 &kCFTypeDictionaryValueCallBacks
);
3097 if (interfacePrivate
->entity_type
!= NULL
) {
3098 CFDictionarySetValue(entity
,
3099 kSCPropNetInterfaceType
,
3100 interfacePrivate
->entity_type
);
3102 if (interfacePrivate
->entity_subtype
!= NULL
) {
3103 CFDictionarySetValue(entity
,
3104 kSCPropNetInterfaceSubType
,
3105 interfacePrivate
->entity_subtype
);
3107 if (interfacePrivate
->entity_device
!= NULL
) {
3108 CFDictionarySetValue(entity
,
3109 kSCPropNetInterfaceDeviceName
,
3110 interfacePrivate
->entity_device
);
3112 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3113 CFDictionarySetValue(entity
,
3114 CFSTR("DeviceUniqueIdentifier"),
3115 interfacePrivate
->entity_device_unique
);
3117 if (interfacePrivate
->hidden
) {
3118 CFDictionarySetValue(entity
,
3119 kSCNetworkInterfaceHiddenConfigurationKey
,
3123 // match the "hardware" with the lowest layer
3125 SCNetworkInterfaceRef nextInterface
;
3127 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3128 if (nextInterface
== NULL
) {
3132 interface
= nextInterface
;
3134 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3136 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3140 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3141 if (interfaceIndex
!= kCFNotFound
) {
3142 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3143 CFDictionarySetValue(entity
,
3144 kSCPropNetInterfaceHardware
,
3145 *configurations
[interfaceIndex
].entity_hardware
);
3148 CFDictionarySetValue(entity
,
3149 kSCPropNetInterfaceHardware
,
3150 interfacePrivate
->interface_type
);
3153 // add the localized display name (which will only be used when/if the
3154 // interface is removed from the system)
3155 CFDictionarySetValue(entity
,
3156 kSCPropUserDefinedName
,
3157 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3159 // note that this is a V.92 capable modem
3160 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
3161 interfacePrivate
->modemIsV92
) {
3165 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
3166 CFDictionarySetValue(entity
,
3167 kSCPropNetInterfaceSupportsModemOnHold
,
3176 static SCNetworkInterfaceRef
3177 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3182 n
= CFArrayGetCount(interfaces
);
3183 for (i
= 0; i
< n
; i
++) {
3184 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3185 CFStringRef interfaceName
;
3187 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3188 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3189 CFRetain(interface
);
3197 #if !TARGET_OS_IPHONE
3198 static SCNetworkInterfaceRef
3199 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3202 SCNetworkInterfaceRef interface
= NULL
;
3204 if (prefs
== NULL
) {
3208 // check if the interface is an Ethernet Bond
3209 bonds
= SCBondInterfaceCopyAll(prefs
);
3210 if (bonds
!= NULL
) {
3211 interface
= findInterface(bonds
, ifDevice
);
3216 #endif // !TARGET_OS_IPHONE
3218 static SCNetworkInterfaceRef
3219 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3222 SCNetworkInterfaceRef interface
= NULL
;
3224 if (prefs
== NULL
) {
3228 // check if the interface is an bridge
3229 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3230 if (bridges
!= NULL
) {
3231 interface
= findInterface(bridges
, ifDevice
);
3237 static SCNetworkInterfaceRef
3238 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3240 SCNetworkInterfaceRef interface
= NULL
;
3243 if (prefs
== NULL
) {
3247 // check if the interface is a VLAN
3248 vlans
= SCVLANInterfaceCopyAll(prefs
);
3249 if (vlans
!= NULL
) {
3250 interface
= findInterface(vlans
, ifDevice
);
3260 static CFMutableDictionaryRef
3261 copy_ppp_entity(CFStringRef bsdName
)
3263 CFMutableDictionaryRef entity
= NULL
;
3264 CFStringRef pattern
;
3265 CFMutableArrayRef patterns
;
3266 CFDictionaryRef dict
;
3268 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3269 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3270 CFArrayAppendValue(patterns
, pattern
);
3272 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3273 CFArrayAppendValue(patterns
, pattern
);
3275 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3276 CFRelease(patterns
);
3279 const void * keys_q
[N_QUICK
];
3280 const void ** keys
= keys_q
;
3282 const void * vals_q
[N_QUICK
];
3283 const void ** vals
= vals_q
;
3285 n
= CFDictionaryGetCount(dict
);
3286 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3287 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3288 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3290 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3291 for (i
= 0; i
< n
; i
++) {
3292 CFArrayRef components
;
3293 CFStringRef interfaceKey
;
3294 CFDictionaryRef interfaceVal
;
3296 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3297 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3298 CFStringRef serviceID
;
3300 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3301 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3302 !CFEqual(bsdName
, ifName
)) {
3303 // if not matching PPP interface
3307 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3308 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3309 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3310 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3311 CFRelease(interfaceKey
);
3312 CFRelease(components
);
3313 if (interfaceVal
!= NULL
) {
3314 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3318 if (keys
!= keys_q
) {
3319 CFAllocatorDeallocate(NULL
, keys
);
3320 CFAllocatorDeallocate(NULL
, vals
);
3330 SCNetworkInterfaceRef
3331 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3332 CFStringRef bsdName
,
3335 CFMutableDictionaryRef entity
= NULL
;
3337 SCNetworkInterfaceRef interface
;
3339 bzero(&ifr
, sizeof(ifr
));
3340 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3343 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3345 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3351 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3353 entity
= copy_ppp_entity(bsdName
);
3357 if (entity
== NULL
) {
3358 entity
= CFDictionaryCreateMutable(NULL
,
3360 &kCFTypeDictionaryKeyCallBacks
,
3361 &kCFTypeDictionaryValueCallBacks
);
3362 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3365 #if !TARGET_OS_IPHONE
3366 if ((flags
& kIncludeBondInterfaces
) == 0) {
3367 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3369 #endif // !TARGET_OS_IPHONE
3371 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3372 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3375 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3376 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3379 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3387 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3389 CFMutableStringRef interfacePrefix
= NULL
;
3393 if (isA_CFString(bsdName
) == NULL
) {
3394 SC_log(LOG_DEBUG
, "no BSD name");
3398 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3399 length
= CFStringGetLength(interfacePrefix
);
3401 while (length
> 0) {
3402 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3403 if (lastChar
>= '0' && lastChar
<= '9') {
3404 CFStringDelete(interfacePrefix
,
3405 CFRangeMake(length
-1, 1));
3410 length
= CFStringGetLength(interfacePrefix
);
3413 return interfacePrefix
;
3418 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3419 CFStringRef prefix
);
3423 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3425 Boolean success
= FALSE
;
3426 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3428 if (isA_SCNetworkInterface(interface
) == NULL
) {
3429 SC_log(LOG_INFO
, "No interface");
3433 if (CFEqual(currentBSDName
, newBSDName
)) {
3438 if (interfacePrivate
->entity_device
!= NULL
) {
3439 CFRelease(interfacePrivate
->entity_device
);
3441 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3449 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3451 Boolean success
= FALSE
;
3452 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3453 CFStringRef oldPath
= NULL
;
3454 CFStringRef newPath
= NULL
;
3456 // Using the BSD Name update the path
3457 oldPath
= interfacePrivate
->path
;
3458 if (isA_CFString(oldPath
) == NULL
) {
3461 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3462 if (interfacePrivate
->path
!= NULL
) {
3463 CFRelease(interfacePrivate
->path
);
3465 interfacePrivate
->path
= CFRetain(newPath
);
3469 if (newPath
!= NULL
) {
3477 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3480 SCNetworkInterfacePrivateRef interfacePrivate
;
3482 if (isA_CFString(prefix
) == NULL
) {
3486 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3490 if (interfacePrivate
->prefix
!= NULL
) {
3491 CFRelease(interfacePrivate
->prefix
);
3494 interfacePrivate
->prefix
= prefix
;
3501 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3504 SCNetworkInterfacePrivateRef interfacePrivate
;
3505 CFStringRef newBSDName
= NULL
;
3506 CFStringRef oldBSDName
= NULL
;
3508 if (isA_CFNumber(unit
) == NULL
) {
3511 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3513 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3515 if (interfacePrivate
->prefix
== NULL
) {
3516 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3517 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3518 if (interfaceNamePrefix
== NULL
) {
3519 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3522 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3523 CFRelease(interfaceNamePrefix
);
3528 if (interfacePrivate
->prefix
!= NULL
) {
3529 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3532 // Update the BSD Name
3533 if ((newBSDName
== NULL
) ||
3534 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3535 SC_log(LOG_INFO
, "BSD name update failed");
3539 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3540 SC_log(LOG_INFO
, "IOPath update failed");
3544 if (interfacePrivate
->unit
!= NULL
) {
3545 CFRelease(interfacePrivate
->unit
);
3547 interfacePrivate
->unit
= unit
;
3550 if (newBSDName
!= NULL
) {
3551 CFRelease(newBSDName
);
3559 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3561 CFMutableDictionaryRef interface_entity
= NULL
;
3562 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3563 CFBooleanRef active
= NULL
;
3564 CFStringRef bsdName
= NULL
;
3565 CFBooleanRef builtin
= NULL
;
3566 CFStringRef interfaceNamePrefix
= NULL
;
3567 CFNumberRef interfaceType
= NULL
;
3568 CFNumberRef interfaceUnit
= NULL
;
3569 CFDataRef macAddress
= NULL
;
3570 CFStringRef pathMatch
= NULL
;
3571 CFDictionaryRef info
= NULL
;
3572 CFStringRef type
= NULL
;
3574 if (interfacePrivate
->active
) {
3575 active
= kCFBooleanTrue
;
3578 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3579 if (!isA_CFString(bsdName
)) {
3583 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3584 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3585 if (!isA_CFString(interfaceNamePrefix
)) {
3589 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3590 if (!isA_CFNumber(interfaceType
)) {
3594 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3595 if (!isA_CFNumber(interfaceUnit
)) {
3599 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3600 if (!isA_CFData(macAddress
)) {
3604 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3605 if (!isA_CFString(pathMatch
)) {
3609 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3610 if (!isA_CFDictionary(info
)) {
3614 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3615 if (!isA_CFString(type
)) {
3619 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3620 &kCFTypeDictionaryKeyCallBacks
,
3621 &kCFTypeDictionaryValueCallBacks
);
3623 if (isA_CFBoolean(active
) != NULL
) {
3624 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3627 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3628 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3629 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3630 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3631 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3632 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3633 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3634 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3635 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3640 return interface_entity
;
3645 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3646 SCNetworkServiceRef service
)
3648 SCNetworkInterfacePrivateRef interfacePrivate
;
3649 SCNetworkServicePrivateRef servicePrivate
;
3651 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3652 if (interfacePrivate
->prefs
!= NULL
) {
3653 CFRelease(interfacePrivate
->prefs
);
3654 interfacePrivate
->prefs
= NULL
;
3656 if (interfacePrivate
->serviceID
!= NULL
) {
3657 CFRelease(interfacePrivate
->serviceID
);
3658 interfacePrivate
->serviceID
= NULL
;
3661 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3662 if (servicePrivate
->prefs
!= NULL
) {
3663 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3665 if (servicePrivate
->serviceID
!= NULL
) {
3666 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3675 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3680 if (bundle
== NULL
) {
3681 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3685 if (!isA_CFString(name
)) {
3686 // if no interface "name"
3690 // check non-localized name for a match
3691 str
= copy_interface_string(bundle
, key
, FALSE
);
3693 match
= CFEqual(name
, str
);
3700 // check localized name for a match
3701 str
= copy_interface_string(bundle
, key
, TRUE
);
3703 match
= CFEqual(name
, str
);
3714 #define kInterfaceTypeEthernetValue 6
3715 #define kInterfaceTypeFirewireValue 144
3718 static SCNetworkInterfaceRef
3719 __SCNetworkInterfaceCreateWithStorageEntity (CFAllocatorRef allocator
,
3720 CFDictionaryRef interface_entity
,
3721 SCPreferencesRef prefs
)
3723 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3724 CFBooleanRef active
= NULL
;
3725 CFStringRef bsdName
= NULL
;
3726 CFBooleanRef ioBuiltin
= NULL
;
3727 CFStringRef ioInterfaceNamePrefix
= NULL
;
3728 CFNumberRef ioInterfaceType
= NULL
;
3729 int ioInterfaceTypeNum
;
3730 CFNumberRef ioInterfaceUnit
= NULL
;
3731 CFDataRef ioMACAddress
= NULL
;
3732 CFStringRef ioPathMatch
= NULL
;
3733 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3734 CFStringRef userDefinedName
= NULL
;
3735 CFStringRef usbProductName
= NULL
;
3736 CFNumberRef idProduct
= NULL
;
3737 CFNumberRef idVendor
= NULL
;
3738 CFStringRef type
= NULL
;
3740 /* initialize runtime */
3741 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3743 if (isA_CFDictionary(interface_entity
) == NULL
) {
3744 SC_log(LOG_INFO
, "No interface entity");
3747 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3748 if (isA_CFBoolean(active
) == NULL
) {
3749 active
= kCFBooleanFalse
;
3751 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3752 if (isA_CFString(bsdName
) == NULL
) {
3753 SC_log(LOG_INFO
, "No BSD name");
3756 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3757 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3758 SC_log(LOG_INFO
, "No IOBuiltin property");
3761 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3762 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3763 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3764 if (ioInterfaceNamePrefix
== NULL
) {
3765 SC_log(LOG_INFO
, "No BSD interface name prefix");
3769 CFRetain(ioInterfaceNamePrefix
);
3771 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3772 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3773 SC_log(LOG_INFO
, "No IOInterfaceType");
3776 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3777 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3779 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3780 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3781 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3785 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3786 if (isA_CFData(ioMACAddress
) == NULL
) {
3787 SC_log(LOG_INFO
, "No IOMACAddress");
3790 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3791 if (isA_CFString(ioPathMatch
) == NULL
) {
3792 SC_log(LOG_INFO
, "No IOPathMatch");
3795 // Check if Path contains the BSD Name in the end
3797 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3798 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3799 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3802 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3803 #if !TARGET_OS_SIMULATOR
3804 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3805 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3806 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3807 #endif // !TARGET_OS_SIMULATOR
3809 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3810 if (isA_CFString(type
) == NULL
) {
3811 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3815 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3816 interfacePrivate
->active
= CFBooleanGetValue(active
);
3817 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3818 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3819 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3820 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3821 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3822 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3823 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3824 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3825 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3826 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3827 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3828 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3830 // Handling interface types to be seen in NetworkInterfaces.plist
3831 CFIndex interfaceIndex
;
3833 interfaceIndex
= findConfiguration(type
);
3834 if (interfaceIndex
!= kCFNotFound
) {
3835 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3837 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3840 // Extracting entity type from value of interface type
3841 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3842 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3843 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3844 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3847 if (ioInterfaceNamePrefix
!= NULL
) {
3848 CFRelease(ioInterfaceNamePrefix
);
3851 return (SCNetworkInterfaceRef
)interfacePrivate
;
3855 SCNetworkInterfaceRef
3856 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3857 CFDictionaryRef interface_entity
,
3858 SCNetworkServiceRef service
)
3860 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3861 CFStringRef ifDevice
;
3862 CFStringRef ifName
= NULL
;
3863 CFStringRef ifSubType
;
3865 CFStringRef ifUnique
;
3866 CFArrayRef matching_interfaces
= NULL
;
3867 SCPreferencesRef servicePref
= NULL
;
3868 Boolean useSystemInterfaces
= TRUE
;
3870 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
3871 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3873 if (service
!= NULL
) {
3874 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
3875 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
3876 (__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
) == FALSE
));
3879 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
3880 if (ifType
== NULL
) {
3882 * The interface "Type" was not specified. We'll make an
3883 * assumption that this is an "Ethernet" interface. If a
3884 * real interface exists with the provided interface name
3885 * then the actual type will be set accordingly. If not, we'll
3886 * end up crafting an "Ethernet" SCNetworkInterface that
3887 * will keep the rest of the configuration APIs happy.
3889 ifType
= kSCValNetInterfaceTypeEthernet
;
3892 if (!isA_CFString(ifType
)) {
3896 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
3897 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
3898 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
3899 if (!isA_CFString(ifSubType
)) {
3904 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
3905 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
3907 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
3908 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
3909 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
3910 char bsdName
[IFNAMSIZ
];
3911 CFMutableDictionaryRef matching
;
3913 if (!isA_CFString(ifDevice
)) {
3917 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
3918 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
3921 if (useSystemInterfaces
) {
3922 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
3926 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
3927 if (matching
== NULL
) {
3930 matching_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
3931 CFRelease(matching
);
3933 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
3934 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
3935 CFDictionaryRef matching
;
3936 CFStringRef match_keys
[2];
3937 CFStringRef match_vals
[2];
3939 if (!isA_CFString(ifDevice
)) {
3943 if (useSystemInterfaces
) {
3944 match_keys
[0] = CFSTR(kIOProviderClassKey
);
3945 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
3947 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
3948 match_vals
[1] = ifDevice
;
3950 matching
= CFDictionaryCreate(NULL
,
3951 (const void **)match_keys
,
3952 (const void **)match_vals
,
3953 sizeof(match_keys
)/sizeof(match_keys
[0]),
3954 &kCFTypeDictionaryKeyCallBacks
,
3955 &kCFTypeDictionaryValueCallBacks
);
3956 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
3957 CFRelease(matching
);
3959 if (ifUnique
== NULL
) {
3961 Boolean useDeviceName
= TRUE
;
3963 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
3967 for (i
= 0; i
< n
; i
++) {
3968 SCNetworkInterfacePrivateRef scanPrivate
;
3970 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
3971 if (scanPrivate
->entity_device_unique
!= NULL
) {
3972 useDeviceName
= FALSE
;
3978 if (useDeviceName
&& useSystemInterfaces
) {
3979 if (matching_interfaces
!= NULL
) {
3980 CFRelease(matching_interfaces
);
3983 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
3984 matching
= CFDictionaryCreate(NULL
,
3985 (const void **)match_keys
,
3986 (const void **)match_vals
,
3987 sizeof(match_keys
)/sizeof(match_keys
[0]),
3988 &kCFTypeDictionaryKeyCallBacks
,
3989 &kCFTypeDictionaryValueCallBacks
);
3990 matching_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
3991 CFRelease(matching
);
3994 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
3995 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
3996 kSCNetworkInterfaceTypeL2TP
);
3997 #pragma GCC diagnostic push
3998 #pragma GCC diagnostic ignored "-Wdeprecated"
3999 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4000 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4001 kSCNetworkInterfaceTypePPTP
);
4002 #pragma GCC diagnostic pop
4004 // XXX do we allow non-Apple variants of PPP??? XXX
4005 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4008 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4009 if (!isA_CFString(ifDevice
)) {
4013 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4014 kSCNetworkInterfaceType6to4
);
4015 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4016 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4017 kSCNetworkInterfaceTypeIPSec
);
4018 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4019 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4020 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4021 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4022 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4025 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4026 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4030 if (matching_interfaces
!= NULL
) {
4032 SCPreferencesRef prefs
;
4033 Boolean temp_preferences
= FALSE
;
4035 n
= CFArrayGetCount(matching_interfaces
);
4038 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4039 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4040 // if the unique ID's match
4041 CFRetain(interfacePrivate
);
4045 interfacePrivate
= NULL
;
4048 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4052 if (CFDictionaryGetValueIfPresent(interface_entity
,
4053 kSCPropUserDefinedName
,
4054 (const void **)&ifName
) &&
4055 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4059 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4060 if (prefs
== NULL
) {
4061 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4062 if (prefs
!= NULL
) {
4063 temp_preferences
= TRUE
;
4066 if (prefs
== NULL
) {
4069 #if !TARGET_OS_IPHONE
4070 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4071 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4073 #endif // !TARGET_OS_IPHONE
4074 if ((interfacePrivate
== NULL
)
4075 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4076 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4079 if ((interfacePrivate
== NULL
)
4080 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4081 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4083 if (temp_preferences
) CFRelease(prefs
);
4086 if (ifUnique
!= NULL
) {
4089 // we are looking for an interface with a unique ID
4090 // so let's try to focus our choices
4091 for (i
= 0; i
< n
; i
++) {
4092 SCNetworkInterfacePrivateRef scanPrivate
;
4094 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4095 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4096 if (interfacePrivate
!= NULL
) {
4097 // if we've matched more than one interface
4098 interfacePrivate
= NULL
;
4101 interfacePrivate
= scanPrivate
;
4104 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4105 kSCPropUserDefinedName
,
4106 (const void **)&ifName
)) {
4109 // we don't have a unique ID but do have an interface
4110 // name. If the matching interfaces do have IDs than
4111 // we can try to focus our choices using the name
4112 for (i
= 0; i
< n
; i
++) {
4113 SCNetworkInterfacePrivateRef scanPrivate
;
4115 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4116 if (scanPrivate
->entity_device_unique
!= NULL
) {
4117 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4118 CFStringRef scanName
;
4120 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4121 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4122 continue; // if not the same display name
4126 if (interfacePrivate
!= NULL
) {
4127 // if we've matched more than one interface
4128 interfacePrivate
= NULL
;
4131 interfacePrivate
= scanPrivate
;
4134 if (interfacePrivate
== NULL
) {
4135 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4136 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4138 CFRetain(interfacePrivate
);
4141 CFRelease(matching_interfaces
);
4146 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4148 * if device not present on this system
4150 if (!useSystemInterfaces
) {
4151 if (interfacePrivate
!= NULL
) {
4152 CFRelease(interfacePrivate
);
4156 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4157 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4158 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4159 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4160 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4162 // Using UserDefinedName to check the validity of preferences file
4163 // when useSystemInterfaces is FALSE
4164 if (!useSystemInterfaces
) {
4165 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4166 if (isA_CFString(userDefinedName
) != NULL
) {
4167 CFRetain(userDefinedName
);
4168 if (interfacePrivate
->name
!= NULL
) {
4169 CFRelease(interfacePrivate
->name
);
4171 interfacePrivate
->name
= userDefinedName
;
4173 CFRetain(userDefinedName
);
4174 if (interfacePrivate
->localized_name
!= NULL
) {
4175 CFRelease(interfacePrivate
->localized_name
);
4177 interfacePrivate
->localized_name
= userDefinedName
;
4181 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4182 CFStringRef entity_hardware
;
4183 SCNetworkInterfaceRef virtualInterface
;
4185 if (!useSystemInterfaces
&&
4186 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4187 #if !TARGET_OS_IPHONE
4188 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4190 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4191 CFRelease(interfacePrivate
);
4192 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4194 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4195 if (isA_CFString((entity_hardware
)) &&
4196 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4197 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4198 interfacePrivate
->localized_key
= CFSTR("airport");
4199 interfacePrivate
->sort_order
= kSortAirPort
;
4203 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4205 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4206 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4207 interfacePrivate
->localized_key
= CFSTR("iPhone");
4208 interfacePrivate
->sort_order
= kSortTethered
;
4209 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4210 interfacePrivate
->localized_key
= CFSTR("iPad");
4211 interfacePrivate
->sort_order
= kSortTethered
;
4212 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4213 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4214 interfacePrivate
->sort_order
= kSortThunderbolt
;
4215 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4216 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4217 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4218 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4219 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4220 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4221 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4222 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4223 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4225 interfacePrivate
->sort_order
= kSortEthernet
;
4229 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4230 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4231 interfacePrivate
->sort_order
= kSortFireWire
;
4232 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4233 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4234 CFStringRef entity_hardware
;
4236 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4237 if (isA_CFString((entity_hardware
)) &&
4238 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4239 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4240 interfacePrivate
->sort_order
= kSortAirPort
;
4242 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4243 interfacePrivate
->sort_order
= kSortEthernet
;
4245 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4246 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4247 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4248 interfacePrivate
->sort_order
= kSortBluetooth
;
4249 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4250 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4251 interfacePrivate
->sort_order
= kSortIrDA
;
4252 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4253 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4254 interfacePrivate
->sort_order
= kSortWWAN
;
4256 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4257 interfacePrivate
->sort_order
= kSortModem
;
4260 SCNetworkInterfaceRef child
;
4262 CFRelease(interfacePrivate
);
4263 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4264 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4265 if (interfacePrivate
== NULL
) {
4269 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4270 SCNetworkInterfaceRef child
;
4271 CFRelease(interfacePrivate
);
4272 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4273 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4274 if (interfacePrivate
== NULL
) {
4277 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4278 CFRelease(interfacePrivate
);
4279 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4280 kSCNetworkInterfaceTypeIPSec
);
4281 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4282 CFRelease(interfacePrivate
);
4283 if (!isA_CFString(ifDevice
)) {
4286 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4287 kSCNetworkInterfaceType6to4
);
4288 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4289 CFRelease(interfacePrivate
);
4290 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4291 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4292 // if vendor interface
4293 pthread_mutex_lock(&lock
);
4294 if (vendor_interface_types
== NULL
) {
4295 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4297 CFSetAddValue(vendor_interface_types
, ifType
);
4298 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4299 pthread_mutex_unlock(&lock
);
4301 // if unknown interface
4302 CFRelease(interfacePrivate
);
4303 interfacePrivate
= NULL
;
4307 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4308 interfacePrivate
->hidden
= TRUE
;
4312 if (service
!= NULL
) {
4313 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4316 #if !TARGET_OS_IPHONE
4317 // set prefs & serviceID to Bond member interfaces
4318 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4323 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4324 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4325 for (i
= 0; i
< n
; i
++) {
4326 SCNetworkInterfaceRef member
;
4328 member
= CFArrayGetValueAtIndex(members
, i
);
4329 __SCNetworkInterfaceSetService(member
, service
);
4332 #endif // !TARGET_OS_IPHONE
4334 // set prefs & serviceID to Bridge member interfaces
4335 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4340 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4341 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4342 for (i
= 0; i
< n
; i
++) {
4343 SCNetworkInterfaceRef member
;
4345 member
= CFArrayGetValueAtIndex(members
, i
);
4346 __SCNetworkInterfaceSetService(member
, service
);
4349 // set prefs & serviceID to VLAN pyhsical interface
4350 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4351 SCNetworkInterfaceRef vlan_physical
;
4353 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4354 if (vlan_physical
!= NULL
) {
4355 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4360 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4361 SCNetworkInterfaceRef parent
;
4364 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4365 kSCNetworkInterfaceTypePPP
);
4366 CFRelease(interfacePrivate
);
4367 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4368 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4369 SCNetworkInterfaceRef parent
;
4372 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4373 kSCNetworkInterfaceTypeVPN
);
4374 CFRelease(interfacePrivate
);
4375 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4378 return (SCNetworkInterfaceRef
)interfacePrivate
;
4383 #pragma mark SCNetworkInterface APIs
4388 __SCNetworkInterfaceCopyAll_IONetworkInterface(void)
4390 CFDictionaryRef matching
;
4391 CFArrayRef new_interfaces
;
4393 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4395 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4396 new_interfaces
= findMatchingInterfaces(matching
, processNetworkInterface
, kSCNetworkInterfaceHiddenInterfaceKey
);
4397 CFRelease(matching
);
4399 return new_interfaces
;
4405 __SCNetworkInterfaceCopyAll_Modem()
4407 CFDictionaryRef matching
;
4408 CFStringRef match_keys
[2];
4409 CFStringRef match_vals
[2];
4410 CFArrayRef new_interfaces
;
4412 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4413 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4415 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4416 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4418 matching
= CFDictionaryCreate(NULL
,
4419 (const void **)match_keys
,
4420 (const void **)match_vals
,
4421 sizeof(match_keys
)/sizeof(match_keys
[0]),
4422 &kCFTypeDictionaryKeyCallBacks
,
4423 &kCFTypeDictionaryValueCallBacks
);
4424 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4425 CFRelease(matching
);
4427 return new_interfaces
;
4433 __SCNetworkInterfaceCopyAll_RS232()
4435 CFDictionaryRef matching
;
4436 CFStringRef match_keys
[2];
4437 CFStringRef match_vals
[2];
4438 CFArrayRef new_interfaces
;
4440 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4441 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4443 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4444 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4446 matching
= CFDictionaryCreate(NULL
,
4447 (const void **)match_keys
,
4448 (const void **)match_vals
,
4449 sizeof(match_keys
)/sizeof(match_keys
[0]),
4450 &kCFTypeDictionaryKeyCallBacks
,
4451 &kCFTypeDictionaryValueCallBacks
);
4452 new_interfaces
= findMatchingInterfaces(matching
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
4453 CFRelease(matching
);
4455 return new_interfaces
;
4459 #if !TARGET_OS_IPHONE
4461 addBTPANInterface(SCPreferencesRef prefs
, CFMutableArrayRef all_interfaces
)
4464 SCNetworkInterfaceRef interface
;
4467 n
= CFArrayGetCount(all_interfaces
);
4468 for (i
= 0; i
< n
; i
++) {
4469 SCNetworkInterfaceRef interface
;
4471 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4472 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4473 // if we already have a BT-PAN interface
4478 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4479 if (interface
!= NULL
) {
4480 // include BT-PAN interface
4481 CFArrayAppendValue(all_interfaces
, interface
);
4482 CFRelease(interface
);
4487 #endif // !TARGET_OS_IPHONE
4491 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4496 n
= CFArrayGetCount(new_interfaces
);
4497 for (i
= 0; i
< n
; i
++) {
4498 CFStringRef bsdName
;
4499 SCNetworkInterfaceRef interface
;
4501 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4502 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4503 if (bsdName
!= NULL
) {
4504 CFArrayAppendValue(all_interfaces
, interface
);
4513 __waitForInterfaces()
4518 SCDynamicStoreRef store
;
4520 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4521 if (store
== NULL
) {
4525 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4526 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4527 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4530 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4535 CFArrayRef changedKeys
;
4536 CFDictionaryRef dict
;
4537 Boolean quiet
= FALSE
;
4540 dict
= SCDynamicStoreCopyValue(store
, key
);
4542 if (isA_CFDictionary(dict
) &&
4543 (CFDictionaryContainsKey(dict
, CFSTR("*QUIET*")) ||
4544 CFDictionaryContainsKey(dict
, CFSTR("*TIMEOUT*")))) {
4553 ok
= SCDynamicStoreNotifyWait(store
);
4555 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4559 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4560 if (changedKeys
!= NULL
) {
4561 CFRelease(changedKeys
);
4573 CFArrayRef
/* of SCNetworkInterfaceRef's */
4574 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4576 CFMutableArrayRef all_interfaces
;
4577 CFArrayRef new_interfaces
;
4578 Boolean temp_preferences
= FALSE
;
4580 /* initialize runtime */
4581 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4583 /* wait for IOKit to quiesce */
4584 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4586 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4588 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4589 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface();
4590 if (new_interfaces
!= NULL
) {
4591 add_interfaces(all_interfaces
, new_interfaces
);
4592 CFRelease(new_interfaces
);
4595 // get Modem interfaces
4596 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4597 if (new_interfaces
!= NULL
) {
4598 add_interfaces(all_interfaces
, new_interfaces
);
4599 CFRelease(new_interfaces
);
4602 // get serial (RS232) interfaces
4603 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4604 if (new_interfaces
!= NULL
) {
4605 add_interfaces(all_interfaces
, new_interfaces
);
4606 CFRelease(new_interfaces
);
4609 // get virtual network interfaces (Bond, Bridge, VLAN)
4610 if (prefs
== NULL
) {
4611 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4612 if (prefs
!= NULL
) {
4613 temp_preferences
= TRUE
;
4616 if (prefs
!= NULL
) {
4617 #if !TARGET_OS_IPHONE
4618 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4619 if (new_interfaces
!= NULL
) {
4620 add_interfaces(all_interfaces
, new_interfaces
);
4621 CFRelease(new_interfaces
);
4623 #endif // !TARGET_OS_IPHONE
4625 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4626 if (new_interfaces
!= NULL
) {
4627 add_interfaces(all_interfaces
, new_interfaces
);
4628 CFRelease(new_interfaces
);
4631 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4632 if (new_interfaces
!= NULL
) {
4633 add_interfaces(all_interfaces
, new_interfaces
);
4634 CFRelease(new_interfaces
);
4637 #if !TARGET_OS_IPHONE
4638 // add BT-PAN interface
4639 addBTPANInterface(prefs
, all_interfaces
);
4640 #endif // !TARGET_OS_IPHONE
4642 if (temp_preferences
) CFRelease(prefs
);
4645 // all interfaces have been identified, order and return
4646 sort_interfaces(all_interfaces
);
4648 return all_interfaces
;
4652 CFArrayRef
/* of SCNetworkInterfaceRef's */
4653 SCNetworkInterfaceCopyAll()
4655 CFArrayRef all_interfaces
;
4657 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4658 return all_interfaces
;
4662 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4663 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4666 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4668 if (!isA_SCNetworkInterface(interface
)) {
4669 _SCErrorSet(kSCStatusInvalidArgument
);
4673 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4677 i
= findConfiguration(interfacePrivate
->interface_type
);
4678 if (i
!= kCFNotFound
) {
4679 if (configurations
[i
].supported_interfaces
!= doNone
) {
4680 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4681 if (configurations
[i
].supported_interfaces
& do6to4
) {
4682 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4684 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4685 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4687 if (configurations
[i
].supported_interfaces
& doPPP
) {
4688 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4690 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4691 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4695 SCNetworkInterfaceRef child
;
4697 child
= SCNetworkInterfaceGetInterface(interface
);
4698 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4699 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4700 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4706 return interfacePrivate
->supported_interface_types
;
4710 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4711 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4714 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4716 if (!isA_SCNetworkInterface(interface
)) {
4717 _SCErrorSet(kSCStatusInvalidArgument
);
4721 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4725 i
= findConfiguration(interfacePrivate
->interface_type
);
4726 if (i
!= kCFNotFound
) {
4727 if (configurations
[i
].supported_protocols
!= doNone
) {
4728 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4729 if (configurations
[i
].supported_protocols
& doDNS
) {
4730 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4732 if (configurations
[i
].supported_protocols
& doIPv4
) {
4733 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4735 if (configurations
[i
].supported_protocols
& doIPv6
) {
4736 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4738 if (configurations
[i
].supported_protocols
& doProxies
) {
4739 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4741 #if !TARGET_OS_IPHONE
4742 if (configurations
[i
].supported_protocols
& doSMB
) {
4743 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4745 #endif // !TARGET_OS_IPHONE
4751 return interfacePrivate
->supported_protocol_types
;
4755 SCNetworkInterfaceRef
4756 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4758 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4760 SCNetworkInterfacePrivateRef parentPrivate
;
4762 if (!isA_SCNetworkInterface(child
)) {
4763 _SCErrorSet(kSCStatusInvalidArgument
);
4767 if (!isA_CFString(interfaceType
)) {
4768 _SCErrorSet(kSCStatusInvalidArgument
);
4772 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4773 // can't layer on top of loopback
4774 _SCErrorSet(kSCStatusInvalidArgument
);
4778 childIndex
= findConfiguration(childPrivate
->interface_type
);
4780 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4782 childPrivate
->prefs
,
4783 childPrivate
->serviceID
);
4784 if (parentPrivate
== NULL
) {
4785 _SCErrorSet(kSCStatusFailed
);
4789 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4790 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4791 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4794 if (childIndex
!= kCFNotFound
) {
4795 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4796 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4798 // sorry, the child interface does not support PPP
4802 // if the child's interface type not known, use the child entities "Type"
4803 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4806 if (childPrivate
->entity_device
!= NULL
) {
4807 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4810 if (childPrivate
->entity_device_unique
!= NULL
) {
4811 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4813 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4814 if ((childIndex
== kCFNotFound
) ||
4815 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4816 // if the child interface does not support L2TP
4819 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4820 parentPrivate
->localized_key
= CFSTR("l2tp");
4821 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4822 #pragma GCC diagnostic push
4823 #pragma GCC diagnostic ignored "-Wdeprecated"
4824 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4825 if ((childIndex
== kCFNotFound
) ||
4826 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
4827 // if the child interface does not support PPTP
4830 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
4831 parentPrivate
->localized_key
= CFSTR("pptp");
4832 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
4833 #pragma GCC diagnostic pop
4834 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
4835 if ((childIndex
== kCFNotFound
) ||
4836 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
4837 // if the child interface does not support 6to4
4841 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
4842 parentPrivate
->localized_key
= CFSTR("6to4");
4843 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
4844 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
4845 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
4846 if ((childIndex
== kCFNotFound
) ||
4847 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
4848 // if the child interface does not support IPSec
4851 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
4852 parentPrivate
->localized_key
= CFSTR("ipsec");
4853 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
4854 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
4855 if (childIndex
!= kCFNotFound
) {
4856 // if not a "vendor" child interface
4860 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
4861 parentPrivate
->localized_key
= CFSTR("vpn");
4862 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
4863 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
4864 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4865 if (childPrivate
->entity_device
!= NULL
) {
4866 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4868 if (parentPrivate
->entity_subtype
!= NULL
) {
4869 CFArrayRef components
;
4871 CFStringRef vpnType
;
4874 // the "default" interface name is derived from the VPN type
4877 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
4880 vpnType
= parentPrivate
->entity_subtype
;
4881 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
4882 n
= CFArrayGetCount(components
);
4884 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
4885 CFMutableStringRef str
;
4887 str
= CFStringCreateMutableCopy(NULL
,
4889 CFArrayGetValueAtIndex(components
, n
- 2));
4890 (void) CFStringFindAndReplace(str
,
4893 CFRangeMake(0, CFStringGetLength(str
)),
4895 parentPrivate
->localized_name
= str
;
4897 CFRelease(components
);
4899 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4900 // if custom interface type
4901 pthread_mutex_lock(&lock
);
4902 if (vendor_interface_types
== NULL
) {
4903 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4905 CFSetAddValue(vendor_interface_types
, interfaceType
);
4906 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
4907 pthread_mutex_unlock(&lock
);
4909 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
4910 // a dictionary with the same
4911 // name as the interfaceType
4913 // unknown interface type
4917 parentPrivate
->hidden
= childPrivate
->hidden
;
4919 if (childPrivate
->overrides
!= NULL
) {
4920 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
4923 // The following change handles the case where a user has both an Ethernet and
4924 // PPPoE network service. Because a PPPoE service is typically associated with
4925 // an ISP we want it to be sorted higher in the service order.
4926 if ((parentPrivate
->entity_subtype
!= NULL
) &&
4927 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
4928 if ((childPrivate
->interface_type
!= NULL
) &&
4929 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
4930 parentPrivate
->sort_order
= kSortAirportPPP
;
4932 parentPrivate
->sort_order
= kSortEthernetPPP
;
4935 // set sort order of the parent to match the child interface
4936 parentPrivate
->sort_order
= childPrivate
->sort_order
;
4939 return (SCNetworkInterfaceRef
)parentPrivate
;
4943 CFRelease(parentPrivate
);
4944 _SCErrorSet(kSCStatusInvalidArgument
);
4951 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
4953 CFDictionaryRef config
= NULL
;
4954 CFStringRef defaultType
;
4955 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4957 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4958 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4960 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
4961 if (defaultType
!= NULL
) {
4965 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
4966 SCNetworkSetGetSetID(set
), // set
4967 interfacePrivate
->entity_device
, // interface
4968 defaultType
); // entity
4970 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
4973 if (config
== NULL
) {
4974 // if the "set" does not have a saved configuration, use
4975 // the [template] "interface" configuration
4976 if (interfacePrivate
->unsaved
!= NULL
) {
4977 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
4978 if (config
== (CFDictionaryRef
)kCFNull
) {
4983 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
4994 static CFDictionaryRef
4995 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
4996 CFStringRef extendedType
)
4998 CFDictionaryRef config
= NULL
;
4999 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5002 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5003 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5005 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5006 if (paths
!= NULL
) {
5009 path
= CFArrayGetValueAtIndex(paths
, 0);
5010 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5014 if (interfacePrivate
->unsaved
!= NULL
) {
5015 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5016 if (config
== (CFDictionaryRef
)kCFNull
) {
5022 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5031 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5033 CFDictionaryRef config
;
5034 CFStringRef defaultType
;
5036 if (!isA_SCNetworkInterface(interface
)) {
5037 _SCErrorSet(kSCStatusInvalidArgument
);
5041 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5042 if (defaultType
== NULL
) {
5046 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5047 if (config
== NULL
) {
5048 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5049 SCNetworkInterfacePrivateRef interfacePrivate
;
5052 // if AirPort interface, check for a per-service config
5053 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5054 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5055 interfacePrivate
->serviceID
, // service
5056 kSCEntNetAirPort
); // entity
5057 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5061 if (config
== NULL
) {
5062 _SCErrorSet(kSCStatusOK
);
5070 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5071 CFStringRef extendedType
)
5073 CFDictionaryRef config
;
5075 if (!isA_SCNetworkInterface(interface
)) {
5076 _SCErrorSet(kSCStatusInvalidArgument
);
5080 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5081 _SCErrorSet(kSCStatusInvalidArgument
);
5085 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5086 if (config
== NULL
) {
5087 _SCErrorSet(kSCStatusOK
);
5096 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5098 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5100 return interfacePrivate
->entity_type
;
5106 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5108 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5110 return interfacePrivate
->entity_subtype
;
5115 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5117 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5119 if (!isA_SCNetworkInterface(interface
)) {
5120 _SCErrorSet(kSCStatusInvalidArgument
);
5124 if ((interfacePrivate
->interface
!= NULL
) &&
5125 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5126 _SCErrorSet(kSCStatusOK
);
5130 return interfacePrivate
->entity_device
;
5135 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5137 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5139 if (!isA_SCNetworkInterface(interface
)) {
5140 _SCErrorSet(kSCStatusInvalidArgument
);
5144 if ((interfacePrivate
->address
!= NULL
) &&
5145 (interfacePrivate
->addressString
== NULL
)) {
5149 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5152 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5153 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5155 if (n
> sizeof(mac
)) {
5156 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5159 for (cp
= mac_p
; n
> 0; n
-= 3) {
5160 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5163 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5164 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5167 return interfacePrivate
->addressString
;
5171 SCNetworkInterfaceRef
5172 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5174 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5176 if (!isA_SCNetworkInterface(interface
)) {
5177 _SCErrorSet(kSCStatusInvalidArgument
);
5181 return interfacePrivate
->interface
;
5186 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5188 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5190 if (!isA_SCNetworkInterface(interface
)) {
5191 _SCErrorSet(kSCStatusInvalidArgument
);
5195 return interfacePrivate
->interface_type
;
5200 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5202 CFStringRef str
= NULL
;
5205 str
= CFBundleCopyLocalizedString(bundle
,
5208 NETWORKINTERFACE_LOCALIZATIONS
);
5210 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5213 NETWORKINTERFACE_LOCALIZATIONS
);
5221 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5223 static Boolean reported
= FALSE
;
5224 CFStringRef str
= NULL
;
5226 str
= copy_string_from_bundle(bundle
, key
, localized
);
5229 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5235 if (CFEqual(str
, key
) && !reported
) {
5236 const CFStringRef knownStrKey
= CFSTR("airport");
5237 CFStringRef knownStrValue
= NULL
;
5239 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5240 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5241 /* We are here because we requested for a localized/non-localized string
5242 based on the localization key, but we were given the same key/NULL back,
5243 implying a bad...bad thing!
5245 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5249 #if TARGET_OS_IPHONE
5250 /* ...and we want to know about it! */
5251 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5252 #endif //TARGET_OS_IPHONE
5256 if (knownStrValue
!= NULL
) {
5257 CFRelease(knownStrValue
);
5267 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5269 CFMutableStringRef local
;
5272 local
= CFStringCreateMutable(NULL
, 0);
5274 while (interface
!= NULL
) {
5275 Boolean added
= FALSE
;
5276 SCNetworkInterfaceRef child
= NULL
;
5277 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5279 if ((interfacePrivate
->interface
!= NULL
) &&
5280 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5281 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5282 child
= interfacePrivate
->interface
;
5285 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5287 CFStringRef key
= interfacePrivate
->localized_key
;
5289 if (oldLocalization
) {
5290 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5291 interfacePrivate
->localized_key
);
5293 fmt
= copy_interface_string(bundle
, key
, localized
);
5295 CFStringAppendFormat(local
,
5298 interfacePrivate
->localized_arg1
,
5299 interfacePrivate
->localized_arg2
);
5303 if (oldLocalization
) {
5309 (interfacePrivate
->prefs
!= NULL
) &&
5310 (interfacePrivate
->serviceID
!= NULL
) &&
5312 CFDictionaryRef entity
;
5315 // check for (and use) the name of the interface when it
5316 // was last available
5317 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5318 interfacePrivate
->serviceID
,
5319 kSCEntNetInterface
);
5320 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5322 if (isA_CFDictionary(entity
)) {
5325 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5326 if (isA_CFString(name
)) {
5327 CFStringAppend(local
, name
);
5334 // create (non-)localized name based on the interface type
5335 CFStringAppend(local
, interfacePrivate
->interface_type
);
5337 // ... and, if this is a leaf node, the interface device
5338 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5339 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5343 if (child
!= NULL
) {
5344 // if this interface is layered over another
5345 CFStringAppend(local
, CFSTR(" --> "));
5351 name
= CFStringCreateCopy(NULL
, local
);
5358 #if !TARGET_OS_IPHONE
5361 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5365 if (!isA_SCNetworkInterface(interface
)) {
5366 _SCErrorSet(kSCStatusInvalidArgument
);
5370 name
= copy_display_name(interface
, TRUE
, TRUE
);
5377 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5379 CFStringRef localized_name
;
5381 if (!isA_SCNetworkInterface(interface
)) {
5382 _SCErrorSet(kSCStatusInvalidArgument
);
5386 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5387 return localized_name
;
5389 #endif // !TARGET_OS_IPHONE
5393 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5395 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5397 if (!isA_SCNetworkInterface(interface
)) {
5403 if (interfacePrivate
->name
!= NULL
) {
5404 CFRelease(interfacePrivate
->name
);
5406 interfacePrivate
->name
= name
;
5411 if (interfacePrivate
->localized_name
!= NULL
) {
5412 CFRelease(interfacePrivate
->localized_name
);
5414 interfacePrivate
->localized_name
= name
;
5419 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5421 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5423 if (!isA_SCNetworkInterface(interface
)) {
5427 return interfacePrivate
->name
;
5433 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5435 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5437 if (!isA_SCNetworkInterface(interface
)) {
5438 _SCErrorSet(kSCStatusInvalidArgument
);
5442 if (interfacePrivate
->name
== NULL
) {
5443 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5446 return interfacePrivate
->name
;
5451 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5453 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5455 if (!isA_SCNetworkInterface(interface
)) {
5456 _SCErrorSet(kSCStatusInvalidArgument
);
5460 if (interfacePrivate
->localized_name
== NULL
) {
5461 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5464 return interfacePrivate
->localized_name
;
5470 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5472 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5473 CFDictionaryRef overrides
= NULL
;
5475 if (interfacePrivate
->overrides
!= NULL
) {
5476 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5484 SCNetworkInterfaceGetTypeID(void)
5486 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5487 return __kSCNetworkInterfaceTypeID
;
5493 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5494 SCNetworkInterfaceRef interface
,
5495 CFStringRef defaultType
,
5496 CFDictionaryRef config
,
5499 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5502 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5503 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5505 if (defaultType
== NULL
) {
5506 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5507 if (defaultType
== NULL
) {
5512 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5519 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5520 SCNetworkSetGetSetID(set
), // set
5521 interfacePrivate
->entity_device
, // interface
5522 defaultType
); // entity
5524 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5527 // if configuration has been saved
5528 if (interfacePrivate
->unsaved
!= NULL
) {
5529 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5530 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5531 CFRelease(interfacePrivate
->unsaved
);
5532 interfacePrivate
->unsaved
= NULL
;
5538 if (config
== NULL
) {
5539 // remember that we are clearing the configuration
5540 config
= (CFDictionaryRef
)kCFNull
;
5543 if (interfacePrivate
->unsaved
== NULL
) {
5544 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5546 &kCFTypeDictionaryKeyCallBacks
,
5547 &kCFTypeDictionaryValueCallBacks
);
5549 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5552 _SCErrorSet(kSCStatusNoKey
);
5563 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5564 CFStringRef extendedType
,
5565 CFDictionaryRef config
,
5568 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5572 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5573 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5575 if (extendedType
== NULL
) {
5576 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5577 if (extendedType
== NULL
) {
5582 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5586 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5587 if (paths
!= NULL
) {
5591 n
= CFArrayGetCount(paths
);
5592 for (i
= 0; i
< n
; i
++) {
5595 path
= CFArrayGetValueAtIndex(paths
, i
);
5596 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5603 // if configuration has been saved
5604 if (interfacePrivate
->unsaved
!= NULL
) {
5605 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5606 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5607 CFRelease(interfacePrivate
->unsaved
);
5608 interfacePrivate
->unsaved
= NULL
;
5616 if (config
== NULL
) {
5617 // remember that we are clearing the configuration
5618 config
= (CFDictionaryRef
)kCFNull
;
5621 if (interfacePrivate
->unsaved
== NULL
) {
5622 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5624 &kCFTypeDictionaryKeyCallBacks
,
5625 &kCFTypeDictionaryValueCallBacks
);
5627 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5630 _SCErrorSet(kSCStatusNoKey
);
5639 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5641 CFStringRef defaultType
;
5644 if (!isA_SCNetworkInterface(interface
)) {
5645 _SCErrorSet(kSCStatusInvalidArgument
);
5649 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5650 if (defaultType
== NULL
) {
5654 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5656 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5658 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5666 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5667 CFStringRef extendedType
,
5668 CFDictionaryRef config
)
5672 if (!isA_SCNetworkInterface(interface
)) {
5673 _SCErrorSet(kSCStatusInvalidArgument
);
5677 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5681 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5683 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5685 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5693 #pragma mark SCNetworkInterface [Refresh Configuration] API
5696 #ifndef kSCEntNetRefreshConfiguration
5697 #define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
5698 #endif // kSCEntNetRefreshConfiguration
5701 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5706 if (!isA_CFString(ifName
)) {
5707 _SCErrorSet(kSCStatusInvalidArgument
);
5711 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5712 kSCDynamicStoreDomainState
,
5714 kSCEntNetRefreshConfiguration
);
5715 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5722 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5724 CFDataRef data
= NULL
;
5726 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5727 uint32_t status
= kSCStatusOK
;
5728 CFDataRef reply
= NULL
;
5730 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5731 ok
= __SCPreferencesCreate_helper(prefs
);
5737 // serialize the interface name
5738 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5743 // have the helper "refresh" the configuration
5744 status
= kSCStatusOK
;
5746 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5747 SCHELPER_MSG_INTERFACE_REFRESH
,
5751 if (data
!= NULL
) CFRelease(data
);
5756 if (status
!= kSCStatusOK
) {
5765 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5766 _SCHelperClose(&prefsPrivate
->helper_port
);
5769 status
= kSCStatusAccessError
;
5774 _SCErrorSet(status
);
5780 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5783 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5785 if (!isA_SCNetworkInterface(interface
)) {
5786 _SCErrorSet(kSCStatusInvalidArgument
);
5790 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5791 if (ifName
== NULL
) {
5792 _SCErrorSet(kSCStatusInvalidArgument
);
5796 if (interfacePrivate
->prefs
!= NULL
) {
5797 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5798 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5800 if (prefsPrivate
->authorizationData
!= NULL
) {
5801 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5805 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5810 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5812 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5817 #pragma mark SCNetworkInterface Password APIs
5821 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5823 CFStringRef unique_id
= NULL
;
5825 if (config
!= NULL
) {
5826 CFStringRef encryption
;
5828 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
5829 if (isA_CFString(encryption
) &&
5830 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
5831 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
5834 if (unique_id
== NULL
) {
5835 unique_id
= serviceID
;
5843 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
5845 CFMutableStringRef shared_id
= NULL
;
5847 if (config
!= NULL
) {
5848 CFStringRef encryption
;
5850 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
5851 if (isA_CFString(encryption
) &&
5852 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
5853 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
5854 if (shared_id
!= NULL
) {
5855 CFRetain(shared_id
);
5860 if (shared_id
== NULL
) {
5861 CFStringRef unique_id
;
5863 unique_id
= getPasswordID(config
, serviceID
);
5864 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5865 CFStringAppend(shared_id
, CFSTR(".SS"));
5873 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
5875 CFMutableStringRef xauth_id
= NULL
;
5877 if (config
!= NULL
) {
5878 CFStringRef encryption
;
5880 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
5881 if (isA_CFString(encryption
) &&
5882 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
5883 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
5884 if (xauth_id
!= NULL
) {
5890 if (xauth_id
== NULL
) {
5891 CFStringRef unique_id
;
5893 unique_id
= getPasswordID(config
, serviceID
);
5894 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
5895 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
5903 checkInterfacePassword(SCNetworkInterfaceRef interface
,
5904 SCNetworkInterfacePasswordType passwordType
,
5905 SCPreferencesRef
*prefs
,
5906 CFStringRef
*serviceID
)
5908 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5910 if (!isA_SCNetworkInterface(interface
)) {
5914 *serviceID
= interfacePrivate
->serviceID
;
5915 if (*serviceID
== NULL
) {
5919 *prefs
= interfacePrivate
->prefs
;
5920 if (*prefs
== NULL
) {
5924 switch (passwordType
) {
5925 case kSCNetworkInterfacePasswordTypePPP
: {
5926 CFStringRef interfaceType
;
5928 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5929 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5937 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
5938 CFStringRef interfaceType
;
5940 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5941 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
5942 interface
= SCNetworkInterfaceGetInterface(interface
);
5943 if (interface
!= NULL
) {
5944 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5945 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
5946 // if PPP->L2TP interface
5950 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5951 // if IPSec interface
5958 case kSCNetworkInterfacePasswordTypeEAPOL
: {
5962 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
5963 CFStringRef interfaceType
;
5965 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5966 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5967 // if IPSec interface
5974 case kSCNetworkInterfacePasswordTypeVPN
: {
5975 CFStringRef interfaceType
;
5977 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
5978 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5994 _SCErrorSet(kSCStatusInvalidArgument
);
6000 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6001 SCNetworkInterfacePasswordType passwordType
)
6003 Boolean exists
= FALSE
;
6004 SCPreferencesRef prefs
= NULL
;
6005 CFStringRef serviceID
= NULL
;
6007 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6011 switch (passwordType
) {
6012 case kSCNetworkInterfacePasswordTypePPP
: {
6013 CFDictionaryRef config
;
6014 CFStringRef unique_id
;
6016 // get configuration
6017 config
= SCNetworkInterfaceGetConfiguration(interface
);
6020 unique_id
= getPasswordID(config
, serviceID
);
6023 exists
= __extract_password(prefs
,
6025 kSCPropNetPPPAuthPassword
,
6026 kSCPropNetPPPAuthPasswordEncryption
,
6027 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6033 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6034 CFDictionaryRef config
;
6036 CFStringRef shared_id
;
6038 // get configuration
6039 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6041 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6043 config
= SCNetworkInterfaceGetConfiguration(interface
);
6046 // get sharedSecret ID
6047 shared_id
= copySharedSecretID(config
, serviceID
);
6050 exists
= __extract_password(prefs
,
6052 kSCPropNetIPSecSharedSecret
,
6053 kSCPropNetIPSecSharedSecretEncryption
,
6054 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6057 CFRelease(shared_id
);
6061 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6062 CFDictionaryRef config
;
6063 CFStringRef unique_id
= NULL
;
6065 // get configuration
6066 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6068 // get 802.1X identifier
6069 if (config
!= NULL
) {
6070 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6072 if (!isA_CFString(unique_id
)) {
6077 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6081 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6082 CFDictionaryRef config
;
6083 CFStringRef xauth_id
;
6085 // get configuration
6086 config
= SCNetworkInterfaceGetConfiguration(interface
);
6089 xauth_id
= copyXAuthID(config
, serviceID
);
6092 exists
= __extract_password(prefs
,
6094 kSCPropNetIPSecXAuthPassword
,
6095 kSCPropNetIPSecXAuthPasswordEncryption
,
6096 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6099 CFRelease(xauth_id
);
6103 case kSCNetworkInterfacePasswordTypeVPN
: {
6104 CFDictionaryRef config
;
6107 // get configuration
6108 config
= SCNetworkInterfaceGetConfiguration(interface
);
6111 vpn_id
= getPasswordID(config
, serviceID
);
6114 exists
= __extract_password(prefs
,
6116 kSCPropNetVPNAuthPassword
,
6117 kSCPropNetVPNAuthPasswordEncryption
,
6118 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6125 _SCErrorSet(kSCStatusInvalidArgument
);
6134 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6135 SCNetworkInterfacePasswordType passwordType
)
6137 CFDataRef password
= NULL
;
6138 SCPreferencesRef prefs
= NULL
;
6139 CFStringRef serviceID
= NULL
;
6141 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6145 switch (passwordType
) {
6146 case kSCNetworkInterfacePasswordTypePPP
: {
6147 CFDictionaryRef config
;
6148 CFStringRef unique_id
;
6150 // get configuration
6151 config
= SCNetworkInterfaceGetConfiguration(interface
);
6154 unique_id
= getPasswordID(config
, serviceID
);
6157 (void) __extract_password(prefs
,
6159 kSCPropNetPPPAuthPassword
,
6160 kSCPropNetPPPAuthPasswordEncryption
,
6161 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6167 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6168 CFDictionaryRef config
;
6170 CFStringRef shared_id
;
6172 // get configuration
6173 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6175 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6177 config
= SCNetworkInterfaceGetConfiguration(interface
);
6180 // get sharedSecret ID
6181 shared_id
= copySharedSecretID(config
, serviceID
);
6184 (void) __extract_password(prefs
,
6186 kSCPropNetIPSecSharedSecret
,
6187 kSCPropNetIPSecSharedSecretEncryption
,
6188 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6192 CFRelease(shared_id
);
6196 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6197 CFDictionaryRef config
;
6198 CFStringRef unique_id
= NULL
;
6200 // get configuration
6201 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6203 // get 802.1X identifier
6204 if (config
!= NULL
) {
6205 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6207 if (!isA_CFString(unique_id
)) {
6208 _SCErrorSet(kSCStatusFailed
);
6213 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6217 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6218 CFDictionaryRef config
;
6219 CFStringRef xauth_id
;
6221 // get configuration
6222 config
= SCNetworkInterfaceGetConfiguration(interface
);
6225 xauth_id
= copyXAuthID(config
, serviceID
);
6228 (void) __extract_password(prefs
,
6230 kSCPropNetIPSecXAuthPassword
,
6231 kSCPropNetIPSecXAuthPasswordEncryption
,
6232 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6235 CFRelease(xauth_id
);
6239 case kSCNetworkInterfacePasswordTypeVPN
: {
6240 CFDictionaryRef config
;
6243 // get configuration
6244 config
= SCNetworkInterfaceGetConfiguration(interface
);
6247 vpn_id
= getPasswordID(config
, serviceID
);
6250 (void) __extract_password(prefs
,
6252 kSCPropNetVPNAuthPassword
,
6253 kSCPropNetVPNAuthPasswordEncryption
,
6254 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6261 _SCErrorSet(kSCStatusInvalidArgument
);
6270 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6271 SCNetworkInterfacePasswordType passwordType
)
6274 SCPreferencesRef prefs
= NULL
;
6275 CFStringRef serviceID
= NULL
;
6277 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6281 switch (passwordType
) {
6282 case kSCNetworkInterfacePasswordTypePPP
: {
6283 CFDictionaryRef config
;
6284 CFDictionaryRef newConfig
= NULL
;
6285 CFStringRef unique_id
;
6287 // get configuration
6288 config
= SCNetworkInterfaceGetConfiguration(interface
);
6291 unique_id
= getPasswordID(config
, serviceID
);
6294 ok
= __remove_password(prefs
,
6296 kSCPropNetPPPAuthPassword
,
6297 kSCPropNetPPPAuthPasswordEncryption
,
6298 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6302 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6303 if (newConfig
!= NULL
) CFRelease(newConfig
);
6309 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6310 CFDictionaryRef config
;
6312 CFDictionaryRef newConfig
= NULL
;
6313 CFStringRef shared_id
;
6315 // get configuration
6316 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6318 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6320 config
= SCNetworkInterfaceGetConfiguration(interface
);
6323 // get sharedSecret ID
6324 shared_id
= copySharedSecretID(config
, serviceID
);
6327 ok
= __remove_password(prefs
,
6329 kSCPropNetIPSecSharedSecret
,
6330 kSCPropNetIPSecSharedSecretEncryption
,
6331 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6336 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6340 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6343 if (newConfig
!= NULL
) CFRelease(newConfig
);
6346 CFRelease(shared_id
);
6350 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6351 CFDictionaryRef config
;
6352 CFStringRef unique_id
= NULL
;
6354 // get configuration
6355 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6357 // get 802.1X identifier
6358 if (config
!= NULL
) {
6359 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6361 if (!isA_CFString(unique_id
)) {
6362 _SCErrorSet(kSCStatusFailed
);
6367 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6371 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6372 CFDictionaryRef config
;
6373 CFDictionaryRef newConfig
= NULL
;
6374 CFStringRef xauth_id
;
6376 // get configuration
6377 config
= SCNetworkInterfaceGetConfiguration(interface
);
6380 xauth_id
= copyXAuthID(config
, serviceID
);
6383 ok
= __remove_password(prefs
,
6385 kSCPropNetIPSecXAuthPassword
,
6386 kSCPropNetIPSecXAuthPasswordEncryption
,
6387 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6391 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6392 if (newConfig
!= NULL
) CFRelease(newConfig
);
6395 CFRelease(xauth_id
);
6399 case kSCNetworkInterfacePasswordTypeVPN
: {
6400 CFDictionaryRef config
;
6401 CFDictionaryRef newConfig
= NULL
;
6404 // get configuration
6405 config
= SCNetworkInterfaceGetConfiguration(interface
);
6408 vpn_id
= getPasswordID(config
, serviceID
);
6411 ok
= __remove_password(prefs
,
6413 kSCPropNetVPNAuthPassword
,
6414 kSCPropNetVPNAuthPasswordEncryption
,
6415 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6419 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6420 if (newConfig
!= NULL
) CFRelease(newConfig
);
6426 _SCErrorSet(kSCStatusInvalidArgument
);
6435 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6436 SCNetworkInterfacePasswordType passwordType
,
6438 CFDictionaryRef options
)
6440 CFStringRef account
= NULL
;
6441 CFDictionaryRef config
;
6442 CFStringRef description
= NULL
;
6443 CFStringRef label
= NULL
;
6445 SCPreferencesRef prefs
= NULL
;
6446 CFStringRef serviceID
= NULL
;
6448 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6452 switch (passwordType
) {
6453 case kSCNetworkInterfacePasswordTypePPP
: {
6454 SCNetworkServiceRef service
= NULL
;
6455 CFStringRef unique_id
;
6457 // get configuration
6458 config
= SCNetworkInterfaceGetConfiguration(interface
);
6461 unique_id
= getPasswordID(config
, serviceID
);
6463 // get "Account", "Name", "Kind"
6464 if (config
!= NULL
) {
6465 // auth name --> keychain "Account"
6466 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6468 // PPP [user defined] "name" --> keychain "Name"
6469 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6472 if (label
== NULL
) {
6473 // service name --> keychain "Name"
6474 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6479 label
= SCNetworkServiceGetName(service
);
6480 if (label
== NULL
) {
6481 // interface name --> keychain "Name"
6482 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6486 if (bundle
!= NULL
) {
6487 // "PPP Password" --> keychain "Kind"
6488 description
= CFBundleCopyLocalizedString(bundle
,
6489 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6490 CFSTR("PPP Password"),
6495 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6497 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6498 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6503 CFMutableDictionaryRef newConfig
;
6505 if (config
!= NULL
) {
6506 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6508 newConfig
= CFDictionaryCreateMutable(NULL
,
6510 &kCFTypeDictionaryKeyCallBacks
,
6511 &kCFTypeDictionaryValueCallBacks
);
6513 CFDictionarySetValue(newConfig
,
6514 kSCPropNetPPPAuthPassword
,
6516 CFDictionarySetValue(newConfig
,
6517 kSCPropNetPPPAuthPasswordEncryption
,
6518 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6519 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6520 CFRelease(newConfig
);
6523 if (description
!= NULL
) CFRelease(description
);
6524 if (service
!= NULL
) CFRelease(service
);
6528 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6529 CFDictionaryRef baseConfig
= NULL
;
6531 SCNetworkServiceRef service
= NULL
;
6532 CFStringRef shared_id
;
6534 // get configuration
6535 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6536 config
= SCNetworkInterfaceGetConfiguration(interface
);
6538 baseConfig
= config
;
6539 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6542 // get sharedSecret ID
6543 shared_id
= copySharedSecretID(config
, serviceID
);
6545 // get "Account", "Name", "Kind"
6546 if (config
!= NULL
) {
6547 CFStringRef localIdentifier
;
6548 CFStringRef localIdentifierType
;
6550 if (CFDictionaryGetValueIfPresent(config
,
6551 kSCPropNetIPSecLocalIdentifierType
,
6552 (const void **)&localIdentifierType
)
6553 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6554 && CFDictionaryGetValueIfPresent(config
,
6555 kSCPropNetIPSecLocalIdentifier
,
6556 (const void **)&localIdentifier
)
6557 && isA_CFString(localIdentifier
)) {
6558 // local identifier --> keychain "Account"
6559 account
= localIdentifier
;
6562 // PPP [user defined] "name" --> keychain "Name"
6564 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6566 if (baseConfig
!= NULL
) {
6567 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6572 if (label
== NULL
) {
6573 // service name --> keychain "Name"
6574 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6579 label
= SCNetworkServiceGetName(service
);
6580 if (label
== NULL
) {
6581 // interface name --> keychain "Name"
6582 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6586 if (bundle
!= NULL
) {
6587 // "IPSec Shared Secret" --> keychain "Kind"
6588 description
= CFBundleCopyLocalizedString(bundle
,
6589 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6590 CFSTR("IPSec Shared Secret"),
6595 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6597 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6598 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6603 CFMutableDictionaryRef newConfig
= NULL
;
6605 if (config
!= NULL
) {
6606 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6608 newConfig
= CFDictionaryCreateMutable(NULL
,
6610 &kCFTypeDictionaryKeyCallBacks
,
6611 &kCFTypeDictionaryValueCallBacks
);
6613 CFDictionarySetValue(newConfig
,
6614 kSCPropNetIPSecSharedSecret
,
6616 CFDictionarySetValue(newConfig
,
6617 kSCPropNetIPSecSharedSecretEncryption
,
6618 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6620 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6624 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6626 CFRelease(newConfig
);
6629 if (description
!= NULL
) CFRelease(description
);
6630 if (service
!= NULL
) CFRelease(service
);
6631 CFRelease(shared_id
);
6635 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6636 CFStringRef account
= NULL
;
6637 CFStringRef unique_id
= NULL
;
6639 // get configuration
6640 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6642 // get 802.1X identifier
6643 if (config
!= NULL
) {
6644 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6645 unique_id
= isA_CFString(unique_id
);
6647 if (unique_id
!= NULL
) {
6648 CFRetain(unique_id
);
6652 uuid
= CFUUIDCreate(NULL
);
6653 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6657 // 802.1x UserName --> keychain "Account"
6658 if (config
!= NULL
) {
6659 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6662 // get "Name", "Kind"
6663 if (bundle
!= NULL
) {
6664 CFStringRef interface_name
;
6666 // "Network Connection (%@)" --> keychain "Name"
6667 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6668 if (interface_name
!= NULL
) {
6669 CFStringRef label_fmt
;
6671 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6672 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6673 CFSTR("Network Connection (%@)"),
6675 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6676 CFRelease(label_fmt
);
6678 label
= CFBundleCopyLocalizedString(bundle
,
6679 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6680 CFSTR("Network Connection"),
6684 // "802.1X Password" --> keychain "Kind"
6685 description
= CFBundleCopyLocalizedString(bundle
,
6686 CFSTR("KEYCHAIN_KIND_EAPOL"),
6687 CFSTR("802.1X Password"),
6692 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6694 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6695 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6700 CFMutableDictionaryRef newConfig
= NULL
;
6702 if (config
!= NULL
) {
6703 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6705 newConfig
= CFDictionaryCreateMutable(NULL
,
6707 &kCFTypeDictionaryKeyCallBacks
,
6708 &kCFTypeDictionaryValueCallBacks
);
6710 CFDictionarySetValue(newConfig
,
6711 kEAPClientPropUserPasswordKeychainItemID
,
6713 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6716 CFRelease(newConfig
);
6719 CFRelease(unique_id
);
6720 if (label
!= NULL
) CFRelease(label
);
6721 if (description
!= NULL
) CFRelease(description
);
6725 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6726 SCNetworkServiceRef service
= NULL
;
6727 CFStringRef xauth_id
;
6729 // get configuration
6730 config
= SCNetworkInterfaceGetConfiguration(interface
);
6733 xauth_id
= copyXAuthID(config
, serviceID
);
6735 // get "Account", "Name", "Kind"
6736 if (config
!= NULL
) {
6737 // auth name --> keychain "Account"
6738 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6740 // IPSec [user defined] "name" --> keychain "Name"
6741 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6744 if (label
== NULL
) {
6745 // service name --> keychain "Name"
6746 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6751 label
= SCNetworkServiceGetName(service
);
6752 if (label
== NULL
) {
6753 // interface name --> keychain "Name"
6754 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6758 if (bundle
!= NULL
) {
6759 // "IPSec XAuth Password" --> keychain "Kind"
6760 description
= CFBundleCopyLocalizedString(bundle
,
6761 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6762 CFSTR("IPSec XAuth Password"),
6767 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6769 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6770 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6775 CFMutableDictionaryRef newConfig
;
6777 if (config
!= NULL
) {
6778 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6780 newConfig
= CFDictionaryCreateMutable(NULL
,
6782 &kCFTypeDictionaryKeyCallBacks
,
6783 &kCFTypeDictionaryValueCallBacks
);
6785 CFDictionarySetValue(newConfig
,
6786 kSCPropNetIPSecXAuthPassword
,
6788 CFDictionarySetValue(newConfig
,
6789 kSCPropNetIPSecXAuthPasswordEncryption
,
6790 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6791 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6792 CFRelease(newConfig
);
6795 CFRelease(xauth_id
);
6796 if (description
!= NULL
) CFRelease(description
);
6797 if (service
!= NULL
) CFRelease(service
);
6801 case kSCNetworkInterfacePasswordTypeVPN
: {
6802 SCNetworkServiceRef service
= NULL
;
6805 // get configuration
6806 config
= SCNetworkInterfaceGetConfiguration(interface
);
6809 vpn_id
= getPasswordID(config
, serviceID
);
6811 // get "Account", "Name", "Kind"
6812 if (config
!= NULL
) {
6813 // auth name --> keychain "Account"
6814 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6816 // VPN [user defined] "name" --> keychain "Name"
6817 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6820 if (label
== NULL
) {
6821 // service name --> keychain "Name"
6822 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6827 label
= SCNetworkServiceGetName(service
);
6828 if (label
== NULL
) {
6829 // interface name --> keychain "Name"
6830 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6834 if (bundle
!= NULL
) {
6835 // "VPN Password" --> keychain "Kind"
6836 description
= CFBundleCopyLocalizedString(bundle
,
6837 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
6838 CFSTR("VPN Password"),
6843 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6845 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6846 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
6851 CFMutableDictionaryRef newConfig
;
6853 if (config
!= NULL
) {
6854 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6856 newConfig
= CFDictionaryCreateMutable(NULL
,
6858 &kCFTypeDictionaryKeyCallBacks
,
6859 &kCFTypeDictionaryValueCallBacks
);
6861 CFDictionarySetValue(newConfig
,
6862 kSCPropNetVPNAuthPassword
,
6864 CFDictionarySetValue(newConfig
,
6865 kSCPropNetVPNAuthPasswordEncryption
,
6866 kSCValNetVPNAuthPasswordEncryptionKeychain
);
6867 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6868 CFRelease(newConfig
);
6871 if (description
!= NULL
) CFRelease(description
);
6872 if (service
!= NULL
) CFRelease(service
);
6877 _SCErrorSet(kSCStatusInvalidArgument
);
6886 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
6890 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
6892 CFMutableDictionaryRef info
;
6893 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6896 if (interface
== NULL
) {
6900 info
= CFDictionaryCreateMutable(NULL
,
6902 &kCFTypeDictionaryKeyCallBacks
,
6903 &kCFTypeDictionaryValueCallBacks
);
6905 // add non-localized interface name
6906 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
6908 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
6912 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
6913 #if !TARGET_OS_SIMULATOR
6914 if (interfacePrivate
->usb
.name
!= NULL
) {
6915 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
6917 if (interfacePrivate
->usb
.vid
!= NULL
) {
6918 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
6920 if (interfacePrivate
->usb
.pid
!= NULL
) {
6921 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
6923 #endif // !TARGET_OS_SIMULATOR
6926 if (CFDictionaryGetCount(info
) == 0) {
6927 // do not return an empty dictionary
6936 SCNetworkInterfaceRef
6937 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
6939 SCNetworkInterfaceRef interface
= NULL
;
6941 /* initialize runtime */
6942 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
6944 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
6945 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
6946 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
6947 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
6955 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
6957 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6959 return interfacePrivate
->configurationAction
;
6964 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
6966 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6968 return interfacePrivate
->address
;
6973 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
6975 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6977 return interfacePrivate
->prefix
;
6982 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
6984 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6986 return interfacePrivate
->type
;
6991 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
6993 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6995 return interfacePrivate
->unit
;
7000 update_ift_family(SCNetworkInterfaceRef interface
)
7002 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7004 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7006 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7007 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7010 bzero(&ifr
, sizeof(ifr
));
7011 if ((bsdName
!= NULL
) &&
7012 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7015 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7017 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7018 ifr
.ifr_type
.ift_family
= 0;
7019 ifr
.ifr_type
.ift_subfamily
= 0;
7025 interfacePrivate
->family
= CFNumberCreate(NULL
,
7026 kCFNumberSInt32Type
,
7027 &ifr
.ifr_type
.ift_family
);
7028 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7029 kCFNumberSInt32Type
,
7030 &ifr
.ifr_type
.ift_subfamily
);
7036 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7038 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7040 // note: family not in IORegistry, fetch with ioctl()
7042 if (interfacePrivate
->family
== NULL
) {
7043 update_ift_family(interface
);
7046 return interfacePrivate
->family
;
7051 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7053 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7055 // note: subfamily not in IORegistry, fetch with ioctl()
7057 if (interfacePrivate
->subfamily
== NULL
) {
7058 update_ift_family(interface
);
7061 return interfacePrivate
->subfamily
;
7066 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7068 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7070 return interfacePrivate
->path
;
7075 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7077 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7079 return interfacePrivate
->entryID
;
7085 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7087 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7089 return interfacePrivate
->active
;
7094 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7096 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7098 return interfacePrivate
->builtin
;
7103 #pragma mark SCNetworkInterface SPIs
7106 #if !TARGET_OS_EMBEDDED
7108 SCNetworkInterfaceRef
7109 _SCNetworkInterfaceCopyBTPANInterface(void)
7111 CFDictionaryRef dict
;
7112 SCNetworkInterfaceRef interface
= NULL
;
7115 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7116 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7120 CFStringRef if_name
;
7121 SCNetworkInterfacePrivateRef interfacePrivate
;
7123 if (isA_CFDictionary(dict
) &&
7124 CFDictionaryGetValueIfPresent(dict
,
7125 CFSTR("_" BT_PAN_NAME
"_"),
7126 (const void **)&if_name
) &&
7127 isA_CFString(if_name
)) {
7128 CFMutableDictionaryRef entity
;
7130 entity
= CFDictionaryCreateMutable(NULL
,
7132 &kCFTypeDictionaryKeyCallBacks
,
7133 &kCFTypeDictionaryValueCallBacks
);
7134 CFDictionarySetValue(entity
,
7135 kSCPropNetInterfaceType
,
7136 kSCValNetInterfaceTypeEthernet
);
7137 CFDictionarySetValue(entity
,
7138 kSCPropNetInterfaceDeviceName
,
7140 CFDictionarySetValue(entity
,
7141 kSCPropUserDefinedName
,
7142 CFSTR(BT_PAN_NAME
));
7143 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7147 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7149 if ((interfacePrivate
!= NULL
) &&
7150 (interfacePrivate
->address
== NULL
) &&
7151 CFDictionaryGetValueIfPresent(dict
,
7152 CFSTR("_" BT_PAN_MAC
"_"),
7153 (const void **)&addr
) &&
7155 interfacePrivate
->address
= CFRetain(addr
);
7163 #endif // !TARGET_OS_EMBEDDED
7167 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7169 io_registry_entry_t device
;
7170 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7171 CFStringRef device_path
= NULL
;
7172 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7174 CFStringRef match_keys
[2];
7175 CFTypeRef match_vals
[2];
7176 CFDictionaryRef match_dict
;
7177 CFDictionaryRef matching
;
7179 if (interfacePrivate
->entity_device
== NULL
) {
7183 if (interfacePrivate
->entity_device_unique
== NULL
) {
7187 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7188 match_vals
[0] = interfacePrivate
->entity_device
;
7189 match_dict
= CFDictionaryCreate(NULL
,
7190 (const void **)match_keys
,
7191 (const void **)match_vals
,
7193 &kCFTypeDictionaryKeyCallBacks
,
7194 &kCFTypeDictionaryValueCallBacks
);
7196 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7197 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7198 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7199 match_vals
[1] = match_dict
;
7200 matching
= CFDictionaryCreate(NULL
,
7201 (const void **)match_keys
,
7202 (const void **)match_vals
,
7203 sizeof(match_keys
)/sizeof(match_keys
[0]),
7204 &kCFTypeDictionaryKeyCallBacks
,
7205 &kCFTypeDictionaryValueCallBacks
);
7206 CFRelease(match_dict
);
7208 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7209 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7210 if (kr
!= kIOReturnSuccess
) {
7211 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7215 while ((device_path
== NULL
) &&
7216 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7217 CFDictionaryRef overrides
;
7219 overrides
= IORegistryEntrySearchCFProperty(device
,
7221 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7223 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7224 if (overrides
!= NULL
) {
7225 CFDictionaryRef modemOverrides
;
7227 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7228 if (modemOverrides
!= NULL
) {
7229 CFRetain(modemOverrides
);
7231 CFRelease(overrides
);
7232 overrides
= modemOverrides
;
7234 if (overrides
== NULL
) {
7235 overrides
= IORegistryEntrySearchCFProperty(device
,
7237 CFSTR("DeviceModemOverrides"),
7239 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7241 if (overrides
!= NULL
) {
7242 if (isA_CFDictionary(overrides
)) {
7243 CFStringRef matchIdentifier
;
7245 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7246 if (isA_CFString(matchIdentifier
) &&
7247 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7248 device_path
= IORegistryEntryCreateCFProperty(device
,
7249 CFSTR(kIOTTYDeviceKey
),
7254 CFRelease(overrides
);
7256 IOObjectRelease(device
);
7259 IOObjectRelease(device_iterator
);
7263 if (device_path
== NULL
) {
7264 // if we haven't found an exact match to our UniqueIdentifier
7265 // so we simply return the base name.
7266 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7267 if (device_path
!= NULL
) {
7268 CFRetain(device_path
);
7280 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7282 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7284 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7289 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7291 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7293 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7298 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7300 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7302 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7307 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7309 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7311 return interfacePrivate
->hidden
;
7316 _SCNetworkInterfaceIsModemV92(SCNetworkInterfaceRef interface
)
7318 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7320 return interfacePrivate
->modemIsV92
;
7325 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7327 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7329 return (interfacePrivate
->sort_order
== kSortTethered
);
7334 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7336 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7337 CFStringRef interfaceType
;
7339 if (!isA_SCNetworkInterface(interface
)) {
7343 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7344 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7349 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7350 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7352 // if an empty bridge
7356 for (i
= 0; i
< n
; i
++) {
7357 SCNetworkInterfaceRef member
;
7358 SCNetworkInterfacePrivateRef memberPrivate
;
7360 member
= CFArrayGetValueAtIndex(members
, i
);
7361 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7362 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7367 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7371 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7379 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7381 CFDictionaryRef policy
;
7383 if (!isA_SCNetworkInterface(interface
)) {
7384 _SCErrorSet(kSCStatusInvalidArgument
);
7388 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7389 if (policy
== NULL
) {
7390 _SCErrorSet(kSCStatusOK
);
7397 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7401 if (!isA_SCNetworkInterface(interface
)) {
7402 _SCErrorSet(kSCStatusInvalidArgument
);
7406 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7408 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7410 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7418 #pragma mark SCNetworkInterface [internal] SPIs
7422 SCNetworkInterfacePrivateRef
7423 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7424 SCNetworkInterfaceRef interface
,
7425 SCPreferencesRef prefs
,
7426 CFStringRef serviceID
)
7428 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7429 SCNetworkInterfacePrivateRef newPrivate
;
7431 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7432 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7434 if (interface
== kSCNetworkInterfaceIPv4
) {
7435 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7438 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7439 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7440 if (oldPrivate
->interface
!= NULL
) {
7441 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7442 oldPrivate
->interface
, // interface
7443 prefs
, // [new] prefs
7444 serviceID
); // [new] serviceID
7446 if (oldPrivate
->name
!= NULL
) {
7447 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7449 if (oldPrivate
->prefix
!= NULL
) {
7450 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7452 if (oldPrivate
->localized_name
!= NULL
) {
7453 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7455 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7456 if (oldPrivate
->localized_arg1
!= NULL
) {
7457 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7459 if (oldPrivate
->localized_arg2
!= NULL
) {
7460 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7462 if (oldPrivate
->unsaved
!= NULL
) {
7463 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7465 if (oldPrivate
->entity_device
!= NULL
) {
7466 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7468 if (oldPrivate
->entity_device_unique
!= NULL
) {
7469 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7471 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7472 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7473 if (oldPrivate
->supported_interface_types
!= NULL
) {
7474 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7476 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7477 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7479 if (oldPrivate
->address
!= NULL
) {
7480 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7482 newPrivate
->builtin
= oldPrivate
->builtin
;
7483 if (oldPrivate
->configurationAction
!= NULL
) {
7484 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7486 newPrivate
->hidden
= oldPrivate
->hidden
;
7487 if (oldPrivate
->location
!= NULL
) {
7488 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7490 if (oldPrivate
->path
!= NULL
) {
7491 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7493 newPrivate
->entryID
= oldPrivate
->entryID
;
7494 if (oldPrivate
->overrides
!= NULL
) {
7495 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7497 newPrivate
->modemIsV92
= oldPrivate
->modemIsV92
;
7498 if (oldPrivate
->type
!= NULL
) {
7499 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7501 if (oldPrivate
->unit
!= NULL
) {
7502 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7504 if (oldPrivate
->family
!= NULL
) {
7505 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7507 if (oldPrivate
->subfamily
!= NULL
) {
7508 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7510 if (oldPrivate
->usb
.name
!= NULL
) {
7511 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7513 if (oldPrivate
->usb
.vid
!= NULL
) {
7514 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7516 if (oldPrivate
->usb
.pid
!= NULL
) {
7517 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7519 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7521 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7522 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7523 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7525 if (oldPrivate
->bond
.mode
!= NULL
) {
7526 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7528 if (oldPrivate
->bond
.options
!= NULL
) {
7529 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7532 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7533 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7534 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7536 if (oldPrivate
->bridge
.options
!= NULL
) {
7537 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7540 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7541 if (oldPrivate
->vlan
.interface
!= NULL
) {
7542 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7544 if (oldPrivate
->vlan
.tag
!= NULL
) {
7545 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7547 if (oldPrivate
->vlan
.options
!= NULL
) {
7548 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7557 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7559 CFMutableArrayRef configs
;
7561 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7563 while (interface
!= NULL
) {
7564 CFStringRef defaultType
;
7565 CFMutableDictionaryRef interfaceConfiguration
;
7567 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7569 &kCFTypeDictionaryKeyCallBacks
,
7570 &kCFTypeDictionaryValueCallBacks
);
7572 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7573 if (defaultType
!= NULL
) {
7574 CFDictionaryRef config
;
7575 CFArrayRef extendedTypes
;
7578 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7580 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7582 if (config
== NULL
) {
7583 config
= (CFDictionaryRef
)kCFNull
;
7585 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7587 extendedTypes
= extendedConfigurationTypes(interface
);
7588 if (extendedTypes
!= NULL
) {
7592 n
= CFArrayGetCount(extendedTypes
);
7593 for (i
= 0; i
< n
; i
++) {
7594 CFStringRef extendedType
;
7596 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7597 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7598 if (config
== NULL
) {
7599 config
= (CFDictionaryRef
)kCFNull
;
7601 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7604 CFRelease(extendedTypes
);
7608 CFArrayAppendValue(configs
, interfaceConfiguration
);
7609 CFRelease(interfaceConfiguration
);
7611 interface
= SCNetworkInterfaceGetInterface(interface
);
7618 __private_extern__ Boolean
7619 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7621 CFArrayRef interfaces
;
7622 Boolean match
= FALSE
;
7623 CFMutableSetRef members
;
7625 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7627 #if !TARGET_OS_IPHONE
7628 // add Bond [member] interfaces
7629 interfaces
= SCBondInterfaceCopyAll(prefs
);
7630 if (interfaces
!= NULL
) {
7631 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7632 CFRelease(interfaces
);
7634 #endif // !TARGET_OS_IPHONE
7636 // add Bridge [member] interfaces
7637 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7638 if (interfaces
!= NULL
) {
7639 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7640 CFRelease(interfaces
);
7643 if (CFSetGetCount(members
) == 0) {
7647 while (interface
!= NULL
) {
7648 match
= CFSetContainsValue(members
, interface
);
7650 // if the interface is a member of an
7651 // Ethernet Bond or Bridge
7655 interface
= SCNetworkInterfaceGetInterface(interface
);
7667 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
7671 for (i
= 0; interface
!= NULL
; i
++) {
7672 CFStringRef defaultType
;
7673 CFDictionaryRef interfaceConfiguration
;
7676 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
7678 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7679 if (defaultType
!= NULL
) {
7680 CFDictionaryRef config
;
7681 CFArrayRef extendedTypes
;
7683 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
7685 if (config
== (CFDictionaryRef
)kCFNull
) {
7689 // if service is not associated with the set
7690 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
7692 // apply default configuration to this set
7693 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
7696 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7699 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7701 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7706 extendedTypes
= extendedConfigurationTypes(interface
);
7707 if (extendedTypes
!= NULL
) {
7711 n
= CFArrayGetCount(extendedTypes
);
7712 for (j
= 0; j
< n
; j
++) {
7713 CFStringRef extendedType
;
7715 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
7716 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
7718 if (config
== (CFDictionaryRef
)kCFNull
) {
7721 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
7723 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
7726 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
7728 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
7734 CFRelease(extendedTypes
);
7738 interface
= SCNetworkInterfaceGetInterface(interface
);
7745 SCNetworkInterfaceRef
7746 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
7748 SCNetworkInterfaceRef interface
;
7750 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
7751 if (interface
== NULL
) {
7755 if (store
!= NULL
) {
7756 SCNetworkInterfacePrivateRef interfacePrivate
=
7757 (SCNetworkInterfacePrivateRef
)interface
;
7760 interfacePrivate
->store
= store
;
7767 #if !TARGET_OS_SIMULATOR
7768 SCNetworkServicePrimaryRank
7769 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7771 IPMonitorControlRef control
;
7772 SCNetworkInterfacePrivateRef interfacePrivate
=
7773 (SCNetworkInterfacePrivateRef
)interface
;
7774 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
7776 control
= interfacePrivate
->IPMonitorControl
;
7777 if (control
!= NULL
) {
7780 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7781 if (ifName
!= NULL
) {
7782 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
7786 _SCErrorSet(kSCStatusInvalidArgument
);
7793 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7794 SCNetworkServicePrimaryRank newRank
)
7796 IPMonitorControlRef control
;
7797 SCNetworkInterfacePrivateRef interfacePrivate
=
7798 (SCNetworkInterfacePrivateRef
)interface
;
7801 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7802 if (ifName
== NULL
) {
7803 _SCErrorSet(kSCStatusInvalidArgument
);
7806 control
= interfacePrivate
->IPMonitorControl
;
7807 if (control
== NULL
) {
7808 control
= IPMonitorControlCreate();
7809 if (control
== NULL
) {
7810 _SCErrorSet(kSCStatusFailed
);
7813 interfacePrivate
->IPMonitorControl
= control
;
7815 return IPMonitorControlSetInterfacePrimaryRank(control
,
7821 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7823 Boolean disable_until_needed
= FALSE
;
7824 CFNumberRef disable_prop
= NULL
;
7825 CFIndex interfaceIndex
;
7826 SCNetworkInterfacePrivateRef interfacePrivate
7827 = (SCNetworkInterfacePrivateRef
)interface
;
7828 CFArrayRef path_list
;
7830 if (interfacePrivate
->prefs
== NULL
) {
7831 _SCErrorSet(kSCStatusInvalidArgument
);
7834 interfaceIndex
= findPerInterfaceConfiguration(interface
);
7835 if (interfaceIndex
== kCFNotFound
) {
7836 _SCErrorSet(kSCStatusInvalidArgument
);
7839 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7840 if (path_list
!= NULL
) {
7841 CFDictionaryRef config
;
7842 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
7844 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7845 CFRelease(path_list
);
7846 if (config
!= NULL
) {
7849 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
7850 disable_prop
= isA_CFNumber(disable_prop
);
7851 if (disable_prop
!= NULL
) {
7852 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
7853 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
7856 /* invalid property, ignore it */
7857 disable_prop
= NULL
;
7862 if (disable_prop
== NULL
) {
7863 disable_until_needed
7864 = _SCNetworkInterfaceIsTethered(interface
);
7866 _SCErrorSet(kSCStatusOK
);
7867 return (disable_until_needed
);
7871 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
7875 CFIndex interfaceIndex
;
7876 SCNetworkInterfacePrivateRef interfacePrivate
7877 = (SCNetworkInterfacePrivateRef
)interface
;
7879 CFArrayRef path_list
;
7881 if (interfacePrivate
->prefs
== NULL
) {
7882 _SCErrorSet(kSCStatusInvalidArgument
);
7885 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
7886 _SCErrorSet(kSCStatusInvalidArgument
);
7889 interfaceIndex
= findPerInterfaceConfiguration(interface
);
7890 if (interfaceIndex
== kCFNotFound
) {
7891 _SCErrorSet(kSCStatusInvalidArgument
);
7894 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
7895 if (path_list
== NULL
) {
7896 _SCErrorSet(kSCStatusInvalidArgument
);
7899 count
= CFArrayGetCount(path_list
);
7900 for (i
= 0; i
< count
; i
++) {
7901 CFDictionaryRef config
;
7902 CFMutableDictionaryRef new_config
;
7903 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
7905 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
7906 if (config
!= NULL
) {
7908 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7911 = CFDictionaryCreateMutable(NULL
, 0,
7912 &kCFTypeDictionaryKeyCallBacks
,
7913 &kCFTypeDictionaryValueCallBacks
);
7915 if (disable
!= NULL
) {
7916 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
7918 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
7920 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
,
7922 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
7924 CFRelease(new_config
);
7929 CFRelease(path_list
);
7934 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
7941 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
7942 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
7948 #else // !TARGET_OS_SIMULATOR
7950 SCNetworkServicePrimaryRank
7951 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
7953 return (kSCNetworkServicePrimaryRankDefault
);
7957 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
7958 SCNetworkServicePrimaryRank newRank
)
7960 _SCErrorSet(kSCStatusInvalidArgument
);
7965 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
7971 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
7977 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
7979 _SCErrorSet(kSCStatusInvalidArgument
);
7983 #endif // !TARGET_OS_SIMULATOR
7987 CFArrayRef
// SCNetworkInterfaceRef
7988 __SCNetworkInterfaceCopyStoredWithPreferences (SCPreferencesRef ni_prefs
)
7990 CFMutableArrayRef interfaceList
= NULL
;
7992 SCNetworkInterfaceRef interfaceNamer
= NULL
;
7993 CFStringRef defaultNetworkInterfacePath
= NULL
;
7995 /* initialize runtime */
7996 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7998 if (ni_prefs
== NULL
) {
7999 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8000 assert(defaultNetworkInterfacePath
!= NULL
);
8001 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8004 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8006 if (isA_CFArray(if_list
) != NULL
) {
8008 CFIndex n
= CFArrayGetCount(if_list
);
8010 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8011 for (i
= 0; i
< n
; i
++) {
8012 CFDictionaryRef dict
;
8014 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8015 if (isA_CFDictionary(dict
) != NULL
) {
8016 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
, ni_prefs
);
8018 if (interfaceNamer
!= NULL
) {
8019 CFArrayAppendValue(interfaceList
, interfaceNamer
);
8020 CFRelease(interfaceNamer
);
8026 if (defaultNetworkInterfacePath
!= NULL
) {
8027 CFRelease(defaultNetworkInterfacePath
);
8028 // prefs were created in the function, and hence need to be released
8029 CFRelease(ni_prefs
);
8031 return interfaceList
;
8037 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
8039 CFStringRef defaultNetworkInterfacePath
= NULL
;
8040 Boolean success
= FALSE
;
8042 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
8043 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8044 assert(defaultNetworkInterfacePath
!= NULL
);
8045 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8048 if (isA_CFArray(interfacesToSave
) == NULL
) {
8049 SC_log(LOG_INFO
, "No interfaces to save");
8052 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
8055 if (defaultNetworkInterfacePath
!= NULL
) {
8056 CFRelease(defaultNetworkInterfacePath
);
8057 // prefs were created in the function, and hence need to be released
8065 SCNetworkInterfaceRef
8066 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8069 SCNetworkInterfaceRef interface
= NULL
;
8070 CFStringRef defaultNetworkInterfacePath
;
8072 /* initialize runtime */
8073 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8075 if (ni_prefs
== NULL
) {
8076 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8077 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8078 CFRelease(defaultNetworkInterfacePath
);
8084 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8086 if (isA_CFArray(if_list
) != NULL
) {
8088 CFIndex count
= CFArrayGetCount(if_list
);
8090 for (idx
= 0; idx
< count
; idx
++) {
8091 CFDictionaryRef dict
;
8092 CFStringRef tmp_bsdName
;
8094 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8095 if (isA_CFDictionary(dict
) == NULL
) {
8099 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8100 if (tmp_bsdName
== NULL
) {
8103 if (CFEqual(bsdName
, tmp_bsdName
)) {
8104 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
, ni_prefs
);
8110 CFRelease(ni_prefs
);
8116 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8118 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8119 CFStringRef bsdName
= NULL
;
8120 SCNetworkInterfaceRef interface
= NULL
;
8123 count
= CFArrayGetCount(interfaces
);
8125 SC_log(LOG_INFO
, "No interfaces");
8128 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8130 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8131 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8133 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8134 if (isA_CFString(bsdName
) == NULL
) {
8135 SC_log(LOG_INFO
, "No BSD name");
8138 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8140 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8141 CFRelease(mappingBSDToInterface
);
8142 mappingBSDToInterface
= NULL
;
8143 SC_log(LOG_INFO
, "No mappings");
8146 return mappingBSDToInterface
;
8149 __private_extern__ Boolean
8150 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8152 CFStringRef intfSubtype
;
8154 if (entity
== NULL
) {
8158 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8159 #pragma GCC diagnostic push
8160 #pragma GCC diagnostic ignored "-Wdeprecated"
8161 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8164 #pragma GCC diagnostic pop