2 * Copyright (c) 2004-2019 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
29 * which includes code originally authored by
30 * Robert Ulrich <rulrich@apple.com>
31 * Elizabeth Douglas <elizabeth@apple.com>
32 * Quinn <eskimo1@apple.com>
36 #include <TargetConditionals.h>
37 #include <CoreFoundation/CoreFoundation.h>
38 #include <CoreFoundation/CFRuntime.h>
39 #include "SCNetworkConfigurationInternal.h"
40 #include "SCPreferencesInternal.h"
41 #include "SCHelper_client.h"
42 #include "plugin_shared.h"
45 #include <EAP8021X/EAPClientProperties.h>
46 #else // !TARGET_OS_IPHONE
47 #ifndef kEAPClientPropUserName
48 #define kEAPClientPropUserName CFSTR("UserName")
50 #ifndef kEAPClientPropUserPasswordKeychainItemID
51 #define kEAPClientPropUserPasswordKeychainItemID CFSTR("UserPasswordKeychainItemID")
53 #endif // !TARGET_OS_IPHONE
55 #include <IOKit/IOKitLib.h>
56 #include <IOKit/IOCFBundle.h>
57 #include <IOKit/IOBSD.h>
58 #include <IOKit/network/IONetworkController.h>
59 #include <IOKit/network/IONetworkInterface.h>
60 #include <IOKit/network/IOEthernetInterface.h> // for kIOEthernetInterfaceClass
61 #include <IOKit/serial/IOSerialKeys.h>
62 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
63 #if !TARGET_OS_SIMULATOR
64 #include <IOKit/usb/IOUSBLib.h>
65 #endif // !TARGET_OS_SIMULATOR
67 #include "dy_framework.h"
69 #ifndef kPCIThunderboltString
70 #define kPCIThunderboltString "PCI-Thunderbolt"
74 #ifndef kUSBSupportsIPhoneOS
75 #define kUSBSupportsIPhoneOS "SupportsIPhoneOS"
76 #endif // !kUSBSupportsIPhoneOS
77 #endif // TARGET_OS_OSX
79 #ifndef kIOUserEthernetInterfaceRoleKey
80 #define kIOUserEthernetInterfaceRoleKey "InterfaceRole"
83 #ifndef kIOUSBHostInterfaceClassName
84 #define kIOUSBHostInterfaceClassName "IOUSBHostInterface"
89 #include <mach/mach.h>
91 #include <net/if_types.h>
92 #include <net/if_dl.h>
93 #include <net/route.h>
94 #include <sys/ioctl.h>
95 #include <sys/param.h>
96 #include <sys/types.h>
97 #include <sys/socket.h>
99 #include <sys/sysctl.h>
103 /* CrashReporter "Application Specific Information" */
104 #include <CrashReporterClient.h>
107 static CFStringRef
copy_interface_string (CFBundleRef bundle
, CFStringRef key
, Boolean localized
);
108 static CFStringRef
__SCNetworkInterfaceCopyDescription (CFTypeRef cf
);
109 static CFStringRef
__SCNetworkInterfaceCopyFormattingDescription (CFTypeRef cf
, CFDictionaryRef formatOptions
);
110 static void __SCNetworkInterfaceDeallocate (CFTypeRef cf
);
111 static Boolean
__SCNetworkInterfaceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
112 static CFHashCode
__SCNetworkInterfaceHash (CFTypeRef cf
);
113 static void __SCNetworkInterfaceCacheAdd (CFStringRef bsdName
, CFArrayRef matchingInterfaces
);
114 static Boolean
__SCNetworkInterfaceCacheIsOpen (void);
115 static CFArrayRef
__SCNetworkInterfaceCacheCopy (CFStringRef bsdName
);
119 kSortInternalModem
= 0,
134 kSortBluetoothPAN_GN
,
135 kSortBluetoothPAN_NAP
,
146 static const char *sortOrderName
[] = {
174 const CFStringRef kSCNetworkInterfaceType6to4
= CFSTR("6to4");
175 const CFStringRef kSCNetworkInterfaceTypeBluetooth
= CFSTR("Bluetooth");
176 const CFStringRef kSCNetworkInterfaceTypeBond
= CFSTR("Bond");
177 const CFStringRef kSCNetworkInterfaceTypeBridge
= CFSTR("Bridge");
178 const CFStringRef kSCNetworkInterfaceTypeEthernet
= CFSTR("Ethernet");
179 const CFStringRef kSCNetworkInterfaceTypeFireWire
= CFSTR("FireWire");
180 const CFStringRef kSCNetworkInterfaceTypeIEEE80211
= CFSTR("IEEE80211"); // IEEE 802.11, AirPort
181 const CFStringRef kSCNetworkInterfaceTypeIPSec
= CFSTR("IPSec");
182 const CFStringRef kSCNetworkInterfaceTypeIrDA
= CFSTR("IrDA");
183 const CFStringRef kSCNetworkInterfaceTypeL2TP
= CFSTR("L2TP");
184 const CFStringRef kSCNetworkInterfaceTypeLoopback
= CFSTR("Loopback");
185 const CFStringRef kSCNetworkInterfaceTypeModem
= CFSTR("Modem");
186 const CFStringRef kSCNetworkInterfaceTypePPP
= CFSTR("PPP");
187 const CFStringRef kSCNetworkInterfaceTypePPTP
= CFSTR("PPTP");
188 const CFStringRef kSCNetworkInterfaceTypeSerial
= CFSTR("Serial");
189 const CFStringRef kSCNetworkInterfaceTypeVLAN
= CFSTR("VLAN");
190 const CFStringRef kSCNetworkInterfaceTypeVPN
= CFSTR("VPN");
191 const CFStringRef kSCNetworkInterfaceTypeWWAN
= CFSTR("WWAN");
193 const CFStringRef kSCNetworkInterfaceTypeIPv4
= CFSTR("IPv4");
195 static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4
= {
196 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
197 .sort_order
= kSortUnknown
, // sort_order
200 const SCNetworkInterfaceRef kSCNetworkInterfaceIPv4
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceIPv4
;
202 static SCNetworkInterfacePrivate __kSCNetworkInterfaceLoopback
= {
203 .cfBase
= INIT_CFRUNTIME_BASE(), // cfBase
204 .sort_order
= kSortUnknown
, // sort_order
207 const SCNetworkInterfaceRef kSCNetworkInterfaceLoopback
= (SCNetworkInterfaceRef
)&__kSCNetworkInterfaceLoopback
;
209 static CFMutableSetRef vendor_interface_types
= NULL
;
211 // A thread-specific convenience cache of all interfaces matching a bsd name
212 // Key: CFStringRef (BSD name)
213 // Value: CFArrayRef (matching interfaces)
214 static __thread CFMutableDictionaryRef S_interface_cache
= NULL
;
217 #pragma mark SCNetworkInterface configuration details
226 #define doOverIP do6to4|doL2TP|doPPTP|doIPSec
231 #define doProxies 1<<4
232 #if !TARGET_OS_IPHONE
234 #else // !TARGET_OS_IPHONE
236 #endif // !TARGET_OS_IPHONE
238 static const struct {
239 const CFStringRef
*interface_type
;
240 const CFStringRef
*entity_hardware
;
241 Boolean per_interface_config
;
242 uint32_t supported_interfaces
;
243 const CFStringRef
*ppp_subtype
;
244 uint32_t supported_protocols
;
245 } configurations
[] = {
246 // interface type entity_hardware if config? interface types PPP sub-type interface protocols
247 // ===================================== ==================== ========== =============== ======================================= =========================================
248 { &kSCNetworkInterfaceType6to4
, &kSCEntNet6to4
, FALSE
, doNone
, NULL
, doIPv6
},
249 { &kSCNetworkInterfaceTypeBluetooth
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
250 { &kSCNetworkInterfaceTypeBond
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
251 { &kSCNetworkInterfaceTypeBridge
, &kSCEntNetEthernet
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
252 { &kSCNetworkInterfaceTypeEthernet
, &kSCEntNetEthernet
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
253 { &kSCNetworkInterfaceTypeFireWire
, &kSCEntNetFireWire
, TRUE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
254 { &kSCNetworkInterfaceTypeIEEE80211
, &kSCEntNetAirPort
, TRUE
, doPPP
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
255 { &kSCNetworkInterfaceTypeIPSec
, &kSCEntNetIPSec
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
256 { &kSCNetworkInterfaceTypeIrDA
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
257 { &kSCNetworkInterfaceTypeL2TP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypeL2TP
, doNone
},
258 { &kSCNetworkInterfaceTypeModem
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
259 { &kSCNetworkInterfaceTypePPP
, &kSCEntNetPPP
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
260 #pragma GCC diagnostic push
261 #pragma GCC diagnostic ignored "-Wdeprecated"
262 { &kSCNetworkInterfaceTypePPTP
, NULL
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPTP
, doNone
},
263 #pragma GCC diagnostic pop
264 { &kSCNetworkInterfaceTypeSerial
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
265 { &kSCNetworkInterfaceTypeVLAN
, &kSCEntNetEthernet
, TRUE
, doNone
, &kSCValNetInterfaceSubTypePPPoE
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
266 { &kSCNetworkInterfaceTypeVPN
, &kSCEntNetVPN
, FALSE
, doNone
, NULL
, doDNS
|doIPv4
|doIPv6
|doProxies
|doSMB
},
267 { &kSCNetworkInterfaceTypeWWAN
, &kSCEntNetModem
, FALSE
, doPPP
, &kSCValNetInterfaceSubTypePPPSerial
, doNone
},
268 // ===================================== =================== ========== =============== ======================================= =========================================
269 { &kSCNetworkInterfaceTypeLoopback
, NULL
, TRUE
, doNone
, NULL
, doIPv4
|doIPv6
},
270 // ===================================== =================== ========== =============== ======================================= =========================================
271 { &kSCNetworkInterfaceTypeIPv4
, NULL
, FALSE
, doOverIP
, NULL
, doNone
}
275 #define kSCNetworkInterfaceActive "Active"
276 #define kSCNetworkInterfaceInfo "SCNetworkInterfaceInfo"
277 #define kSCNetworkInterfaceType "SCNetworkInterfaceType"
278 #define kSCNetworkInterfaceBSDName kIOBSDNameKey
279 #define kSCNetworkInterfaceIOBuiltin kIOBuiltin
280 #define kSCNetworkInterfaceIOInterfaceNamePrefix kIOInterfaceNamePrefix
281 #define kSCNetworkInterfaceIOInterfaceType kIOInterfaceType
282 #define kSCNetworkInterfaceIOInterfaceUnit kIOInterfaceUnit
283 #define kSCNetworkInterfaceIOMACAddress kIOMACAddress
284 #define kSCNetworkInterfaceIOPathMatch kIOPathMatchKey
287 #define NETWORKINTERFACE_LOCALIZATIONS CFSTR("NetworkInterface")
288 static CFBundleRef bundle
= NULL
;
291 static CFTypeID __kSCNetworkInterfaceTypeID
= _kCFRuntimeNotATypeID
;
294 static const CFRuntimeClass __SCNetworkInterfaceClass
= {
296 "SCNetworkInterface", // className
299 __SCNetworkInterfaceDeallocate
, // dealloc
300 __SCNetworkInterfaceEqual
, // equal
301 __SCNetworkInterfaceHash
, // hash
302 __SCNetworkInterfaceCopyFormattingDescription
, // copyFormattingDesc
303 __SCNetworkInterfaceCopyDescription
// copyDebugDesc
307 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
308 static pthread_once_t iokit_quiet
= PTHREAD_ONCE_INIT
;
309 static pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
312 static mach_port_t masterPort
= MACH_PORT_NULL
;
315 __SCNetworkInterfaceCopyDescription(CFTypeRef cf
)
317 return __SCNetworkInterfaceCopyFormattingDescription(cf
, NULL
);
321 __SCNetworkInterfaceCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
)
323 CFAllocatorRef allocator
= CFGetAllocator(cf
);
324 CFMutableStringRef result
;
325 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
327 result
= CFStringCreateMutable(allocator
, 0);
328 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkInterface %p [%p]> {"), cf
, allocator
);
329 CFStringAppendFormat(result
, NULL
, CFSTR("type = %@"), interfacePrivate
->interface_type
);
330 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_device = %@"), interfacePrivate
->entity_device
);
331 if (interfacePrivate
->entity_device_unique
!= NULL
) {
332 CFStringAppendFormat(result
, NULL
, CFSTR("+%@"), interfacePrivate
->entity_device_unique
);
334 CFStringAppendFormat(result
, NULL
, CFSTR(", entity_type = %@"), interfacePrivate
->entity_type
);
335 if (interfacePrivate
->entity_subtype
!= NULL
) {
336 CFStringAppendFormat(result
, NULL
, CFSTR(" / %@"), interfacePrivate
->entity_subtype
);
338 if (interfacePrivate
->name
!= NULL
) {
339 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), interfacePrivate
->name
);
341 if (interfacePrivate
->localized_name
!= NULL
) {
342 CFStringAppendFormat(result
, NULL
, CFSTR(", name(l) = %@"), interfacePrivate
->localized_name
);
344 if (interfacePrivate
->localized_key
!= NULL
) {
345 CFStringAppendFormat(result
, NULL
, CFSTR(", name(k) = \"%@\""), interfacePrivate
->localized_key
);
346 if (interfacePrivate
->localized_arg1
!= NULL
) {
347 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg1
);
349 if (interfacePrivate
->localized_arg2
!= NULL
) {
350 CFStringAppendFormat(result
, NULL
, CFSTR("+\"%@\""), interfacePrivate
->localized_arg2
);
354 if (interfacePrivate
->address
!= NULL
) {
359 CFStringAppendFormat(result
, NULL
, CFSTR(", address = "));
361 data
= CFDataGetBytePtr(interfacePrivate
->address
);
362 dataLen
= CFDataGetLength(interfacePrivate
->address
);
363 for (i
= 0; i
< dataLen
; i
++) {
364 CFStringAppendFormat(result
, NULL
, CFSTR("%s%02x"),
369 CFStringAppendFormat(result
, NULL
, CFSTR(", builtin = %s"), interfacePrivate
->builtin
? "TRUE" : "FALSE");
370 if (interfacePrivate
->hidden
) {
371 CFStringAppendFormat(result
, NULL
, CFSTR(", hidden = TRUE"));
374 if (interfacePrivate
->trustRequired
) {
375 CFStringAppendFormat(result
, NULL
, CFSTR(", trust required = TRUE"));
377 #endif // TARGET_OS_IPHONE
378 if (interfacePrivate
->location
!= NULL
) {
379 CFStringAppendFormat(result
, NULL
, CFSTR(", location = %@"), interfacePrivate
->location
);
381 if (interfacePrivate
->path
!= NULL
) {
382 CFStringAppendFormat(result
, NULL
, CFSTR(", path = %@"), interfacePrivate
->path
);
384 if (interfacePrivate
->entryID
!= 0) {
385 CFStringAppendFormat(result
, NULL
, CFSTR(", entryID = 0x%llx"), interfacePrivate
->entryID
);
387 if (interfacePrivate
->type
!= NULL
) {
388 CFStringAppendFormat(result
, NULL
, CFSTR(", type = %@"), interfacePrivate
->type
);
390 if (interfacePrivate
->unit
!= NULL
) {
391 CFStringAppendFormat(result
, NULL
, CFSTR(", unit = %@"), interfacePrivate
->unit
);
393 if (interfacePrivate
->family
!= NULL
) {
394 CFStringAppendFormat(result
, NULL
, CFSTR(", family = %@"), interfacePrivate
->family
);
396 if (interfacePrivate
->subfamily
!= NULL
) {
397 CFStringAppendFormat(result
, NULL
, CFSTR(", subfamily = %@"), interfacePrivate
->subfamily
);
399 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
403 if (!isA_CFNumber(interfacePrivate
->usb
.pid
) ||
404 !CFNumberGetValue(interfacePrivate
->usb
.pid
, kCFNumberIntType
, &pid
)) {
407 if (!isA_CFNumber(interfacePrivate
->usb
.vid
) ||
408 !CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
)) {
412 if (interfacePrivate
->usb
.name
!= NULL
) {
413 CFStringAppendFormat(result
, NULL
, CFSTR(", USB name = %@"),
414 interfacePrivate
->usb
.name
);
417 CFStringAppendFormat(result
, NULL
, CFSTR(", USB vid/pid = 0x%0x/0x%0x"),
421 if (interfacePrivate
->configurationAction
!= NULL
) {
422 CFStringAppendFormat(result
, NULL
, CFSTR(", action = %@"), interfacePrivate
->configurationAction
);
424 if (interfacePrivate
->overrides
!= NULL
) {
427 str
= _SCCopyDescription(interfacePrivate
->overrides
, formatOptions
);
428 CFStringAppendFormat(result
, formatOptions
, CFSTR(", overrides = %@"), str
);
431 CFStringAppendFormat(result
, NULL
, CFSTR(", order = %d (%s)"),
432 interfacePrivate
->sort_order
,
433 interfacePrivate
->sort_order
<= kSortUnknown
? sortOrderName
[interfacePrivate
->sort_order
] : "?");
434 if (interfacePrivate
->prefs
!= NULL
) {
435 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), interfacePrivate
->prefs
);
437 if (interfacePrivate
->serviceID
!= NULL
) {
438 CFStringAppendFormat(result
, NULL
, CFSTR(", service = %@"), interfacePrivate
->serviceID
);
440 if (interfacePrivate
->interface
!= NULL
) {
441 CFStringAppendFormat(result
, NULL
, CFSTR(", interface = %@"), interfacePrivate
->interface
);
443 if (interfacePrivate
->unsaved
!= NULL
) {
444 CFStringAppendFormat(result
, formatOptions
, CFSTR(", unsaved = %@"), interfacePrivate
->unsaved
);
447 if (interfacePrivate
->bond
.interfaces
!= NULL
) {
451 n
= CFArrayGetCount(interfacePrivate
->bond
.interfaces
);
452 for (i
= 0; i
< n
; i
++) {
453 SCNetworkInterfaceRef member
;
455 member
= CFArrayGetValueAtIndex(interfacePrivate
->bond
.interfaces
, i
);
456 CFStringAppendFormat(result
, NULL
,
458 (i
== 0) ? ", interfaces = " : ",",
459 SCNetworkInterfaceGetBSDName(member
));
462 if (interfacePrivate
->bond
.mode
!= NULL
) {
463 CFStringAppendFormat(result
, NULL
, CFSTR(", mode = %@"), interfacePrivate
->bond
.mode
);
465 if (interfacePrivate
->bond
.options
!= NULL
) {
468 str
= _SCCopyDescription(interfacePrivate
->bond
.options
, formatOptions
);
469 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
473 if (interfacePrivate
->bridge
.interfaces
!= NULL
) {
477 n
= CFArrayGetCount(interfacePrivate
->bridge
.interfaces
);
478 for (i
= 0; i
< n
; i
++) {
479 SCNetworkInterfaceRef member
;
481 member
= CFArrayGetValueAtIndex(interfacePrivate
->bridge
.interfaces
, i
);
482 CFStringAppendFormat(result
, NULL
,
484 (i
== 0) ? ", interfaces = " : ",",
485 SCNetworkInterfaceGetBSDName(member
));
488 if (interfacePrivate
->bridge
.options
!= NULL
) {
491 str
= _SCCopyDescription(interfacePrivate
->bridge
.options
, formatOptions
);
492 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
496 if (interfacePrivate
->vlan
.interface
!= NULL
) {
497 CFStringAppendFormat(result
, NULL
,
498 CFSTR(", interface = %@"),
499 SCNetworkInterfaceGetBSDName(interfacePrivate
->vlan
.interface
));
501 if (interfacePrivate
->vlan
.tag
!= NULL
) {
502 CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), interfacePrivate
->vlan
.tag
);
504 if (interfacePrivate
->vlan
.options
!= NULL
) {
507 str
= _SCCopyDescription(interfacePrivate
->vlan
.options
, formatOptions
);
508 CFStringAppendFormat(result
, formatOptions
, CFSTR(", options = %@"), str
);
512 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
519 __SCNetworkInterfaceDeallocate(CFTypeRef cf
)
521 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
523 /* release resources */
525 if (interfacePrivate
->name
!= NULL
)
526 CFRelease(interfacePrivate
->name
);
528 if (interfacePrivate
->localized_name
!= NULL
)
529 CFRelease(interfacePrivate
->localized_name
);
531 if (interfacePrivate
->localized_arg1
!= NULL
)
532 CFRelease(interfacePrivate
->localized_arg1
);
534 if (interfacePrivate
->localized_arg2
!= NULL
)
535 CFRelease(interfacePrivate
->localized_arg2
);
537 if (interfacePrivate
->interface
!= NULL
)
538 CFRelease(interfacePrivate
->interface
);
540 if (interfacePrivate
->prefs
!= NULL
)
541 CFRelease(interfacePrivate
->prefs
);
543 if (interfacePrivate
->store
!= NULL
)
544 CFRelease(interfacePrivate
->store
);
546 if (interfacePrivate
->serviceID
!= NULL
)
547 CFRelease(interfacePrivate
->serviceID
);
549 if (interfacePrivate
->unsaved
!= NULL
)
550 CFRelease(interfacePrivate
->unsaved
);
552 if (interfacePrivate
->entity_device
!= NULL
)
553 CFRelease(interfacePrivate
->entity_device
);
555 if (interfacePrivate
->entity_device_unique
!= NULL
)
556 CFRelease(interfacePrivate
->entity_device_unique
);
558 if (interfacePrivate
->supported_interface_types
!= NULL
)
559 CFRelease(interfacePrivate
->supported_interface_types
);
561 if (interfacePrivate
->supported_protocol_types
!= NULL
)
562 CFRelease(interfacePrivate
->supported_protocol_types
);
564 if (interfacePrivate
->address
!= NULL
)
565 CFRelease(interfacePrivate
->address
);
567 if (interfacePrivate
->addressString
!= NULL
)
568 CFRelease(interfacePrivate
->addressString
);
570 if (interfacePrivate
->configurationAction
!= NULL
)
571 CFRelease(interfacePrivate
->configurationAction
);
573 if (interfacePrivate
->location
!= NULL
)
574 CFRelease(interfacePrivate
->location
);
576 if (interfacePrivate
->path
!= NULL
)
577 CFRelease(interfacePrivate
->path
);
579 if (interfacePrivate
->overrides
!= NULL
)
580 CFRelease(interfacePrivate
->overrides
);
582 if (interfacePrivate
->prefix
!= NULL
)
583 CFRelease(interfacePrivate
->prefix
);
585 if (interfacePrivate
->type
!= NULL
)
586 CFRelease(interfacePrivate
->type
);
588 if (interfacePrivate
->unit
!= NULL
)
589 CFRelease(interfacePrivate
->unit
);
591 if (interfacePrivate
->family
!= NULL
)
592 CFRelease(interfacePrivate
->family
);
594 if (interfacePrivate
->subfamily
!= NULL
)
595 CFRelease(interfacePrivate
->subfamily
);
597 if (interfacePrivate
->usb
.name
!= NULL
)
598 CFRelease(interfacePrivate
->usb
.name
);
600 if (interfacePrivate
->usb
.pid
!= NULL
)
601 CFRelease(interfacePrivate
->usb
.pid
);
603 if (interfacePrivate
->usb
.vid
!= NULL
)
604 CFRelease(interfacePrivate
->usb
.vid
);
606 if (interfacePrivate
->bond
.interfaces
!= NULL
)
607 CFRelease(interfacePrivate
->bond
.interfaces
);
609 if (interfacePrivate
->bond
.mode
!= NULL
)
610 CFRelease(interfacePrivate
->bond
.mode
);
612 if (interfacePrivate
->bond
.options
!= NULL
)
613 CFRelease(interfacePrivate
->bond
.options
);
615 if (interfacePrivate
->bridge
.interfaces
!= NULL
)
616 CFRelease(interfacePrivate
->bridge
.interfaces
);
618 if (interfacePrivate
->bridge
.options
!= NULL
)
619 CFRelease(interfacePrivate
->bridge
.options
);
621 if (interfacePrivate
->vlan
.interface
!= NULL
)
622 CFRelease(interfacePrivate
->vlan
.interface
);
624 if (interfacePrivate
->vlan
.tag
!= NULL
)
625 CFRelease(interfacePrivate
->vlan
.tag
);
627 if (interfacePrivate
->vlan
.options
!= NULL
)
628 CFRelease(interfacePrivate
->vlan
.options
);
629 #if !TARGET_OS_SIMULATOR
630 if (interfacePrivate
->IPMonitorControl
!= NULL
)
631 CFRelease(interfacePrivate
->IPMonitorControl
);
632 #endif // !TARGET_OS_SIMULATOR
638 __SCNetworkInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
640 SCNetworkInterfacePrivateRef if1
= (SCNetworkInterfacePrivateRef
)cf1
;
641 SCNetworkInterfacePrivateRef if2
= (SCNetworkInterfacePrivateRef
)cf2
;
646 if (!CFEqual(if1
->interface_type
, if2
->interface_type
)) {
647 return FALSE
; // if not the same interface type
650 if (!_SC_CFEqual(if1
->entity_device
, if2
->entity_device
)) {
651 return FALSE
; // if not the same device
654 if ((if1
->entity_device_unique
!= NULL
) && (if2
->entity_device_unique
!= NULL
)) {
655 if (!_SC_CFEqual(if1
->entity_device_unique
, if2
->entity_device_unique
)) {
656 return FALSE
; // if not the same device unique identifier
658 } else if ((if1
->entity_device_unique
!= NULL
) || (if2
->entity_device_unique
!= NULL
)) {
662 name1
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if1
);
663 name2
= __SCNetworkInterfaceGetNonLocalizedDisplayName((SCNetworkInterfaceRef
)if2
);
664 if ((name1
!= NULL
) && (name2
!= NULL
) && !_SC_CFEqual(name1
, name2
)) {
665 return FALSE
; // if same device but not the same display name
669 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
670 if (!_SC_CFEqual(if1
->bond
.interfaces
, if2
->bond
.interfaces
)) {
671 return FALSE
; // if not the same interfaces
673 if (!_SC_CFEqual(if1
->bond
.mode
, if2
->bond
.mode
)) {
674 return FALSE
; // if not the same mode
678 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
679 if (!_SC_CFEqual(if1
->bridge
.interfaces
, if2
->bridge
.interfaces
)) {
680 return FALSE
; // if not the same interfaces
684 if (CFEqual(if1
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
685 if (!_SC_CFEqual(if1
->vlan
.interface
, if2
->vlan
.interface
)) {
686 return FALSE
; // if not the same physical interface
688 if (!_SC_CFEqual(if1
->vlan
.tag
, if2
->vlan
.tag
)) {
689 return FALSE
; // if not the same tag
693 if (!_SC_CFEqual(if1
->interface
, if2
->interface
)) {
694 return FALSE
; // if not the same layering
702 __SCNetworkInterfaceHash(CFTypeRef cf
)
705 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)cf
;
707 if (interfacePrivate
->entity_device
!= NULL
) {
708 if (interfacePrivate
->entity_device_unique
== NULL
) {
709 hash
= CFHash(interfacePrivate
->entity_device
);
713 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@+%@"),
714 interfacePrivate
->entity_device
,
715 interfacePrivate
->entity_device_unique
);
726 __SCNetworkInterfaceInitialize(void)
731 __kSCNetworkInterfaceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkInterfaceClass
);
733 // initialize __kSCNetworkInterfaceIPv4
734 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceIPv4
, __kSCNetworkInterfaceTypeID
);
735 __kSCNetworkInterfaceIPv4
.interface_type
= kSCNetworkInterfaceTypeIPv4
;
736 __kSCNetworkInterfaceIPv4
.localized_key
= CFSTR("ipv4");
738 // initialize __kSCNetworkInterfaceLoopback
739 _CFRuntimeInitStaticInstance(&__kSCNetworkInterfaceLoopback
, __kSCNetworkInterfaceTypeID
);
740 __kSCNetworkInterfaceLoopback
.interface_type
= kSCNetworkInterfaceTypeLoopback
;
741 __kSCNetworkInterfaceLoopback
.localized_key
= CFSTR("loopback");
742 __kSCNetworkInterfaceLoopback
.entity_device
= CFRetain(CFSTR("lo0"));
743 __kSCNetworkInterfaceLoopback
.entity_type
= kSCValNetInterfaceTypeLoopback
;
745 // get CFBundleRef for SystemConfiguration.framework
746 bundle
= _SC_CFBundleGet();
748 // get mach port used to communication with IOKit
749 kr
= IOMasterPort(MACH_PORT_NULL
, &masterPort
);
750 if (kr
!= kIOReturnSuccess
) {
751 SC_log(LOG_NOTICE
, "could not get IOMasterPort, kr = 0x%x", kr
);
759 SCNetworkInterfacePrivateRef
760 __SCNetworkInterfaceCreatePrivate(CFAllocatorRef allocator
,
761 SCNetworkInterfaceRef interface
,
762 SCPreferencesRef prefs
,
763 CFStringRef serviceID
)
765 SCNetworkInterfacePrivateRef interfacePrivate
;
768 /* initialize runtime */
769 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
771 /* allocate target */
772 size
= sizeof(SCNetworkInterfacePrivate
) - sizeof(CFRuntimeBase
);
773 interfacePrivate
= (SCNetworkInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
,
774 __kSCNetworkInterfaceTypeID
,
777 if (interfacePrivate
== NULL
) {
781 /* initialize non-zero/NULL members */
782 interfacePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
783 interfacePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
) : NULL
;
784 interfacePrivate
->serviceID
= (serviceID
!= NULL
) ? CFRetain(serviceID
) : NULL
;
785 interfacePrivate
->sort_order
= kSortUnknown
;
787 return interfacePrivate
;
793 __SCNetworkInterfaceSupportsVLAN(CFStringRef bsd_if
)
797 struct if_msghdr
* ifm
;
798 char * if_name
= NULL
;
799 unsigned int if_index
;
801 Boolean vlanOK
= FALSE
;
803 // get the interface index
804 if_name
= _SC_cfstring_to_cstring(bsd_if
, NULL
, 0, kCFStringEncodingASCII
);
805 if (if_name
== NULL
) {
806 return FALSE
; // if conversion error
808 if_index
= if_nametoindex(if_name
);
810 goto done
; // if unknown interface
813 // get information for the specified interface
818 mib
[4] = NET_RT_IFLIST
;
819 mib
[5] = if_index
; /* ask for exactly one interface */
821 if (sysctl(mib
, 6, NULL
, &buf_len
, NULL
, 0) == -1) {
822 SC_log(LOG_NOTICE
, "sysctl() size failed: %s", strerror(errno
));
825 buf
= CFAllocatorAllocate(NULL
, buf_len
, 0);
826 if (sysctl(mib
, 6, buf
, &buf_len
, NULL
, 0) == -1) {
827 SC_log(LOG_NOTICE
, "sysctl() failed: %s", strerror(errno
));
831 // check the link type and hwassist flags
832 // ALIGN: buf is aligned
833 ifm
= (struct if_msghdr
*)(void *)buf
;
834 switch (ifm
->ifm_type
) {
836 #if defined(IF_HWASSIST_VLAN_TAGGING) && defined(IF_HWASSIST_VLAN_MTU)
837 struct if_data
*if_data
= &ifm
->ifm_data
;
839 if (if_data
->ifi_hwassist
& (IF_HWASSIST_VLAN_TAGGING
| IF_HWASSIST_VLAN_MTU
)) {
849 if (if_name
!= NULL
) CFAllocatorDeallocate(NULL
, if_name
);
850 if (buf
!= NULL
) CFAllocatorDeallocate(NULL
, buf
);
857 __SCCopyMacAddress(CFStringRef ifname
)
859 struct ifaddrs
*ifap
;
860 char ifname_c
[IFNAMSIZ
];
862 CFDataRef macAddress
= NULL
;
864 if(_SC_cfstring_to_cstring(ifname
,
867 kCFStringEncodingUTF8
) == NULL
) {
871 if (getifaddrs(&ifap
) == -1) {
873 SC_log(LOG_NOTICE
, "getifaddrs() failed: %s", strerror(errno
));
877 for (ifp
= ifap
; ifp
!= NULL
; ifp
= ifp
->ifa_next
) {
878 struct sockaddr_dl
*sdl
;
880 if(strcmp(ifname_c
, ifp
->ifa_name
) != 0) {
884 /* ALIGN: cast ok, this should be aligned (getifaddrs). */
885 sdl
= (struct sockaddr_dl
*)(void *)ifp
->ifa_addr
;
886 if (sdl
->sdl_family
!= AF_LINK
) {
890 macAddress
= CFDataCreate(NULL
, (UInt8
*)LLADDR(sdl
), sdl
->sdl_alen
);
899 SCNetworkInterfacePrivateRef
900 _SCBondInterfaceCreatePrivate(CFAllocatorRef allocator
,
903 SCNetworkInterfacePrivateRef interfacePrivate
;
905 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
906 if (interfacePrivate
== NULL
) {
910 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBond
;
911 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
912 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bond_if
);
913 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
914 interfacePrivate
->builtin
= TRUE
;
915 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bond_if
);
916 interfacePrivate
->sort_order
= kSortBond
;
918 interfacePrivate
->localized_key
= CFSTR("bond");
919 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
921 interfacePrivate
->bond
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
922 // interfacePrivate->bond.mode = NULL;
923 // interfacePrivate->bond.options = NULL;
925 return interfacePrivate
;
930 SCNetworkInterfacePrivateRef
931 _SCBridgeInterfaceCreatePrivate(CFAllocatorRef allocator
,
932 CFStringRef bridge_if
)
934 SCNetworkInterfacePrivateRef interfacePrivate
;
936 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
937 if (interfacePrivate
== NULL
) {
941 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBridge
;
942 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
943 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, bridge_if
);
944 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
945 interfacePrivate
->builtin
= TRUE
;
946 interfacePrivate
->supportsVLAN
= __SCNetworkInterfaceSupportsVLAN(bridge_if
);
947 interfacePrivate
->sort_order
= kSortBridge
;
949 interfacePrivate
->localized_key
= CFSTR("bridge");
950 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
952 interfacePrivate
->bridge
.interfaces
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
953 // interfacePrivate->bridge.options = NULL;
955 return interfacePrivate
;
960 SCNetworkInterfacePrivateRef
961 _SCVLANInterfaceCreatePrivate(CFAllocatorRef allocator
,
964 SCNetworkInterfacePrivateRef interfacePrivate
;
966 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(allocator
, NULL
, NULL
, NULL
);
967 if (interfacePrivate
== NULL
) {
971 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeVLAN
;
972 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
973 interfacePrivate
->entity_device
= CFStringCreateCopy(allocator
, vlan_if
);
974 interfacePrivate
->address
= __SCCopyMacAddress(interfacePrivate
->entity_device
);
975 interfacePrivate
->builtin
= TRUE
;
976 interfacePrivate
->sort_order
= kSortVLAN
;
978 interfacePrivate
->localized_key
= CFSTR("vlan");
979 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->entity_device
);
981 // interfacePrivate->vlan.interface = NULL;
982 // interfacePrivate->vlan.tag = NULL;
983 // interfacePrivate->vlan.options = NULL;
985 return interfacePrivate
;
990 #pragma mark Interface ordering
993 static CF_RETURNS_RETAINED CFArrayRef
994 split_path(CFStringRef path
)
996 CFArrayRef components
;
997 CFMutableStringRef nPath
;
999 // turn '@'s into '/'s
1000 nPath
= CFStringCreateMutableCopy(NULL
, 0, path
);
1001 (void) CFStringFindAndReplace(nPath
,
1004 CFRangeMake(0, CFStringGetLength(nPath
)),
1007 // split path into components to be compared
1008 components
= CFStringCreateArrayBySeparatingStrings(NULL
, nPath
, CFSTR("/"));
1016 _SCNetworkInterfaceCompare(const void *val1
, const void *val2
, void *context
)
1018 #pragma unused(context)
1019 SCNetworkInterfacePrivateRef dev1
= (SCNetworkInterfacePrivateRef
)val1
;
1020 SCNetworkInterfacePrivateRef dev2
= (SCNetworkInterfacePrivateRef
)val2
;
1021 CFComparisonResult res
= kCFCompareEqualTo
;
1023 /* sort by interface type */
1024 if (dev1
->sort_order
!= dev2
->sort_order
) {
1025 if (dev1
->sort_order
< dev2
->sort_order
) {
1026 res
= kCFCompareLessThan
;
1028 res
= kCFCompareGreaterThan
;
1033 /* built-in interfaces sort first */
1034 if (dev1
->builtin
!= dev2
->builtin
) {
1035 if (dev1
->builtin
) {
1036 res
= kCFCompareLessThan
;
1038 res
= kCFCompareGreaterThan
;
1043 /* ... and then, sort built-in interfaces by "location" */
1044 if (dev1
->builtin
) {
1045 if (dev1
->location
!= dev2
->location
) {
1046 if (isA_CFString(dev1
->location
)) {
1047 if (isA_CFString(dev2
->location
)) {
1048 res
= CFStringCompare(dev1
->location
, dev2
->location
, 0);
1050 res
= kCFCompareLessThan
;
1053 res
= kCFCompareGreaterThan
;
1056 if (res
!= kCFCompareEqualTo
) {
1062 /* ... and, then sort by IOPathMatch */
1063 if ((dev1
->path
!= NULL
) && (dev2
->path
!= NULL
)) {
1064 CFArrayRef elements1
;
1065 CFArrayRef elements2
;
1071 elements1
= split_path(dev1
->path
);
1072 n1
= CFArrayGetCount(elements1
);
1074 elements2
= split_path(dev2
->path
);
1075 n2
= CFArrayGetCount(elements2
);
1077 n
= (n1
<= n2
) ? n1
: n2
;
1078 for (i
= 0; i
< n
; i
++) {
1087 e1
= CFArrayGetValueAtIndex(elements1
, i
);
1088 e2
= CFArrayGetValueAtIndex(elements2
, i
);
1090 str
= _SC_cfstring_to_cstring(e1
, NULL
, 0, kCFStringEncodingUTF8
);
1092 q1
= strtoq(str
, &end
, 16);
1093 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1094 CFAllocatorDeallocate(NULL
, str
);
1097 // if e1 is a valid numeric string
1098 str
= _SC_cfstring_to_cstring(e2
, NULL
, 0, kCFStringEncodingUTF8
);
1100 q2
= strtoq(str
, &end
, 16);
1101 isNum
= ((*str
!= '\0') && (*end
== '\0') && (errno
== 0));
1102 CFAllocatorDeallocate(NULL
, str
);
1105 // if e2 is also a valid numeric string
1108 res
= kCFCompareEqualTo
;
1110 } else if (q1
< q2
) {
1111 res
= kCFCompareLessThan
;
1113 res
= kCFCompareGreaterThan
;
1119 res
= CFStringCompare(e1
, e2
, 0);
1120 if (res
!= kCFCompareEqualTo
) {
1125 if (res
== kCFCompareEqualTo
) {
1127 res
= kCFCompareLessThan
;
1128 } else if (n1
< n2
) {
1129 res
= kCFCompareGreaterThan
;
1133 CFRelease(elements1
);
1134 CFRelease(elements2
);
1136 if (res
!= kCFCompareEqualTo
) {
1141 /* ... and, then sort by BSD interface name */
1142 if ((dev1
->entity_device
!= NULL
) && (dev2
->entity_device
!= NULL
)) {
1143 res
= CFStringCompare(dev1
->entity_device
, dev2
->entity_device
, 0);
1144 if (res
!= kCFCompareEqualTo
) {
1149 /* ... and lastly, sort by BSD interface unique identifier */
1150 if ((dev1
->entity_device_unique
!= NULL
) && (dev2
->entity_device_unique
!= NULL
)) {
1151 res
= CFStringCompare(dev1
->entity_device_unique
, dev2
->entity_device_unique
, 0);
1152 // if (res != kCFCompareEqualTo) {
1162 sort_interfaces(CFMutableArrayRef all_interfaces
)
1166 n
= CFArrayGetCount(all_interfaces
);
1171 CFArraySortValues(all_interfaces
, CFRangeMake(0, n
), _SCNetworkInterfaceCompare
, NULL
);
1178 __SCNetworkInterfaceOrder(SCNetworkInterfaceRef interface
)
1180 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
1182 return interfacePrivate
->sort_order
;
1187 #pragma mark Interface details
1191 IOCopyCFStringValue(CFTypeRef ioVal
)
1193 if (isA_CFString(ioVal
)) {
1194 return CFStringCreateCopy(NULL
, ioVal
);
1197 if (isA_CFData(ioVal
)) {
1198 return CFStringCreateWithCString(NULL
,
1199 (const char *)CFDataGetBytePtr(ioVal
),
1200 kCFStringEncodingUTF8
);
1208 IODictionaryCopyBSDName(CFDictionaryRef io_dict
)
1210 CFStringRef if_bsdName
;
1211 CFStringRef if_prefix
;
1212 CFNumberRef if_unit
;
1214 if_bsdName
= CFDictionaryGetValue(io_dict
, CFSTR(kIOBSDNameKey
));
1215 if (if_bsdName
!= NULL
) {
1216 return IOCopyCFStringValue(if_bsdName
);
1219 // no BSD name, get interface prefix and unit
1220 if_prefix
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceNamePrefix
));
1221 if_unit
= CFDictionaryGetValue(io_dict
, CFSTR(kIOInterfaceUnit
));
1222 if (isA_CFString(if_prefix
) && isA_CFNumber(if_unit
)) {
1223 // if both prefix and unit available, construct BSD name
1224 if_bsdName
= CFStringCreateWithFormat(NULL
,
1236 IODictionaryCopyCFStringValue(CFDictionaryRef io_dict
, CFStringRef io_key
)
1240 ioVal
= CFDictionaryGetValue(io_dict
, io_key
);
1241 return IOCopyCFStringValue(ioVal
);
1246 IOStringValueHasPrefix(CFTypeRef ioVal
, CFStringRef prefix
)
1248 Boolean match
= FALSE
;
1249 CFIndex prefixLen
= CFStringGetLength(prefix
);
1250 CFStringRef str
= NULL
;
1252 if (!isA_CFString(ioVal
)) {
1253 if (isA_CFData(ioVal
)) {
1254 str
= CFStringCreateWithCStringNoCopy(NULL
,
1255 (const char *)CFDataGetBytePtr(ioVal
),
1256 kCFStringEncodingUTF8
,
1264 if ((ioVal
!= NULL
) &&
1265 (CFStringGetLength(ioVal
) >= prefixLen
) &&
1266 (CFStringCompareWithOptions(ioVal
,
1268 CFRangeMake(0, prefixLen
),
1269 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
)) {
1273 if (str
!= NULL
) CFRelease(str
);
1278 static const struct {
1279 const CFStringRef name
;
1280 const CFStringRef slot
;
1281 } slot_mappings
[] = {
1283 { CFSTR("A1") , CFSTR("1") },
1284 { CFSTR("B1") , CFSTR("2") },
1285 { CFSTR("C1") , CFSTR("3") },
1287 // Blue&White G3, Yikes G4
1288 { CFSTR("J12"), CFSTR("1") },
1289 { CFSTR("J11"), CFSTR("2") },
1290 { CFSTR("J10"), CFSTR("3") },
1291 { CFSTR("J9"), CFSTR("4") },
1294 { CFSTR("A") , CFSTR("1") },
1295 { CFSTR("B") , CFSTR("2") },
1296 { CFSTR("C") , CFSTR("3") },
1297 { CFSTR("D") , CFSTR("4") },
1299 // Digital Audio G4 (and later models)
1300 { CFSTR("1") , CFSTR("1") },
1301 { CFSTR("2") , CFSTR("2") },
1302 { CFSTR("3") , CFSTR("3") },
1303 { CFSTR("4") , CFSTR("4") },
1304 { CFSTR("5") , CFSTR("5") }
1308 static const CFStringRef slot_prefixes
[] = {
1309 CFSTR("thunderbolt slot "),
1315 static CF_RETURNS_RETAINED CFStringRef
1316 pci_slot(io_registry_entry_t interface
, CFTypeRef
*pci_slot_name
)
1319 io_registry_entry_t parent
;
1320 CFMutableStringRef slot
;
1321 CFTypeRef slot_name
;
1324 if (pci_slot_name
!= NULL
) *pci_slot_name
= NULL
;
1326 slot_name
= IORegistryEntryCreateCFProperty(interface
, CFSTR("AAPL,slot-name"), NULL
, 0);
1327 if (slot_name
!= NULL
) {
1328 slot
= CFStringCreateMutable(NULL
, 0);
1329 if (isA_CFString(slot_name
)) {
1330 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFStringCreateCopy(NULL
, slot_name
);
1331 CFStringAppend(slot
, slot_name
);
1332 } else if (isA_CFData(slot_name
)) {
1333 if (pci_slot_name
!= NULL
) *pci_slot_name
= CFDataCreateCopy(NULL
, slot_name
);
1334 CFStringAppendCString(slot
,
1335 (const char *)CFDataGetBytePtr(slot_name
),
1336 kCFStringEncodingUTF8
);
1339 for (size_t i
= 0; i
< sizeof(slot_prefixes
)/sizeof(slot_prefixes
[0]); i
++) {
1342 len
= CFStringGetLength(slot_prefixes
[i
]);
1343 if (CFStringGetLength(slot
) > len
) {
1344 (void) CFStringFindAndReplace(slot
,
1347 CFRangeMake(0, len
),
1348 kCFCompareCaseInsensitive
|kCFCompareAnchored
);
1352 for (size_t i
= 0; i
< sizeof(slot_mappings
)/sizeof(slot_mappings
[0]); i
++) {
1353 if (CFStringCompare(slot
,
1354 slot_mappings
[i
].name
,
1355 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
1357 slot
= (CFMutableStringRef
)CFRetain(slot_mappings
[i
].slot
);
1362 CFRelease(slot_name
);
1365 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &parent
);
1367 case kIOReturnSuccess
: {
1368 CFTypeRef parent_pci_slot_name
= NULL
;
1369 CFStringRef parent_slot
;
1371 parent_slot
= pci_slot(parent
, &parent_pci_slot_name
);
1372 if (parent_slot
!= NULL
) {
1373 if (slot
!= NULL
) CFRelease(slot
);
1374 slot
= (CFMutableStringRef
)parent_slot
;
1376 if (pci_slot_name
!= NULL
) {
1377 if (*pci_slot_name
!= NULL
) CFRelease(*pci_slot_name
);
1378 *pci_slot_name
= parent_pci_slot_name
;
1380 if (parent_pci_slot_name
!= NULL
) CFRelease(parent_pci_slot_name
);
1384 IOObjectRelease(parent
);
1387 case kIOReturnNoDevice
:
1388 // if we have hit the root node
1391 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
1399 static CFComparisonResult
1400 compare_bsdNames(const void *val1
, const void *val2
, void *context
)
1402 #pragma unused(context)
1403 CFStringRef bsd1
= (CFStringRef
)val1
;
1404 CFStringRef bsd2
= (CFStringRef
)val2
;
1406 return CFStringCompare(bsd1
, bsd2
, 0);
1410 static CF_RETURNS_RETAINED CFStringRef
1411 pci_port(CFTypeRef slot_name
, int ift
, CFStringRef bsdName
)
1414 CFStringRef port_name
= NULL
;
1415 CFMutableArrayRef port_names
;
1418 CFStringRef match_keys
[2];
1419 CFTypeRef match_vals
[2];
1420 CFDictionaryRef match_dict
;
1421 CFDictionaryRef matching
;
1422 io_registry_entry_t slot
;
1423 io_iterator_t slot_iterator
= MACH_PORT_NULL
;
1425 match_keys
[0] = CFSTR("AAPL,slot-name");
1426 match_vals
[0] = slot_name
;
1428 match_dict
= CFDictionaryCreate(NULL
,
1429 (const void **)match_keys
,
1430 (const void **)match_vals
,
1432 &kCFTypeDictionaryKeyCallBacks
,
1433 &kCFTypeDictionaryValueCallBacks
);
1435 match_keys
[0] = CFSTR(kIOProviderClassKey
);
1436 match_vals
[0] = CFSTR("IOPCIDevice");
1438 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
1439 match_vals
[1] = match_dict
;
1441 // note: the "matching" dictionary will be consumed by the following
1442 matching
= CFDictionaryCreate(NULL
,
1443 (const void **)match_keys
,
1444 (const void **)match_vals
,
1445 sizeof(match_keys
)/sizeof(match_keys
[0]),
1446 &kCFTypeDictionaryKeyCallBacks
,
1447 &kCFTypeDictionaryValueCallBacks
);
1448 CFRelease(match_dict
);
1450 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &slot_iterator
);
1451 if (kr
!= kIOReturnSuccess
) {
1452 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1453 return MACH_PORT_NULL
;
1456 port_names
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1458 while ((slot
= IOIteratorNext(slot_iterator
)) != MACH_PORT_NULL
) {
1459 io_registry_entry_t child
;
1460 io_iterator_t child_iterator
= MACH_PORT_NULL
;
1462 kr
= IORegistryEntryCreateIterator(slot
,
1464 kIORegistryIterateRecursively
,
1466 if (kr
!= kIOReturnSuccess
) {
1467 SC_log(LOG_INFO
, "IORegistryEntryCreateIterator() failed, kr = 0x%x", kr
);
1468 CFRelease(port_names
);
1469 return MACH_PORT_NULL
;
1472 while ((child
= IOIteratorNext(child_iterator
)) != MACH_PORT_NULL
) {
1473 if (IOObjectConformsTo(child
, kIONetworkInterfaceClass
)) {
1474 CFMutableDictionaryRef interface_dict
= NULL
;
1476 (void) IORegistryEntryCreateCFProperties(child
, &interface_dict
, NULL
, kNilOptions
);
1477 if (interface_dict
!= NULL
) {
1478 CFNumberRef child_if_type
;
1479 int child_ift
= ift
;
1481 child_if_type
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1482 if (child_if_type
!= NULL
) {
1483 if (!isA_CFNumber(child_if_type
) ||
1484 !CFNumberGetValue(child_if_type
, kCFNumberIntType
, &child_ift
)) {
1485 // assume that it's a match
1490 if (ift
== child_ift
) {
1491 CFStringRef if_bsdName
;
1493 if_bsdName
= IODictionaryCopyBSDName(interface_dict
);
1494 if (if_bsdName
!= NULL
) {
1495 CFArrayAppendValue(port_names
, if_bsdName
);
1496 CFRelease(if_bsdName
);
1500 CFRelease(interface_dict
);
1503 IOObjectRelease(child
);
1505 IOObjectRelease(child_iterator
);
1506 IOObjectRelease(slot
);
1508 IOObjectRelease(slot_iterator
);
1510 n
= CFArrayGetCount(port_names
);
1512 CFArraySortValues(port_names
, CFRangeMake(0, n
), compare_bsdNames
, NULL
);
1513 n
= CFArrayGetFirstIndexOfValue(port_names
, CFRangeMake(0, n
), bsdName
);
1514 if (n
!= kCFNotFound
) {
1515 port_name
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%ld"), n
+ 1);
1519 CFRelease(port_names
);
1525 pci_slot_info(io_registry_entry_t interface
, int ift
, CFStringRef
*slot_name
, CFStringRef
*port_name
)
1527 CFStringRef bsd_name
= NULL
;
1528 CFMutableDictionaryRef interface_dict
= NULL
;
1530 CFTypeRef pci_slot_name
;
1535 (void) IORegistryEntryCreateCFProperties(interface
, &interface_dict
, NULL
, kNilOptions
);
1536 if (interface_dict
!= NULL
) {
1537 bsd_name
= IODictionaryCopyBSDName(interface_dict
);
1538 CFRelease(interface_dict
);
1541 if (bsd_name
== NULL
) {
1545 *slot_name
= pci_slot(interface
, &pci_slot_name
);
1546 if (*slot_name
!= NULL
) {
1547 if (pci_slot_name
!= NULL
) {
1548 *port_name
= pci_port(pci_slot_name
, ift
, bsd_name
);
1549 CFRelease(pci_slot_name
);
1554 CFRelease(bsd_name
);
1560 isBuiltin(io_registry_entry_t interface
)
1564 slot
= pci_slot(interface
, NULL
);
1566 // interfaces which have a "slot" are not built-in
1576 isBluetoothBuiltin(Boolean
*haveController
)
1578 Boolean builtin
= FALSE
;
1579 io_object_t hciController
;
1580 io_iterator_t iter
= MACH_PORT_NULL
;
1583 kr
= IOServiceGetMatchingServices(masterPort
,
1584 IOServiceMatching("IOBluetoothHCIController"),
1586 if ((kr
!= kIOReturnSuccess
) || (iter
== MACH_PORT_NULL
)) {
1587 if (kr
!= kIOReturnSuccess
) {
1588 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
1590 *haveController
= FALSE
;
1593 *haveController
= TRUE
;
1595 hciController
= IOIteratorNext(iter
);
1596 IOObjectRelease(iter
);
1597 if(hciController
!= MACH_PORT_NULL
) {
1598 #if !TARGET_OS_SIMULATOR
1599 CFNumberRef idVendor
;
1601 idVendor
= IORegistryEntryCreateCFProperty(hciController
, CFSTR(kUSBVendorID
), NULL
, 0);
1602 if (idVendor
!= NULL
) {
1605 if (isA_CFNumber(idVendor
) &&
1606 CFNumberGetValue(idVendor
, kCFNumberIntType
, &idVendorVal
) &&
1607 (idVendorVal
== kIOUSBVendorIDAppleComputer
)) {
1611 CFRelease(idVendor
);
1613 #endif // !TARGET_OS_SIMULATOR
1615 IOObjectRelease(hciController
);
1623 isThunderbolt(io_registry_entry_t interface
)
1627 val
= IORegistryEntrySearchCFProperty(interface
,
1629 CFSTR(kPCIThunderboltString
),
1631 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1642 processUSBInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1643 io_registry_entry_t interface
,
1644 CFDictionaryRef interface_dict
,
1645 io_registry_entry_t controller
,
1646 CFDictionaryRef controller_dict
,
1647 io_registry_entry_t bus
,
1648 CFDictionaryRef bus_dict
)
1650 #if TARGET_OS_SIMULATOR
1651 #pragma unused(interfacePrivate)
1652 #pragma unused(interface)
1653 #endif // TARGET_OS_SIMULATOR
1654 #pragma unused(interface_dict)
1655 #pragma unused(controller)
1656 #pragma unused(controller_dict)
1658 #pragma unused(bus_dict)
1659 #if !TARGET_OS_SIMULATOR
1661 if (interfacePrivate
->usb
.name
== NULL
) {
1662 interfacePrivate
->usb
.name
= IORegistryEntrySearchCFProperty(interface
,
1664 CFSTR(kUSBProductString
),
1666 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1668 if (interfacePrivate
->usb
.vid
== NULL
) {
1669 interfacePrivate
->usb
.vid
= IORegistryEntrySearchCFProperty(interface
,
1671 CFSTR(kUSBVendorID
),
1673 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1675 if (interfacePrivate
->usb
.pid
== NULL
) {
1676 interfacePrivate
->usb
.pid
= IORegistryEntrySearchCFProperty(interface
,
1678 CFSTR(kUSBProductID
),
1680 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1682 #endif // !TARGET_OS_SIMULATOR
1689 update_interface_name(SCNetworkInterfacePrivateRef interfacePrivate
,
1690 io_registry_entry_t interface
,
1693 Boolean updated
= FALSE
;
1696 // check if a "Product Name" has been provided
1697 val
= IORegistryEntrySearchCFProperty(interface
,
1699 CFSTR(kIOPropertyProductNameKey
),
1701 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1702 if ((val
== NULL
) && useUSBInfo
&& (interfacePrivate
->usb
.name
!= NULL
)) {
1703 // else, use "USB Product Name" if available
1704 val
= CFRetain(interfacePrivate
->usb
.name
);
1707 CFStringRef productName
;
1709 productName
= IOCopyCFStringValue(val
);
1712 if (productName
!= NULL
) {
1713 if (CFStringGetLength(productName
) > 0) {
1714 // if we have a [somewhat reasonable?] product name
1715 if (interfacePrivate
->name
!= NULL
) {
1716 CFRelease(interfacePrivate
->name
);
1718 interfacePrivate
->name
= CFRetain(productName
);
1719 if (interfacePrivate
->localized_name
!= NULL
) {
1720 CFRelease(interfacePrivate
->localized_name
);
1721 interfacePrivate
->localized_name
= NULL
;
1723 if (bundle
!= NULL
) {
1724 interfacePrivate
->localized_name
= copy_interface_string(bundle
, productName
, TRUE
);
1730 CFRelease(productName
);
1739 #pragma mark Interface enumeration
1742 typedef Boolean (*processInterface
)(SCNetworkInterfacePrivateRef interfacePrivate
,
1743 io_registry_entry_t interface
,
1744 CFDictionaryRef interface_dict
,
1745 io_registry_entry_t controller
,
1746 CFDictionaryRef controller_dict
,
1747 io_registry_entry_t bus
,
1748 CFDictionaryRef bus_dict
);
1752 merge_override(SCNetworkInterfacePrivateRef interfacePrivate
,
1753 io_registry_entry_t interface
,
1754 CFStringRef override
)
1759 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Device%@Overrides"), override
);
1760 val
= IORegistryEntrySearchCFProperty(interface
,
1764 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1767 if (isA_CFDictionary(val
)) {
1768 if (interfacePrivate
->overrides
== NULL
) {
1769 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
1771 &kCFTypeDictionaryKeyCallBacks
,
1772 &kCFTypeDictionaryValueCallBacks
);
1774 CFDictionarySetValue(interfacePrivate
->overrides
, override
, val
);
1784 processNetworkInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
1785 io_registry_entry_t interface
,
1786 CFDictionaryRef interface_dict
,
1787 io_registry_entry_t controller
,
1788 CFDictionaryRef controller_dict
,
1789 io_registry_entry_t bus
,
1790 CFDictionaryRef bus_dict
)
1800 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceType
));
1801 if (isA_CFNumber(num
) &&
1802 CFNumberGetValue(num
, kCFNumberIntType
, &ift
)) {
1803 interfacePrivate
->type
= CFRetain(num
);
1805 SC_log(LOG_INFO
, "no interface type: %@", interface_dict
);
1813 if (IOObjectConformsTo(controller
, "IO80211Controller") ||
1814 IOObjectConformsTo(controller
, "AirPortPCI" ) ||
1815 IOObjectConformsTo(controller
, "AirPortDriver" )) {
1816 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
1817 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1818 interfacePrivate
->sort_order
= kSortAirPort
;
1819 } else if (IOObjectConformsTo(controller
, "AppleThunderboltIPPort")) {
1820 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1821 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1822 interfacePrivate
->sort_order
= kSortThunderbolt
;
1823 } else if (IOObjectConformsTo(controller
, "IOBluetoothBNEPDriver")) {
1824 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1825 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1826 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1827 } else if (IOObjectConformsTo(controller
, "AppleUSBEthernetHost")) {
1828 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1829 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1830 interfacePrivate
->sort_order
= kSortTethered
;
1831 } else if (IOObjectConformsTo(controller
, "AppleUSBCDCECMData")) {
1832 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1833 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1834 interfacePrivate
->sort_order
= kSortWWANEthernet
;
1837 if (interfacePrivate
->interface_type
== NULL
) {
1838 val
= IORegistryEntrySearchCFProperty(interface
,
1840 CFSTR(kIOUserEthernetInterfaceRoleKey
),
1842 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1844 if (isA_CFString(val
)) {
1845 if (CFEqual(val
, CFSTR(BT_PAN_NAME
))) {
1846 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1847 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1848 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
1849 } else if (CFEqual(val
, CFSTR("Bluetooth PAN-NAP"))) {
1850 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1851 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1852 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
1853 } else if (CFEqual(val
, CFSTR("Bluetooth P2P"))) {
1854 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1855 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1856 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
1857 } else if (CFEqual(val
, CFSTR("CarPlay"))) {
1858 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1859 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1860 interfacePrivate
->sort_order
= kSortCarPlay
;
1869 if (interfacePrivate
->interface_type
== NULL
) {
1870 val
= IORegistryEntrySearchCFProperty(interface
,
1872 CFSTR(kUSBSupportsIPhoneOS
),
1874 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1876 if (isA_CFBoolean(val
) && CFBooleanGetValue(val
)) {
1877 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1878 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1879 interfacePrivate
->sort_order
= kSortTethered
;
1885 #endif // TARGET_OS_OSX
1887 if (interfacePrivate
->interface_type
== NULL
) {
1888 str
= IODictionaryCopyCFStringValue(bus_dict
, CFSTR("name"));
1890 if (CFEqual(str
, CFSTR("radio"))) {
1891 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
; // ??
1892 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1893 interfacePrivate
->sort_order
= kSortOtherWireless
;
1900 if (interfacePrivate
->interface_type
== NULL
) {
1901 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
1902 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
;
1903 interfacePrivate
->sort_order
= kSortEthernet
;
1905 // BOND support only enabled for ethernet devices
1906 interfacePrivate
->supportsBond
= TRUE
;
1909 // enable Bridge support
1910 interfacePrivate
->supportsBridge
= TRUE
;
1913 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOBuiltin
)));
1915 val
= isA_CFBoolean(CFDictionaryGetValue(interface_dict
, CFSTR(kIOPrimaryInterface
)));
1918 interfacePrivate
->builtin
= CFBooleanGetValue(val
);
1920 interfacePrivate
->builtin
= isBuiltin(interface
);
1923 if (!interfacePrivate
->builtin
&&
1924 CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1925 // always treat AirPort interfaces as built-in
1926 interfacePrivate
->builtin
= TRUE
;
1930 interfacePrivate
->location
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOLocation
));
1931 if ((interfacePrivate
->location
!= NULL
) &&
1932 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1933 CFRelease(interfacePrivate
->location
);
1934 interfacePrivate
->location
= NULL
;
1938 num
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOFeatures
));
1939 if (isA_CFNumber(num
) &&
1940 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
1941 if (iVal
& (kIONetworkFeatureHardwareVlan
| kIONetworkFeatureSoftwareVlan
)) {
1942 interfacePrivate
->supportsVLAN
= TRUE
;
1947 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
)) {
1948 interfacePrivate
->localized_key
= CFSTR("airport");
1949 } else if (interfacePrivate
->sort_order
== kSortThunderbolt
) {
1950 if ((interfacePrivate
->location
== NULL
) ||
1951 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1952 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
1954 interfacePrivate
->localized_key
= CFSTR("multithunderbolt");
1955 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1957 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
) {
1958 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
1959 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
) {
1960 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
1961 } else if (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
) {
1962 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
1963 } else if (interfacePrivate
->sort_order
== kSortOtherWireless
) {
1964 interfacePrivate
->localized_key
= CFSTR("wireless");
1965 interfacePrivate
->localized_arg1
= CFRetain(CFSTR("")); // ??
1966 } else if (interfacePrivate
->builtin
) {
1967 if ((interfacePrivate
->location
== NULL
) ||
1968 (CFStringGetLength(interfacePrivate
->location
) == 0)) {
1969 interfacePrivate
->localized_key
= CFSTR("ether");
1971 interfacePrivate
->localized_key
= CFSTR("multiether");
1972 interfacePrivate
->localized_arg1
= CFRetain(interfacePrivate
->location
);
1975 CFStringRef provider
;
1977 // check provider class
1978 provider
= IORegistryEntrySearchCFProperty(interface
,
1980 CFSTR(kIOProviderClassKey
),
1982 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
1983 if (provider
!= NULL
) {
1984 if (CFEqual(provider
, CFSTR("IOPCIDevice"))) {
1985 CFStringRef port_name
;
1986 CFStringRef slot_name
;
1988 // set interface "name"
1989 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
1990 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
1991 if (isThunderbolt(interface
)) {
1992 if (port_name
== NULL
) {
1993 interfacePrivate
->localized_key
= CFSTR("thunderbolt-ether");
1994 interfacePrivate
->localized_arg1
= slot_name
;
1996 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multiether");
1997 interfacePrivate
->localized_arg1
= slot_name
;
1998 interfacePrivate
->localized_arg2
= port_name
;
2002 if (port_name
== NULL
) {
2003 interfacePrivate
->localized_key
= CFSTR("pci-ether");
2004 interfacePrivate
->localized_arg1
= slot_name
;
2006 interfacePrivate
->localized_key
= CFSTR("pci-multiether");
2007 interfacePrivate
->localized_arg1
= slot_name
;
2008 interfacePrivate
->localized_arg2
= port_name
;
2013 io_registry_entry_t node
= interface
;
2015 while (provider
!= NULL
) {
2016 #if !TARGET_OS_SIMULATOR
2017 if (CFEqual(provider
, CFSTR(kIOUSBDeviceClassName
)) ||
2018 CFEqual(provider
, CFSTR(kIOUSBInterfaceClassName
)) ||
2019 CFEqual(provider
, CFSTR(kIOUSBHostInterfaceClassName
))) {
2020 // get USB info (if available)
2021 processUSBInterface(interfacePrivate
,
2029 // set interface "name"
2030 if (!update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2031 interfacePrivate
->localized_key
= CFSTR("usb-ether");
2032 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2036 #endif // !TARGET_OS_SIMULATOR
2038 if (node
== interface
) {
2040 } else if (node
== controller
) {
2046 CFRelease(provider
);
2047 provider
= IORegistryEntrySearchCFProperty(node
,
2049 CFSTR(kIOProviderClassKey
),
2051 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2054 if (interfacePrivate
->localized_key
== NULL
) {
2055 update_interface_name(interfacePrivate
, interface
, FALSE
);
2059 if (provider
!= NULL
) CFRelease(provider
);
2062 if (interfacePrivate
->localized_key
== NULL
) {
2063 // if no provider, not a PCI device, or no slot information
2064 interfacePrivate
->localized_key
= CFSTR("generic-ether");
2065 interfacePrivate
->localized_arg1
= IODictionaryCopyBSDName(interface_dict
);
2072 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
2075 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
2078 interfacePrivate
->builtin
= isBuiltin(interface
);
2081 interfacePrivate
->sort_order
= kSortFireWire
;
2084 if (interfacePrivate
->builtin
) {
2085 interfacePrivate
->localized_key
= CFSTR("firewire");
2087 CFStringRef port_name
;
2088 CFStringRef slot_name
;
2090 // set interface "name"
2091 if (!update_interface_name(interfacePrivate
, interface
, FALSE
) &&
2092 pci_slot_info(interface
, ift
, &slot_name
, &port_name
)) {
2093 if (isThunderbolt(interface
)) {
2094 if (port_name
== NULL
) {
2095 interfacePrivate
->localized_key
= CFSTR("thunderbolt-firewire");
2096 interfacePrivate
->localized_arg1
= slot_name
;
2098 interfacePrivate
->localized_key
= CFSTR("thunderbolt-multifirewire");
2099 interfacePrivate
->localized_arg1
= slot_name
;
2100 interfacePrivate
->localized_arg2
= port_name
;
2103 if (port_name
== NULL
) {
2104 interfacePrivate
->localized_key
= CFSTR("pci-firewire");
2105 interfacePrivate
->localized_arg1
= slot_name
;
2107 interfacePrivate
->localized_key
= CFSTR("pci-multifirewire");
2108 interfacePrivate
->localized_arg1
= slot_name
;
2109 interfacePrivate
->localized_arg2
= port_name
;
2117 SC_log(LOG_INFO
, "unknown interface type = %d", ift
);
2122 interfacePrivate
->entity_device
= IODictionaryCopyBSDName(interface_dict
);
2124 // Hardware (MAC) address
2125 data
= CFDictionaryGetValue(controller_dict
, CFSTR(kIOMACAddress
));
2126 if (isA_CFData(data
)) {
2127 interfacePrivate
->address
= CFRetain(data
);
2131 str
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceNamePrefix
));
2132 if (isA_CFString(str
)) {
2133 interfacePrivate
->prefix
= CFRetain(str
);
2137 num
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOInterfaceUnit
));
2138 if (isA_CFNumber(num
) &&
2139 CFNumberGetValue(num
, kCFNumberIntType
, & iVal
)) {
2140 interfacePrivate
->unit
= CFRetain(num
);
2143 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2144 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2151 set_connection_script(SCNetworkInterfacePrivateRef interfacePrivate
, CFStringRef script
)
2153 CFDictionaryRef dict
;
2154 CFMutableDictionaryRef newDict
;
2156 if (interfacePrivate
->overrides
== NULL
) {
2157 interfacePrivate
->overrides
= CFDictionaryCreateMutable(NULL
,
2159 &kCFTypeDictionaryKeyCallBacks
,
2160 &kCFTypeDictionaryValueCallBacks
);
2163 dict
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2165 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
2167 newDict
= CFDictionaryCreateMutable(NULL
,
2169 &kCFTypeDictionaryKeyCallBacks
,
2170 &kCFTypeDictionaryValueCallBacks
);
2172 if (script
!= NULL
) {
2173 CFDictionarySetValue(newDict
, kSCPropNetModemConnectionScript
, script
);
2175 CFDictionaryRemoveValue(newDict
, kSCPropNetModemConnectionScript
);
2177 if (CFDictionaryGetCount(newDict
) > 0) {
2178 CFDictionarySetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
, newDict
);
2180 CFDictionaryRemoveValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2184 if (CFDictionaryGetCount(interfacePrivate
->overrides
) == 0) {
2185 CFRelease(interfacePrivate
->overrides
);
2186 interfacePrivate
->overrides
= NULL
;
2193 is_valid_connection_script(CFStringRef script
)
2195 char ccl
[MAXPATHLEN
];
2196 char path
[MAXPATHLEN
];
2197 sysdir_search_path_enumeration_state state
;
2199 (void) _SC_cfstring_to_cstring(script
,
2202 kCFStringEncodingUTF8
);
2204 state
= sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_LIBRARY
,
2205 SYSDIR_DOMAIN_MASK_LOCAL
|SYSDIR_DOMAIN_MASK_SYSTEM
);
2206 while ((state
= sysdir_get_next_search_path_enumeration(state
, path
))) {
2208 struct stat statBuf
;
2210 if (ccl
[0] == '/') {
2211 path
[0] = '\0'; // if modemCCL is a full path
2213 strlcat(path
, "/Modem Scripts/", sizeof(path
));
2215 strlcat(path
, ccl
, sizeof(path
));
2217 if (stat(path
, &statBuf
) != 0) {
2218 if (errno
== ENOENT
) {
2222 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2225 if (S_ISREG(statBuf
.st_mode
)) {
2226 // if we have a valid CCL script
2230 #define BUNDLE_EXT ".ccl"
2231 #define BUNDLE_EXT_LEN sizeof(BUNDLE_EXT) - 1
2236 if ((n
<= BUNDLE_EXT_LEN
) ||
2237 (strstr(&path
[n
- BUNDLE_EXT_LEN
], BUNDLE_EXT
) == NULL
)) {
2238 strlcat(path
, BUNDLE_EXT
, sizeof(path
));
2239 if (stat(path
, &statBuf
) != 0) {
2240 if (errno
== ENOENT
) {
2244 SC_log(LOG_INFO
, "stat() failed: %s", strerror(errno
));
2248 if (S_ISDIR(statBuf
.st_mode
)) {
2249 // if we have a valid CCL bundle
2259 processSerialInterface(SCNetworkInterfacePrivateRef interfacePrivate
,
2260 io_registry_entry_t interface
,
2261 CFDictionaryRef interface_dict
,
2262 io_registry_entry_t controller
,
2263 CFDictionaryRef controller_dict
,
2264 io_registry_entry_t bus
,
2265 CFDictionaryRef bus_dict
)
2267 CFStringRef base
= NULL
;
2269 Boolean isModem
= FALSE
;
2270 Boolean isWWAN
= FALSE
;
2271 CFStringRef modemCCL
= NULL
;
2275 // check if initializing
2276 val
= IORegistryEntrySearchCFProperty(interface
,
2278 kSCNetworkInterfaceInitializingKey
,
2280 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2282 Boolean initializing
;
2284 initializing
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2287 return FALSE
; // if this interface is still initializing
2292 val
= IORegistryEntrySearchCFProperty(interface
,
2296 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2298 isWWAN
= isA_CFBoolean(val
) && CFBooleanGetValue(val
);
2303 interfacePrivate
->entity_device
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYDeviceKey
));
2304 if (interfacePrivate
->entity_device
== NULL
) {
2308 base
= IODictionaryCopyCFStringValue(interface_dict
, CFSTR(kIOTTYBaseNameKey
));
2310 base
= CFRetain(interfacePrivate
->entity_device
);
2316 * Exclude ports named "irda" because otherwise the IrDA ports on the
2317 * original iMac (rev's A through D) show up as serial ports. Given
2318 * that only the rev A actually had an IrDA port, and Mac OS X doesn't
2319 * even support it, these ports definitely shouldn't be listed.
2321 if (CFStringCompare(base
,
2323 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
2327 if (IOStringValueHasPrefix(base
, CFSTR("bluetooth"))) {
2328 Boolean haveController
= FALSE
;
2331 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
2332 interfacePrivate
->sort_order
= kSortBluetooth
;
2333 interfacePrivate
->builtin
= isBluetoothBuiltin(&haveController
);
2334 if (!haveController
) {
2335 // if device with no controller present
2338 } else if (IOStringValueHasPrefix(base
, CFSTR("irda-ircomm"))) {
2340 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
2341 interfacePrivate
->sort_order
= kSortIrDA
;
2342 } else if (isWWAN
) {
2344 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
2345 interfacePrivate
->sort_order
= kSortWWAN
;
2348 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
2349 interfacePrivate
->sort_order
= kSortModem
;
2353 interfacePrivate
->entity_type
= kSCEntNetModem
;
2355 // Entity (Hardware)
2356 ift
= CFDictionaryGetValue(interface_dict
, CFSTR(kIOSerialBSDTypeKey
));
2357 if (!isA_CFString(ift
)) {
2361 if (CFEqual(ift
, CFSTR(kIOSerialBSDModemType
))) {
2365 if (CFEqual(base
, CFSTR("modem"))) {
2366 interfacePrivate
->builtin
= TRUE
;
2367 interfacePrivate
->sort_order
= kSortInternalModem
;
2368 } else if (CFEqual(base
, CFSTR("usbmodem"))) {
2369 interfacePrivate
->sort_order
= kSortUSBModem
;
2371 } else if (CFEqual(ift
, CFSTR(kIOSerialBSDRS232Type
))) {
2373 interfacePrivate
->sort_order
= kSortSerialPort
;
2378 // configuration [PPP] template override (now deprecated, use NetworkConfigurationOverrides)
2379 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypePPP
);
2381 // configuration [Modem] template override (now deprecated, use NetworkConfigurationOverrides)
2382 merge_override(interfacePrivate
, interface
, kSCNetworkInterfaceTypeModem
);
2384 // look for modem CCL, unique identifier
2385 if (interfacePrivate
->overrides
!= NULL
) {
2386 val
= CFDictionaryGetValue(interfacePrivate
->overrides
, kSCNetworkInterfaceTypeModem
);
2388 CFStringRef uniqueID
;
2390 modemCCL
= CFDictionaryGetValue(val
, kSCPropNetModemConnectionScript
);
2391 modemCCL
= isA_CFString(modemCCL
);
2393 uniqueID
= CFDictionaryGetValue(val
, CFSTR("UniqueIdentifier"));
2394 uniqueID
= isA_CFString(uniqueID
);
2395 if (uniqueID
!= NULL
) {
2396 // retain the device's base name and the unique id
2397 CFRelease(interfacePrivate
->entity_device
);
2398 interfacePrivate
->entity_device
= CFRetain(base
);
2399 interfacePrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, uniqueID
);
2404 // if not part of the NetworkConfigurationOverrides/DeviceModemOverrides, look
2405 // a bit harder for the modem CCL
2406 if (modemCCL
== NULL
) {
2407 val
= IORegistryEntrySearchCFProperty(interface
,
2411 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2413 modemCCL
= IOCopyCFStringValue(val
);
2414 if (modemCCL
!= NULL
) {
2415 set_connection_script(interfacePrivate
, modemCCL
);
2416 CFRelease(modemCCL
);
2424 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeIrDA
)) {
2425 interfacePrivate
->localized_key
= CFSTR("irda");
2426 } else if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBluetooth
)) {
2427 interfacePrivate
->localized_key
= CFSTR("bluetooth");
2429 CFStringRef localized
= NULL
;
2430 CFStringRef name
= NULL
;
2431 CFMutableStringRef port
;
2433 port
= CFStringCreateMutableCopy(NULL
, 0, base
);
2434 CFStringLowercase(port
, NULL
);
2437 CFStringAppend(port
, CFSTR("-port"));
2440 // set non-localized name
2441 if (bundle
!= NULL
) {
2442 name
= copy_interface_string(bundle
, port
, FALSE
);
2445 if (!CFEqual(port
, name
)) {
2446 // if [English] localization available
2447 interfacePrivate
->name
= name
;
2449 // if no [English] localization available, use TTY base name
2451 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2454 interfacePrivate
->name
= CFStringCreateCopy(NULL
, base
);
2457 // set localized name
2458 if (bundle
!= NULL
) {
2459 localized
= copy_interface_string(bundle
, port
, TRUE
);
2461 if (localized
!= NULL
) {
2462 if (!CFEqual(port
, localized
)) {
2463 // if localization available
2464 interfacePrivate
->localized_name
= localized
;
2466 // if no localization available, use TTY base name
2467 CFRelease(localized
);
2468 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2471 interfacePrivate
->localized_name
= CFStringCreateCopy(NULL
, base
);
2474 if (!isModem
|| !CFEqual(base
, CFSTR("modem"))) {
2475 // get USB info (if available)
2476 processUSBInterface(interfacePrivate
,
2484 // set interface "name"
2485 if (update_interface_name(interfacePrivate
, interface
, TRUE
)) {
2486 // if "ModemCCL" not provided, also check if the product/interface
2487 // name matches a CCL script
2488 if ((modemCCL
== NULL
) &&
2489 is_valid_connection_script(interfacePrivate
->name
)) {
2490 set_connection_script(interfacePrivate
, interfacePrivate
->name
);
2502 if (!ok
&& (interfacePrivate
->entity_device
!= NULL
)) {
2503 CFRelease(interfacePrivate
->entity_device
);
2504 interfacePrivate
->entity_device
= NULL
;
2506 if (base
!= NULL
) CFRelease(base
);
2513 __SC_IORegistryEntryCopyPath(io_registry_entry_t entry
, const io_name_t plane
)
2516 * Create a path for a registry entry.
2520 CFStringRef str
= NULL
;
2522 status
= IORegistryEntryGetPath(entry
, plane
, path
);
2523 if (status
== kIOReturnSuccess
) {
2524 str
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
2525 } else if (status
== kIOReturnBadArgument
) {
2526 io_registry_entry_t parent
;
2528 status
= IORegistryEntryGetParentEntry(entry
, plane
, &parent
);
2529 if (status
== kIOReturnSuccess
) {
2530 CFStringRef str_parent
;
2532 str_parent
= __SC_IORegistryEntryCopyPath(parent
, plane
);
2533 if (str_parent
!= NULL
) {
2536 status
= IORegistryEntryGetNameInPlane(entry
, plane
, name
);
2537 if (status
== kIOReturnSuccess
) {
2540 status
= IORegistryEntryGetLocationInPlane(entry
, plane
, location
);
2541 if (status
== kIOReturnSuccess
) {
2542 str
= CFStringCreateWithFormat(NULL
,
2549 str
= CFStringCreateWithFormat(NULL
,
2557 CFRelease(str_parent
);
2560 IOObjectRelease(parent
);
2567 static CFMutableDictionaryRef
2568 copyIORegistryProperties(io_registry_entry_t reg_ent
, const CFStringRef
*reg_keys
, CFIndex numKeys
)
2571 CFMutableDictionaryRef reg_dict
= NULL
;
2572 CFTypeRef value
= NULL
;
2574 reg_dict
= CFDictionaryCreateMutable(NULL
,
2576 &kCFTypeDictionaryKeyCallBacks
,
2577 &kCFTypeDictionaryValueCallBacks
);
2579 for (; idx
< numKeys
; idx
++) {
2580 value
= IORegistryEntryCreateCFProperty(reg_ent
, reg_keys
[idx
], NULL
, 0);
2581 if (value
!= NULL
) {
2582 CFDictionaryAddValue(reg_dict
, reg_keys
[idx
], value
);
2590 static SCNetworkInterfaceRef
2591 createInterface(io_registry_entry_t interface
, processInterface func
,
2592 CFStringRef hidden_key
)
2594 io_registry_entry_t bus
= MACH_PORT_NULL
;
2595 CFMutableDictionaryRef bus_dict
= NULL
;
2596 io_registry_entry_t controller
= MACH_PORT_NULL
;
2597 CFMutableDictionaryRef controller_dict
= NULL
;
2598 uint64_t entryID
= 0;
2599 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
2600 CFMutableDictionaryRef interface_dict
= NULL
;
2605 const CFStringRef interface_dict_keys
[] = {
2606 CFSTR(kIOInterfaceType
),
2608 CFSTR(kIOBSDNameKey
),
2609 CFSTR(kIOPrimaryInterface
),
2610 CFSTR(kIOInterfaceNamePrefix
),
2611 CFSTR(kIOInterfaceUnit
),
2612 CFSTR(kIOTTYDeviceKey
),
2613 CFSTR(kIOTTYBaseNameKey
),
2614 CFSTR(kIOSerialBSDTypeKey
),
2618 const CFStringRef controller_dict_keys
[] = {
2620 CFSTR(kIOMACAddress
)
2623 const CFStringRef bus_dict_keys
[] = {
2627 if (hidden_key
!= NULL
) {
2629 val
= IORegistryEntrySearchCFProperty(interface
,
2633 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2636 goto done
; // if this interface should not be exposed
2640 interface_dict
= copyIORegistryProperties(interface
,
2641 interface_dict_keys
,
2642 sizeof(interface_dict_keys
)/sizeof(interface_dict_keys
[0]));
2644 // get the controller node
2645 kr
= IORegistryEntryGetParentEntry(interface
, kIOServicePlane
, &controller
);
2646 if (kr
!= kIOReturnSuccess
) {
2647 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2651 controller_dict
= copyIORegistryProperties(controller
,
2652 controller_dict_keys
,
2653 sizeof(controller_dict_keys
)/sizeof(controller_dict_keys
[0]));
2656 kr
= IORegistryEntryGetParentEntry(controller
, kIOServicePlane
, &bus
);
2657 if (kr
!= kIOReturnSuccess
) {
2658 SC_log(LOG_INFO
, "IORegistryEntryGetParentEntry() failed, kr = 0x%x", kr
);
2662 bus_dict
= copyIORegistryProperties(bus
,
2664 sizeof(bus_dict_keys
)/sizeof(bus_dict_keys
[0]));
2666 // get the registry entry ID
2667 kr
= IORegistryEntryGetRegistryEntryID(interface
, &entryID
);
2668 if (kr
!= kIOReturnSuccess
) {
2669 SC_log(LOG_INFO
, "IORegistryEntryGetRegistryEntryID() failed, kr = 0x%x", kr
);
2673 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
2674 assert(interfacePrivate
!= NULL
);
2675 interfacePrivate
->path
= __SC_IORegistryEntryCopyPath(interface
, kIOServicePlane
);
2676 interfacePrivate
->entryID
= entryID
;
2678 // configuration [PPP, Modem, DNS, IPv4, IPv6, Proxies, SMB] template overrides
2679 val
= IORegistryEntrySearchCFProperty(interface
,
2681 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
2683 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2685 if (isA_CFDictionary(val
)) {
2686 interfacePrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, val
);
2691 if ((*func
)(interfacePrivate
, interface
, interface_dict
, controller
, controller_dict
, bus
, bus_dict
)) {
2692 // get user-notification / auto-configuration preference
2693 val
= IORegistryEntrySearchCFProperty(interface
,
2695 kSCNetworkInterfaceConfigurationActionKey
,
2697 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2699 if (isA_CFString(val
)) {
2700 interfacePrivate
->configurationAction
= CFRetain(val
);
2705 // get HiddenConfiguration preference
2706 val
= IORegistryEntrySearchCFProperty(interface
,
2708 kSCNetworkInterfaceHiddenConfigurationKey
,
2710 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2712 interfacePrivate
->hidden
= TRUE
;
2716 #if TARGET_OS_IPHONE
2717 // get TrustRequired preference
2718 val
= IORegistryEntrySearchCFProperty(interface
,
2720 kSCNetworkInterfaceTrustRequiredKey
,
2722 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
2724 if (isA_CFBoolean(val
)) {
2725 interfacePrivate
->trustRequired
= CFBooleanGetValue(val
);
2729 #endif // TARGET_OS_IPHONE
2731 CFRelease(interfacePrivate
);
2732 interfacePrivate
= NULL
;
2737 if (interface_dict
!= NULL
) CFRelease(interface_dict
);
2739 if (controller
!= MACH_PORT_NULL
) IOObjectRelease(controller
);
2740 if (controller_dict
!= NULL
) CFRelease(controller_dict
);
2742 if (bus
!= MACH_PORT_NULL
) IOObjectRelease(bus
);
2743 if (bus_dict
!= NULL
) CFRelease(bus_dict
);
2745 return (SCNetworkInterfaceRef
)interfacePrivate
;
2749 static CF_RETURNS_RETAINED CFArrayRef
2750 findMatchingInterfaces(CFDictionaryRef matching
,
2751 processInterface func
,
2752 CFStringRef hidden_key
,
2753 Boolean keep_pre_configured
)
2755 CFMutableArrayRef interfaces
;
2756 io_registry_entry_t interface
;
2758 io_iterator_t iterator
= MACH_PORT_NULL
;
2761 * A reference to the "matching" dictionary will be consumed by the
2762 * the call to IOServiceGetMatchingServices so we bump up the retain
2767 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &iterator
);
2768 if (kr
!= kIOReturnSuccess
) {
2769 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
2773 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2775 while ((interface
= IOIteratorNext(iterator
)) != MACH_PORT_NULL
) {
2776 SCNetworkInterfaceRef match
;
2778 match
= createInterface(interface
, func
, hidden_key
);
2779 if (match
!= NULL
) {
2780 if (keep_pre_configured
|| !_SCNetworkInterfaceIsApplePreconfigured(match
)) {
2781 CFArrayAppendValue(interfaces
, match
);
2786 IOObjectRelease(interface
);
2789 IOObjectRelease(iterator
);
2796 #pragma mark helper functions
2800 findConfiguration(CFStringRef interface_type
)
2802 for (size_t i
= 0; i
< sizeof(configurations
)/sizeof(configurations
[0]); i
++) {
2803 if (CFEqual(interface_type
, *configurations
[i
].interface_type
)) {
2814 __SCNetworkInterfaceGetDefaultConfigurationType(SCNetworkInterfaceRef interface
)
2816 CFIndex interfaceIndex
;
2817 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2819 if (interfacePrivate
->serviceID
== NULL
) {
2820 // if not associated with a service (yet)
2821 _SCErrorSet(kSCStatusInvalidArgument
);
2825 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2826 if (interfaceIndex
== kCFNotFound
) {
2827 // unknown interface type, use per-service configuration preferences
2828 return interfacePrivate
->interface_type
; // entity
2831 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
2832 // if configuration information can be associated with this interface type
2833 return *configurations
[interfaceIndex
].entity_hardware
;
2836 _SCErrorSet(kSCStatusInvalidArgument
);
2843 __SCNetworkInterfaceIsValidExtendedConfigurationType(SCNetworkInterfaceRef interface
,
2844 CFStringRef extendedType
,
2845 Boolean requirePerInterface
)
2847 CFStringRef defaultType
;
2848 CFIndex extendedIndex
;
2849 CFIndex interfaceIndex
;
2850 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2851 Boolean isL2TP
= FALSE
;
2854 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2855 if (defaultType
== NULL
) {
2859 if (CFEqual(extendedType
, defaultType
)) {
2860 // extended and default configuration types cannot conflict
2864 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2865 if (interfaceIndex
== kCFNotFound
) {
2866 // configuration information for unknown interface type's
2867 // are stored along with the service and we don't allow
2868 // per-service extended configurations
2872 if (CFEqual(extendedType
, kSCEntNetIPSec
)) {
2873 CFStringRef interfaceType
;
2875 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
2876 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2877 SCNetworkInterfaceRef child
;
2879 child
= SCNetworkInterfaceGetInterface(interface
);
2880 if (child
!= NULL
) {
2881 interfaceType
= SCNetworkInterfaceGetInterfaceType(child
);
2882 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2889 if (requirePerInterface
&&
2890 !configurations
[interfaceIndex
].per_interface_config
&&
2892 // we don't allow per-service extended configurations (except
2893 // that we do allow IPSec as an extended type for PPP->L2TP)
2897 extendedIndex
= findConfiguration(extendedType
);
2898 if ((extendedIndex
!= kCFNotFound
) && !isL2TP
) {
2899 // extended type cannot match a known interface type (except
2900 // that we do allow IPSec as an extended type for PPP->L2TP)
2906 * Should we check/match and specifically allow known extended
2907 * configuration types (e.g. EAPOL)?
2909 * Should we check/match and specifically block known internal
2910 * configuration types (e.g. QoSMarking)?
2912 * Lastly, should we ensure that any non-standard extended configuration
2913 * types be of the form com.myCompany.myType?
2922 _SCErrorSet(kSCStatusInvalidArgument
);
2929 CFStringRef defaultType
;
2930 CFMutableArrayRef types
;
2931 } extendedConfiguration
, *extendedConfigurationRef
;
2935 __addExtendedConfigurationType(const void *key
, const void *value
, void *context
)
2937 #pragma unused(value)
2938 CFStringRef extendedType
= (CFStringRef
)key
;
2939 extendedConfigurationRef myContextRef
= (extendedConfigurationRef
)context
;
2941 if (CFEqual(extendedType
, myContextRef
->defaultType
)) {
2942 // do not include the default configuration type
2946 if (CFArrayContainsValue(myContextRef
->types
,
2947 CFRangeMake(0, CFArrayGetCount(myContextRef
->types
)),
2949 // if extendedType already has already been added
2953 CFArrayAppendValue(myContextRef
->types
, extendedType
);
2960 findPerInterfaceConfiguration(SCNetworkInterfaceRef interface
)
2962 CFIndex interfaceIndex
;
2963 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2965 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
2966 if (interfaceIndex
== kCFNotFound
) {
2967 // if per-service (not per interface) configuration
2971 if (!configurations
[interfaceIndex
].per_interface_config
) {
2972 // if per-interface configuration not allowed
2976 return interfaceIndex
;
2980 static CF_RETURNS_RETAINED CFArrayRef
2981 extendedConfigurationTypes(SCNetworkInterfaceRef interface
)
2984 CFIndex interfaceIndex
;
2985 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
2986 extendedConfiguration myContext
;
2987 SCNetworkServiceRef service
;
2991 myContext
.defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
2992 if (myContext
.defaultType
== NULL
) {
2993 myContext
.types
= NULL
;
2997 myContext
.types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
2999 if (interfacePrivate
->serviceID
== NULL
) {
3000 // if not associated with a service (yet)
3004 interfaceIndex
= findPerInterfaceConfiguration(interface
);
3005 if (interfaceIndex
== kCFNotFound
) {
3006 // if no per-interface configuration
3010 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3011 interfacePrivate
->prefs
,
3012 interfacePrivate
->serviceID
,
3015 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3016 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3018 for (i
= 0; i
< n
; i
++) {
3019 CFDictionaryRef configs
;
3022 CFArrayRef services
;
3023 SCNetworkSetRef set
;
3025 set
= CFArrayGetValueAtIndex(sets
, i
);
3026 services
= SCNetworkSetCopyServices(set
);
3027 found
= CFArrayContainsValue(services
,
3028 CFRangeMake(0, CFArrayGetCount(services
)),
3030 CFRelease(services
);
3036 // add stored extended configuration types
3037 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3038 SCNetworkSetGetSetID(set
), // set
3039 interfacePrivate
->entity_device
, // service
3041 configs
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
3043 if (isA_CFDictionary(configs
)) {
3044 CFDictionaryApplyFunction(configs
,
3045 __addExtendedConfigurationType
,
3049 // add not-yet-stored extended configuration types
3050 if (interfacePrivate
->unsaved
!= NULL
) {
3051 CFDictionaryApplyFunction(interfacePrivate
->unsaved
,
3052 __addExtendedConfigurationType
,
3060 if (sets
!= NULL
) CFRelease(sets
);
3064 return myContext
.types
;
3068 stringCreateArray(CFStringRef str
)
3070 return (CFArrayCreate(NULL
, (const void **)&str
, 1, &kCFTypeArrayCallBacks
));
3074 copyPerInterfaceConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3075 CFStringRef extendedType
)
3077 CFMutableArrayRef array
= NULL
;
3081 SCNetworkServiceRef service
;
3084 // known interface type, per-interface configuration preferences
3086 // 1. look for all sets which contain the associated service
3087 // 2. add a per-set path for the interface configuration for
3090 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
3091 interfacePrivate
->prefs
,
3092 interfacePrivate
->serviceID
,
3093 (SCNetworkInterfaceRef
)interfacePrivate
);
3095 sets
= SCNetworkSetCopyAll(interfacePrivate
->prefs
);
3096 n
= (sets
!= NULL
) ? CFArrayGetCount(sets
) : 0;
3098 for (i
= 0; i
< n
; i
++) {
3099 CFArrayRef services
;
3100 SCNetworkSetRef set
;
3102 set
= CFArrayGetValueAtIndex(sets
, i
);
3103 services
= SCNetworkSetCopyServices(set
);
3104 if (CFArrayContainsValue(services
,
3105 CFRangeMake(0, CFArrayGetCount(services
)),
3107 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
3108 SCNetworkSetGetSetID(set
), // set
3109 interfacePrivate
->entity_device
, // service
3110 extendedType
); // entity
3111 if (array
== NULL
) {
3112 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3114 CFArrayAppendValue(array
, path
);
3117 CFRelease(services
);
3121 if (sets
!= NULL
) CFRelease(sets
);
3127 copyConfigurationPaths(SCNetworkInterfacePrivateRef interfacePrivate
,
3128 CFStringRef extendedType
)
3130 CFArrayRef array
= NULL
;
3131 CFIndex interfaceIndex
;
3134 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3135 if (interfaceIndex
== kCFNotFound
) {
3136 // unknown interface type, use per-service configuration preferences
3137 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3138 interfacePrivate
->serviceID
, // service
3139 extendedType
); // entity
3140 array
= stringCreateArray(path
);
3144 else if (!configurations
[interfaceIndex
].per_interface_config
) {
3145 // known interface type, per-service configuration preferences
3146 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
3147 interfacePrivate
->serviceID
, // service
3148 extendedType
); // entity
3149 array
= stringCreateArray(path
);
3153 else if (interfacePrivate
->serviceID
!= NULL
) {
3154 array
= copyPerInterfaceConfigurationPaths(interfacePrivate
, extendedType
);
3162 #pragma mark SCNetworkInterface <--> preferences entity
3167 __SCNetworkInterfaceCopyInterfaceEntity(SCNetworkInterfaceRef interface
)
3169 CFMutableDictionaryRef entity
;
3170 CFIndex interfaceIndex
;
3171 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3173 entity
= CFDictionaryCreateMutable(NULL
,
3175 &kCFTypeDictionaryKeyCallBacks
,
3176 &kCFTypeDictionaryValueCallBacks
);
3177 if (interfacePrivate
->entity_type
!= NULL
) {
3178 CFDictionarySetValue(entity
,
3179 kSCPropNetInterfaceType
,
3180 interfacePrivate
->entity_type
);
3182 if (interfacePrivate
->entity_subtype
!= NULL
) {
3183 CFDictionarySetValue(entity
,
3184 kSCPropNetInterfaceSubType
,
3185 interfacePrivate
->entity_subtype
);
3187 if (interfacePrivate
->entity_device
!= NULL
) {
3188 CFDictionarySetValue(entity
,
3189 kSCPropNetInterfaceDeviceName
,
3190 interfacePrivate
->entity_device
);
3192 if (interfacePrivate
->entity_device_unique
!= NULL
) {
3193 CFDictionarySetValue(entity
,
3194 CFSTR("DeviceUniqueIdentifier"),
3195 interfacePrivate
->entity_device_unique
);
3197 if (interfacePrivate
->hidden
) {
3198 CFDictionarySetValue(entity
,
3199 kSCNetworkInterfaceHiddenConfigurationKey
,
3202 #if TARGET_OS_IPHONE
3203 if (interfacePrivate
->trustRequired
) {
3204 CFDictionarySetValue(entity
,
3205 kSCNetworkInterfaceTrustRequiredKey
,
3208 #endif // TARGET_OS_IPHONE
3210 // match the "hardware" with the lowest layer
3212 SCNetworkInterfaceRef nextInterface
;
3214 nextInterface
= SCNetworkInterfaceGetInterface(interface
);
3215 if (nextInterface
== NULL
) {
3219 interface
= nextInterface
;
3221 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3223 if (CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
3227 interfaceIndex
= findConfiguration(interfacePrivate
->interface_type
);
3228 if (interfaceIndex
!= kCFNotFound
) {
3229 if (configurations
[interfaceIndex
].entity_hardware
!= NULL
) {
3230 CFDictionarySetValue(entity
,
3231 kSCPropNetInterfaceHardware
,
3232 *configurations
[interfaceIndex
].entity_hardware
);
3235 CFDictionarySetValue(entity
,
3236 kSCPropNetInterfaceHardware
,
3237 interfacePrivate
->interface_type
);
3240 // add the localized display name (which will only be used when/if the
3241 // interface is removed from the system)
3242 CFDictionarySetValue(entity
,
3243 kSCPropUserDefinedName
,
3244 SCNetworkInterfaceGetLocalizedDisplayName(interface
));
3250 static SCNetworkInterfaceRef
3251 findInterface(CFArrayRef interfaces
, CFStringRef match_if
)
3256 n
= CFArrayGetCount(interfaces
);
3257 for (i
= 0; i
< n
; i
++) {
3258 SCNetworkInterfaceRef interface
= CFArrayGetValueAtIndex(interfaces
, i
);
3259 CFStringRef interfaceName
;
3261 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
3262 if ((interfaceName
!= NULL
) && CFEqual(interfaceName
, match_if
)) {
3263 CFRetain(interface
);
3271 #if !TARGET_OS_IPHONE
3272 static SCNetworkInterfaceRef
3273 findBondInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3276 SCNetworkInterfaceRef interface
= NULL
;
3278 if (prefs
== NULL
) {
3282 // check if the interface is an Ethernet Bond
3283 bonds
= SCBondInterfaceCopyAll(prefs
);
3284 if (bonds
!= NULL
) {
3285 interface
= findInterface(bonds
, ifDevice
);
3290 #endif // !TARGET_OS_IPHONE
3292 static SCNetworkInterfaceRef
3293 findBridgeInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3296 SCNetworkInterfaceRef interface
= NULL
;
3298 if (prefs
== NULL
) {
3302 // check if the interface is an bridge
3303 bridges
= SCBridgeInterfaceCopyAll(prefs
);
3304 if (bridges
!= NULL
) {
3305 interface
= findInterface(bridges
, ifDevice
);
3311 static SCNetworkInterfaceRef
3312 findVLANInterface(SCPreferencesRef prefs
, CFStringRef ifDevice
)
3314 SCNetworkInterfaceRef interface
= NULL
;
3317 if (prefs
== NULL
) {
3321 // check if the interface is a VLAN
3322 vlans
= SCVLANInterfaceCopyAll(prefs
);
3323 if (vlans
!= NULL
) {
3324 interface
= findInterface(vlans
, ifDevice
);
3334 static CFMutableDictionaryRef
3335 copy_ppp_entity(CFStringRef bsdName
)
3337 CFMutableDictionaryRef entity
= NULL
;
3338 CFStringRef pattern
;
3339 CFMutableArrayRef patterns
;
3340 CFDictionaryRef dict
;
3342 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
3343 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainState
, kSCCompAnyRegex
, kSCEntNetPPP
);
3344 CFArrayAppendValue(patterns
, pattern
);
3346 pattern
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, kSCCompAnyRegex
, kSCEntNetInterface
);
3347 CFArrayAppendValue(patterns
, pattern
);
3349 dict
= SCDynamicStoreCopyMultiple(NULL
, NULL
, patterns
);
3350 CFRelease(patterns
);
3353 const void * keys_q
[N_QUICK
];
3354 const void ** keys
= keys_q
;
3356 const void * vals_q
[N_QUICK
];
3357 const void ** vals
= vals_q
;
3359 n
= CFDictionaryGetCount(dict
);
3360 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
3361 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3362 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
3364 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
3365 for (i
= 0; i
< n
; i
++) {
3366 CFArrayRef components
;
3367 CFStringRef interfaceKey
;
3368 CFDictionaryRef interfaceVal
;
3370 CFStringRef pppKey
= (CFStringRef
)keys
[i
];
3371 CFDictionaryRef pppVal
= (CFDictionaryRef
)vals
[i
];
3372 CFStringRef serviceID
;
3374 if (!CFStringHasSuffix(pppKey
, kSCEntNetPPP
) ||
3375 !CFDictionaryGetValueIfPresent(pppVal
, kSCPropInterfaceName
, (const void **)&ifName
) ||
3376 !CFEqual(bsdName
, ifName
)) {
3377 // if not matching PPP interface
3381 components
= CFStringCreateArrayBySeparatingStrings(NULL
, pppKey
, CFSTR("/"));
3382 serviceID
= CFArrayGetValueAtIndex(components
, 3);
3383 interfaceKey
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
, kSCDynamicStoreDomainSetup
, serviceID
, kSCEntNetInterface
);
3384 interfaceVal
= CFDictionaryGetValue(dict
, interfaceKey
);
3385 CFRelease(interfaceKey
);
3386 CFRelease(components
);
3387 if (interfaceVal
!= NULL
) {
3388 entity
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceVal
);
3392 if (keys
!= keys_q
) {
3393 CFAllocatorDeallocate(NULL
, keys
);
3394 CFAllocatorDeallocate(NULL
, vals
);
3404 SCNetworkInterfaceRef
3405 _SCNetworkInterfaceCreateWithBSDName(CFAllocatorRef allocator
,
3406 CFStringRef bsdName
,
3409 #pragma unused(allocator)
3410 CFMutableDictionaryRef entity
= NULL
;
3412 SCNetworkInterfaceRef interface
;
3414 memset(&ifr
, 0, sizeof(ifr
));
3415 if (_SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
3418 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
3420 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) == -1) {
3426 if ((ifr
.ifr_flags
& IFF_POINTOPOINT
) != 0) {
3428 entity
= copy_ppp_entity(bsdName
);
3432 if (entity
== NULL
) {
3433 entity
= CFDictionaryCreateMutable(NULL
,
3435 &kCFTypeDictionaryKeyCallBacks
,
3436 &kCFTypeDictionaryValueCallBacks
);
3437 CFDictionarySetValue(entity
, kSCPropNetInterfaceDeviceName
, bsdName
);
3440 #if !TARGET_OS_IPHONE
3441 if ((flags
& kIncludeBondInterfaces
) == 0) {
3442 CFDictionarySetValue(entity
, CFSTR("_NO_BOND_INTERFACES_"), kCFBooleanTrue
);
3444 #endif // !TARGET_OS_IPHONE
3446 if ((flags
& kIncludeBridgeInterfaces
) == 0) {
3447 CFDictionarySetValue(entity
, CFSTR("_NO_BRIDGE_INTERFACES_"), kCFBooleanTrue
);
3450 if ((flags
& kIncludeVLANInterfaces
) == 0) {
3451 CFDictionarySetValue(entity
, CFSTR("_NO_VLAN_INTERFACES_"), kCFBooleanTrue
);
3454 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
3462 _SCNetworkInterfaceCopyPrefixFromBSDName(CFStringRef bsdName
)
3464 CFMutableStringRef interfacePrefix
= NULL
;
3468 if (isA_CFString(bsdName
) == NULL
) {
3469 SC_log(LOG_DEBUG
, "no BSD name");
3473 interfacePrefix
= CFStringCreateMutableCopy(NULL
, 0, bsdName
);
3474 length
= CFStringGetLength(interfacePrefix
);
3476 while (length
> 0) {
3477 lastChar
= CFStringGetCharacterAtIndex(interfacePrefix
, length
- 1);
3478 if (lastChar
>= '0' && lastChar
<= '9') {
3479 CFStringDelete(interfacePrefix
,
3480 CFRangeMake(length
-1, 1));
3485 length
= CFStringGetLength(interfacePrefix
);
3488 return interfacePrefix
;
3493 __SCNetworkInterfaceSetIOInterfacePrefix(SCNetworkInterfaceRef interface
,
3494 CFStringRef prefix
);
3498 __SCNetworkInterfaceUpdateBSDName(SCNetworkInterfaceRef interface
, CFStringRef currentBSDName
, CFStringRef newBSDName
)
3500 Boolean success
= FALSE
;
3501 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3503 if (isA_SCNetworkInterface(interface
) == NULL
) {
3504 SC_log(LOG_INFO
, "No interface");
3508 if (CFEqual(currentBSDName
, newBSDName
)) {
3513 if (interfacePrivate
->entity_device
!= NULL
) {
3514 CFRelease(interfacePrivate
->entity_device
);
3516 interfacePrivate
->entity_device
= CFRetain(newBSDName
);
3524 __SCNetworkInterfaceUpdateIOPath(SCNetworkInterfaceRef interface
)
3526 Boolean success
= FALSE
;
3527 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3528 CFStringRef oldPath
= NULL
;
3529 CFStringRef newPath
= NULL
;
3531 // Using the BSD Name update the path
3532 oldPath
= interfacePrivate
->path
;
3533 if (isA_CFString(oldPath
) == NULL
) {
3536 newPath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("Migrated_From: %@"), oldPath
);
3537 if (interfacePrivate
->path
!= NULL
) {
3538 CFRelease(interfacePrivate
->path
);
3540 interfacePrivate
->path
= CFRetain(newPath
);
3544 if (newPath
!= NULL
) {
3552 __SCNetworkInterfaceSetIOInterfacePrefix (SCNetworkInterfaceRef interface
,
3555 SCNetworkInterfacePrivateRef interfacePrivate
;
3557 if (isA_CFString(prefix
) == NULL
) {
3561 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3565 if (interfacePrivate
->prefix
!= NULL
) {
3566 CFRelease(interfacePrivate
->prefix
);
3569 interfacePrivate
->prefix
= prefix
;
3576 __SCNetworkInterfaceSetIOInterfaceUnit(SCNetworkInterfaceRef interface
,
3579 SCNetworkInterfacePrivateRef interfacePrivate
;
3580 CFStringRef newBSDName
= NULL
;
3581 CFStringRef oldBSDName
= NULL
;
3583 if (isA_CFNumber(unit
) == NULL
) {
3586 interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
3588 oldBSDName
= SCNetworkInterfaceGetBSDName(interface
);
3590 if (interfacePrivate
->prefix
== NULL
) {
3591 if (isA_CFString(interfacePrivate
->entity_device
) != NULL
) {
3592 CFStringRef interfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(interfacePrivate
->entity_device
);
3593 if (interfaceNamePrefix
== NULL
) {
3594 SC_log(LOG_INFO
, "interfaceNamePrefix is NULL");
3597 __SCNetworkInterfaceSetIOInterfacePrefix(interface
, interfaceNamePrefix
);
3598 CFRelease(interfaceNamePrefix
);
3603 if (interfacePrivate
->prefix
!= NULL
) {
3604 newBSDName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), interfacePrivate
->prefix
, unit
);
3607 // Update the BSD Name
3608 if ((newBSDName
== NULL
) ||
3609 (!__SCNetworkInterfaceUpdateBSDName(interface
, oldBSDName
, newBSDName
))) {
3610 SC_log(LOG_INFO
, "BSD name update failed");
3614 if (!__SCNetworkInterfaceUpdateIOPath(interface
)) {
3615 SC_log(LOG_INFO
, "IOPath update failed");
3619 if (interfacePrivate
->unit
!= NULL
) {
3620 CFRelease(interfacePrivate
->unit
);
3622 interfacePrivate
->unit
= unit
;
3625 if (newBSDName
!= NULL
) {
3626 CFRelease(newBSDName
);
3634 __SCNetworkInterfaceCopyStorageEntity(SCNetworkInterfaceRef interface
)
3636 CFMutableDictionaryRef interface_entity
= NULL
;
3637 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3638 CFBooleanRef active
= NULL
;
3639 CFStringRef bsdName
= NULL
;
3640 CFBooleanRef builtin
= NULL
;
3641 CFStringRef interfaceNamePrefix
= NULL
;
3642 CFNumberRef interfaceType
= NULL
;
3643 CFNumberRef interfaceUnit
= NULL
;
3644 CFDataRef macAddress
= NULL
;
3645 CFStringRef pathMatch
= NULL
;
3646 CFDictionaryRef info
= NULL
;
3647 CFStringRef type
= NULL
;
3649 if (interfacePrivate
->active
) {
3650 active
= kCFBooleanTrue
;
3653 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
3654 if (!isA_CFString(bsdName
)) {
3658 builtin
= interfacePrivate
->builtin
? kCFBooleanTrue
: kCFBooleanFalse
;
3659 interfaceNamePrefix
= _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface
);
3660 if (!isA_CFString(interfaceNamePrefix
)) {
3664 interfaceType
= _SCNetworkInterfaceGetIOInterfaceType(interface
);
3665 if (!isA_CFNumber(interfaceType
)) {
3669 interfaceUnit
= _SCNetworkInterfaceGetIOInterfaceUnit(interface
);
3670 if (!isA_CFNumber(interfaceUnit
)) {
3674 macAddress
= _SCNetworkInterfaceGetHardwareAddress(interface
);
3675 if (!isA_CFData(macAddress
)) {
3679 pathMatch
= _SCNetworkInterfaceGetIOPath(interface
);
3680 if (!isA_CFString(pathMatch
)) {
3684 info
= _SCNetworkInterfaceCopyInterfaceInfo(interface
);
3685 if (!isA_CFDictionary(info
)) {
3689 type
= SCNetworkInterfaceGetInterfaceType(interface
);
3690 if (!isA_CFString(type
)) {
3694 interface_entity
= CFDictionaryCreateMutable(NULL
, 0,
3695 &kCFTypeDictionaryKeyCallBacks
,
3696 &kCFTypeDictionaryValueCallBacks
);
3698 if (isA_CFBoolean(active
) != NULL
) {
3699 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
), active
);
3702 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
), bsdName
);
3703 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
), builtin
);
3704 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
), interfaceNamePrefix
);
3705 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
), interfaceType
);
3706 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
), interfaceUnit
);
3707 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
), macAddress
);
3708 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
), pathMatch
);
3709 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
), info
);
3710 CFDictionaryAddValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
), type
);
3715 return interface_entity
;
3720 __SCNetworkInterfaceSetService(SCNetworkInterfaceRef interface
,
3721 SCNetworkServiceRef service
)
3723 SCNetworkInterfacePrivateRef interfacePrivate
;
3724 SCNetworkServicePrivateRef servicePrivate
;
3726 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
3727 if (interfacePrivate
->prefs
!= NULL
) {
3728 CFRelease(interfacePrivate
->prefs
);
3729 interfacePrivate
->prefs
= NULL
;
3731 if (interfacePrivate
->serviceID
!= NULL
) {
3732 CFRelease(interfacePrivate
->serviceID
);
3733 interfacePrivate
->serviceID
= NULL
;
3736 servicePrivate
= (SCNetworkServicePrivateRef
)service
;
3737 if (servicePrivate
->prefs
!= NULL
) {
3738 interfacePrivate
->prefs
= CFRetain(servicePrivate
->prefs
);
3740 if (servicePrivate
->serviceID
!= NULL
) {
3741 interfacePrivate
->serviceID
= CFRetain(servicePrivate
->serviceID
);
3750 __SCNetworkInterfaceMatchesName(CFStringRef name
, CFStringRef key
)
3755 if (bundle
== NULL
) {
3756 SC_log(LOG_NOTICE
, "no bundle information to compare interface names");
3760 if (!isA_CFString(name
)) {
3761 // if no interface "name"
3765 // check non-localized name for a match
3766 str
= copy_interface_string(bundle
, key
, FALSE
);
3768 match
= CFEqual(name
, str
);
3775 // check localized name for a match
3776 str
= copy_interface_string(bundle
, key
, TRUE
);
3778 match
= CFEqual(name
, str
);
3789 #define kInterfaceTypeEthernetValue 6
3790 #define kInterfaceTypeFirewireValue 144
3793 static SCNetworkInterfaceRef
3794 __SCNetworkInterfaceCreateWithStorageEntity(CFAllocatorRef allocator
,
3795 CFDictionaryRef interface_entity
)
3797 #pragma unused(allocator)
3798 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
3799 CFBooleanRef active
= NULL
;
3800 CFStringRef bsdName
= NULL
;
3801 CFBooleanRef ioBuiltin
= NULL
;
3802 CFStringRef ioInterfaceNamePrefix
= NULL
;
3803 CFNumberRef ioInterfaceType
= NULL
;
3804 int ioInterfaceTypeNum
;
3805 CFNumberRef ioInterfaceUnit
= NULL
;
3806 CFDataRef ioMACAddress
= NULL
;
3807 CFStringRef ioPathMatch
= NULL
;
3808 CFDictionaryRef SCNetworkInterfaceInfo
= NULL
;
3809 CFStringRef userDefinedName
= NULL
;
3810 CFStringRef usbProductName
= NULL
;
3811 CFNumberRef idProduct
= NULL
;
3812 CFNumberRef idVendor
= NULL
;
3813 CFStringRef type
= NULL
;
3815 /* initialize runtime */
3816 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
3818 if (isA_CFDictionary(interface_entity
) == NULL
) {
3819 SC_log(LOG_INFO
, "No interface entity");
3822 active
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceActive
));
3823 if (isA_CFBoolean(active
) == NULL
) {
3824 active
= kCFBooleanFalse
;
3826 bsdName
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceBSDName
));
3827 if (isA_CFString(bsdName
) == NULL
) {
3828 SC_log(LOG_INFO
, "No BSD name");
3831 ioBuiltin
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOBuiltin
));
3832 if (isA_CFBoolean(ioBuiltin
) == NULL
) {
3833 SC_log(LOG_INFO
, "No IOBuiltin property");
3836 ioInterfaceNamePrefix
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceNamePrefix
));
3837 if (isA_CFString(ioInterfaceNamePrefix
) == NULL
) {
3838 ioInterfaceNamePrefix
= _SCNetworkInterfaceCopyPrefixFromBSDName(bsdName
);
3839 if (ioInterfaceNamePrefix
== NULL
) {
3840 SC_log(LOG_INFO
, "No BSD interface name prefix");
3844 CFRetain(ioInterfaceNamePrefix
);
3846 ioInterfaceType
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceType
));
3847 if (isA_CFNumber(ioInterfaceType
) == NULL
) {
3848 SC_log(LOG_INFO
, "No IOInterfaceType");
3851 if (!CFNumberGetValue(ioInterfaceType
, kCFNumberIntType
, &ioInterfaceTypeNum
)) {
3852 SC_log(LOG_NOTICE
, "Count not extract value from ioInterfaceType");
3854 ioInterfaceUnit
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOInterfaceUnit
));
3855 if (isA_CFNumber(ioInterfaceUnit
) == NULL
) {
3856 SC_log(LOG_INFO
, "No IOInterfaceUnit");
3860 ioMACAddress
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOMACAddress
));
3861 if (isA_CFData(ioMACAddress
) == NULL
) {
3862 SC_log(LOG_INFO
, "No IOMACAddress");
3865 ioPathMatch
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceIOPathMatch
));
3866 if (isA_CFString(ioPathMatch
) == NULL
) {
3867 SC_log(LOG_INFO
, "No IOPathMatch");
3870 // Check if Path contains the BSD Name in the end
3872 SCNetworkInterfaceInfo
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceInfo
));
3873 if (isA_CFDictionary(SCNetworkInterfaceInfo
) == NULL
) {
3874 SC_log(LOG_INFO
, "No SCNetworkInterfaceInfo");
3877 userDefinedName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, kSCPropUserDefinedName
);
3878 #if !TARGET_OS_SIMULATOR
3879 usbProductName
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductString
));
3880 idProduct
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBProductID
));
3881 idVendor
= CFDictionaryGetValue(SCNetworkInterfaceInfo
, CFSTR(kUSBVendorID
));
3882 #endif // !TARGET_OS_SIMULATOR
3884 type
= CFDictionaryGetValue(interface_entity
, CFSTR(kSCNetworkInterfaceType
));
3885 if (isA_CFString(type
) == NULL
) {
3886 SC_log(LOG_INFO
, "No SCNetworkInterfaceType");
3890 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
3891 interfacePrivate
->active
= CFBooleanGetValue(active
);
3892 interfacePrivate
->entity_device
= CFRetain(bsdName
);
3893 interfacePrivate
->builtin
= CFBooleanGetValue(ioBuiltin
);
3894 interfacePrivate
->prefix
= CFRetain(ioInterfaceNamePrefix
);
3895 interfacePrivate
->type
= CFRetain(ioInterfaceType
);
3896 interfacePrivate
->unit
= CFRetain(ioInterfaceUnit
);
3897 interfacePrivate
->address
= CFRetain(ioMACAddress
);
3898 interfacePrivate
->path
= CFRetain(ioPathMatch
);
3899 interfacePrivate
->name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3900 interfacePrivate
->localized_name
= ((userDefinedName
!= NULL
) ? CFRetain(userDefinedName
) : NULL
);
3901 interfacePrivate
->usb
.name
= ((usbProductName
!= NULL
) ? CFRetain(usbProductName
) : NULL
);
3902 interfacePrivate
->usb
.pid
= ((idProduct
!= NULL
) ? CFRetain(idProduct
) : NULL
);
3903 interfacePrivate
->usb
.vid
= ((idVendor
!= NULL
) ? CFRetain(idVendor
) : NULL
);
3905 // Handling interface types to be seen in NetworkInterfaces.plist
3906 CFIndex interfaceIndex
;
3908 interfaceIndex
= findConfiguration(type
);
3909 if (interfaceIndex
!= kCFNotFound
) {
3910 interfacePrivate
->interface_type
= *configurations
[interfaceIndex
].interface_type
;
3912 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
3915 // Extracting entity type from value of interface type
3916 if (ioInterfaceTypeNum
== kInterfaceTypeEthernetValue
) {
3917 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeEthernet
; // kSCNetworkInterfaceTypeEthernet;
3918 } else if (ioInterfaceTypeNum
== kInterfaceTypeFirewireValue
) {
3919 interfacePrivate
->entity_type
= kSCValNetInterfaceTypeFireWire
;
3922 if (ioInterfaceNamePrefix
!= NULL
) {
3923 CFRelease(ioInterfaceNamePrefix
);
3926 return (SCNetworkInterfaceRef
)interfacePrivate
;
3932 _SCNetworkInterfaceCacheOpen(void)
3934 if (!__SCNetworkInterfaceCacheIsOpen()) {
3935 S_interface_cache
= CFDictionaryCreateMutable(NULL
,
3937 &kCFTypeDictionaryKeyCallBacks
,
3938 &kCFTypeDictionaryValueCallBacks
);
3939 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): open", S_interface_cache
);
3946 _SCNetworkInterfaceCacheClose(void)
3948 if (__SCNetworkInterfaceCacheIsOpen()) {
3949 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): close", S_interface_cache
);
3950 CFRelease(S_interface_cache
);
3951 S_interface_cache
= NULL
;
3957 __SCNetworkInterfaceCacheAdd(CFStringRef bsdName
, CFArrayRef matchingInterfaces
)
3959 if (__SCNetworkInterfaceCacheIsOpen() &&
3961 matchingInterfaces
!= NULL
) {
3962 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): add %@", S_interface_cache
, bsdName
);
3963 CFDictionaryAddValue(S_interface_cache
, bsdName
, matchingInterfaces
);
3968 static inline Boolean
3969 __SCNetworkInterfaceCacheIsOpen(void)
3971 return (S_interface_cache
!= NULL
);
3976 __SCNetworkInterfaceCacheCopy(CFStringRef bsdName
)
3978 if (__SCNetworkInterfaceCacheIsOpen() &&
3980 CFArrayRef matchingInterfaces
= CFDictionaryGetValue(S_interface_cache
, bsdName
);
3981 if (matchingInterfaces
) {
3982 CFRetain(matchingInterfaces
);
3983 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ match for %@", S_interface_cache
, bsdName
);
3985 SC_log(LOG_DEBUG
, "SCNetworkInterface cache (%p): copy w/ no match for %@", S_interface_cache
, bsdName
);
3988 return matchingInterfaces
;
3995 SCNetworkInterfaceRef
3996 _SCNetworkInterfaceCreateWithEntity(CFAllocatorRef allocator
,
3997 CFDictionaryRef interface_entity
,
3998 SCNetworkServiceRef service
)
4000 #pragma unused(allocator)
4001 SCNetworkInterfacePrivateRef interfacePrivate
= NULL
;
4002 CFStringRef ifDevice
;
4003 CFStringRef ifName
= NULL
;
4004 CFStringRef ifSubType
;
4006 CFStringRef ifUnique
;
4007 CFArrayRef matching_interfaces
= NULL
;
4008 SCPreferencesRef servicePref
= NULL
;
4009 Boolean useSystemInterfaces
= TRUE
;
4011 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
4012 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4014 if (service
!= NULL
) {
4015 servicePref
= ((SCNetworkServicePrivateRef
)service
)->prefs
;
4016 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePref
)) &&
4017 (!__SCPreferencesGetLimitSCNetworkConfiguration(servicePref
)));
4020 ifType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceType
);
4021 if (ifType
== NULL
) {
4023 * The interface "Type" was not specified. We'll make an
4024 * assumption that this is an "Ethernet" interface. If a
4025 * real interface exists with the provided interface name
4026 * then the actual type will be set accordingly. If not, we'll
4027 * end up crafting an "Ethernet" SCNetworkInterface that
4028 * will keep the rest of the configuration APIs happy.
4030 ifType
= kSCValNetInterfaceTypeEthernet
;
4033 if (!isA_CFString(ifType
)) {
4037 ifSubType
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceSubType
);
4038 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) ||
4039 CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4040 if (!isA_CFString(ifSubType
)) {
4045 ifDevice
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceDeviceName
);
4046 ifUnique
= CFDictionaryGetValue(interface_entity
, CFSTR("DeviceUniqueIdentifier"));
4048 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
) ||
4049 CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
) ||
4050 (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
))) {
4051 char bsdName
[IFNAMSIZ
];
4052 CFMutableDictionaryRef matching
;
4054 if (!isA_CFString(ifDevice
)) {
4058 if (CFEqual(ifDevice
, CFSTR("lo0"))) { // for _SCNetworkInterfaceCreateWithBSDName
4059 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4062 if (useSystemInterfaces
) {
4063 // Check to see if we already have the info in the cache
4064 matching_interfaces
= __SCNetworkInterfaceCacheCopy(ifDevice
);
4065 if (matching_interfaces
== NULL
) {
4066 if (_SC_cfstring_to_cstring(ifDevice
, bsdName
, sizeof(bsdName
), kCFStringEncodingASCII
) == NULL
) {
4070 matching
= IOBSDNameMatching(masterPort
, 0, bsdName
);
4071 if (matching
== NULL
) {
4074 matching_interfaces
= findMatchingInterfaces(matching
,
4075 processNetworkInterface
,
4076 kSCNetworkInterfaceHiddenInterfaceKey
,
4079 __SCNetworkInterfaceCacheAdd(ifDevice
, matching_interfaces
);
4080 CFRelease(matching
);
4083 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4084 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4085 CFDictionaryRef matching
;
4086 CFStringRef match_keys
[2];
4087 CFStringRef match_vals
[2];
4089 if (!isA_CFString(ifDevice
)) {
4093 if (useSystemInterfaces
) {
4094 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4095 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4097 match_keys
[1] = CFSTR(kIOTTYBaseNameKey
);
4098 match_vals
[1] = ifDevice
;
4100 matching
= CFDictionaryCreate(NULL
,
4101 (const void **)match_keys
,
4102 (const void **)match_vals
,
4103 sizeof(match_keys
)/sizeof(match_keys
[0]),
4104 &kCFTypeDictionaryKeyCallBacks
,
4105 &kCFTypeDictionaryValueCallBacks
);
4106 matching_interfaces
= findMatchingInterfaces(matching
,
4107 processSerialInterface
,
4108 kSCNetworkInterfaceHiddenPortKey
,
4110 CFRelease(matching
);
4112 if (ifUnique
== NULL
) {
4114 Boolean useDeviceName
= TRUE
;
4116 n
= (matching_interfaces
!= NULL
) ? CFArrayGetCount(matching_interfaces
) : 0;
4120 for (i
= 0; i
< n
; i
++) {
4121 SCNetworkInterfacePrivateRef scanPrivate
;
4123 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4124 if (scanPrivate
->entity_device_unique
!= NULL
) {
4125 useDeviceName
= FALSE
;
4131 if (useDeviceName
&& useSystemInterfaces
) {
4132 if (matching_interfaces
!= NULL
) {
4133 CFRelease(matching_interfaces
);
4136 match_keys
[1] = CFSTR(kIOTTYDeviceKey
);
4137 matching
= CFDictionaryCreate(NULL
,
4138 (const void **)match_keys
,
4139 (const void **)match_vals
,
4140 sizeof(match_keys
)/sizeof(match_keys
[0]),
4141 &kCFTypeDictionaryKeyCallBacks
,
4142 &kCFTypeDictionaryValueCallBacks
);
4143 matching_interfaces
= findMatchingInterfaces(matching
,
4144 processSerialInterface
,
4145 kSCNetworkInterfaceHiddenPortKey
,
4147 CFRelease(matching
);
4150 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypeL2TP
)) {
4151 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4152 kSCNetworkInterfaceTypeL2TP
);
4153 #pragma GCC diagnostic push
4154 #pragma GCC diagnostic ignored "-Wdeprecated"
4155 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPTP
)) {
4156 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4157 kSCNetworkInterfaceTypePPTP
);
4158 #pragma GCC diagnostic pop
4160 // XXX do we allow non-Apple variants of PPP??? XXX
4161 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4164 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4165 if (!isA_CFString(ifDevice
)) {
4169 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4170 kSCNetworkInterfaceType6to4
);
4171 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4172 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4173 kSCNetworkInterfaceTypeIPSec
);
4174 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4175 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4176 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4177 if (CFStringFind(ifSubType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4178 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4181 } else if ((CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) && (ifDevice
== NULL
)) {
4182 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4186 if (matching_interfaces
!= NULL
) {
4188 SCPreferencesRef prefs
;
4189 Boolean temp_preferences
= FALSE
;
4191 n
= CFArrayGetCount(matching_interfaces
);
4194 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4195 if (_SC_CFEqual(ifUnique
, interfacePrivate
->entity_device_unique
)) {
4196 // if the unique ID's match
4197 CFRetain(interfacePrivate
);
4201 interfacePrivate
= NULL
;
4204 if (!CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4208 if (CFDictionaryGetValueIfPresent(interface_entity
,
4209 kSCPropUserDefinedName
,
4210 (const void **)&ifName
) &&
4211 CFEqual(ifName
, CFSTR(BT_PAN_NAME
))) {
4215 prefs
= (service
!= NULL
) ? ((SCNetworkServicePrivateRef
)service
)->prefs
: NULL
;
4216 if (prefs
== NULL
) {
4217 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), NULL
);
4218 if (prefs
!= NULL
) {
4219 temp_preferences
= TRUE
;
4222 if (prefs
== NULL
) {
4225 #if !TARGET_OS_IPHONE
4226 if (!CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BOND_INTERFACES_"))) {
4227 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBondInterface(prefs
, ifDevice
);
4229 #endif // !TARGET_OS_IPHONE
4230 if ((interfacePrivate
== NULL
)
4231 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_BRIDGE_INTERFACES_"))) {
4232 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findBridgeInterface(prefs
, ifDevice
);
4235 if ((interfacePrivate
== NULL
)
4236 && !CFDictionaryContainsKey(interface_entity
, CFSTR("_NO_VLAN_INTERFACES_"))) {
4237 interfacePrivate
= (SCNetworkInterfacePrivateRef
)findVLANInterface(prefs
, ifDevice
);
4239 if (temp_preferences
) CFRelease(prefs
);
4242 if (ifUnique
!= NULL
) {
4245 // we are looking for an interface with a unique ID
4246 // so let's try to focus our choices
4247 for (i
= 0; i
< n
; i
++) {
4248 SCNetworkInterfacePrivateRef scanPrivate
;
4250 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4251 if (_SC_CFEqual(ifUnique
, scanPrivate
->entity_device_unique
)) {
4252 if (interfacePrivate
!= NULL
) {
4253 // if we've matched more than one interface
4254 interfacePrivate
= NULL
;
4257 interfacePrivate
= scanPrivate
;
4260 } else if (CFDictionaryGetValueIfPresent(interface_entity
,
4261 kSCPropUserDefinedName
,
4262 (const void **)&ifName
)) {
4265 // we don't have a unique ID but do have an interface
4266 // name. If the matching interfaces do have IDs than
4267 // we can try to focus our choices using the name
4268 for (i
= 0; i
< n
; i
++) {
4269 SCNetworkInterfacePrivateRef scanPrivate
;
4271 scanPrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, i
);
4272 if (scanPrivate
->entity_device_unique
!= NULL
) {
4273 SCNetworkInterfaceRef scan
= (SCNetworkInterfaceRef
)scanPrivate
;
4274 CFStringRef scanName
;
4276 scanName
= __SCNetworkInterfaceGetNonLocalizedDisplayName(scan
);
4277 if ((scanName
!= NULL
) && !_SC_CFEqual(ifName
, scanName
)) {
4278 continue; // if not the same display name
4282 if (interfacePrivate
!= NULL
) {
4283 // if we've matched more than one interface
4284 interfacePrivate
= NULL
;
4287 interfacePrivate
= scanPrivate
;
4290 if (interfacePrivate
== NULL
) {
4291 SC_log(LOG_NOTICE
, "more than one interface matches %@", ifDevice
);
4292 interfacePrivate
= (SCNetworkInterfacePrivateRef
)CFArrayGetValueAtIndex(matching_interfaces
, 0);
4294 CFRetain(interfacePrivate
);
4297 CFRelease(matching_interfaces
);
4302 if ((interfacePrivate
== NULL
) || !useSystemInterfaces
) {
4304 * if device not present on this system
4306 if (!useSystemInterfaces
) {
4307 if (interfacePrivate
!= NULL
) {
4308 CFRelease(interfacePrivate
);
4312 interfacePrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, NULL
, NULL
);
4313 interfacePrivate
->entity_type
= (ifType
!= NULL
) ? ifType
: NULL
;
4314 interfacePrivate
->entity_subtype
= (ifSubType
!= NULL
) ? ifSubType
: NULL
;
4315 interfacePrivate
->entity_device
= (ifDevice
!= NULL
) ? CFStringCreateCopy(NULL
, ifDevice
) : NULL
;
4316 interfacePrivate
->entity_device_unique
= (ifUnique
!= NULL
) ? CFStringCreateCopy(NULL
, ifUnique
) : NULL
;
4318 // Using UserDefinedName to check the validity of preferences file
4319 // when useSystemInterfaces is FALSE
4320 if (!useSystemInterfaces
) {
4321 CFStringRef userDefinedName
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4322 if (isA_CFString(userDefinedName
) != NULL
) {
4323 CFRetain(userDefinedName
);
4324 if (interfacePrivate
->name
!= NULL
) {
4325 CFRelease(interfacePrivate
->name
);
4327 interfacePrivate
->name
= userDefinedName
;
4329 CFRetain(userDefinedName
);
4330 if (interfacePrivate
->localized_name
!= NULL
) {
4331 CFRelease(interfacePrivate
->localized_name
);
4333 interfacePrivate
->localized_name
= userDefinedName
;
4337 if (CFEqual(ifType
, kSCValNetInterfaceTypeEthernet
)) {
4338 CFStringRef entity_hardware
;
4339 SCNetworkInterfaceRef virtualInterface
;
4341 if (!useSystemInterfaces
&&
4342 (((virtualInterface
= findBridgeInterface(servicePref
, ifDevice
)) != NULL
) ||
4343 #if !TARGET_OS_IPHONE
4344 ((virtualInterface
= findBondInterface(servicePref
, ifDevice
)) != NULL
) ||
4345 #endif // !TARGET_OS_IPHONE
4346 ((virtualInterface
= findVLANInterface(servicePref
, ifDevice
)) != NULL
))) {
4347 CFRelease(interfacePrivate
);
4348 interfacePrivate
= (SCNetworkInterfacePrivateRef
)virtualInterface
;
4350 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4351 if (isA_CFString((entity_hardware
)) &&
4352 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4353 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4354 interfacePrivate
->localized_key
= CFSTR("airport");
4355 interfacePrivate
->sort_order
= kSortAirPort
;
4359 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4361 name
= CFDictionaryGetValue(interface_entity
, kSCPropUserDefinedName
);
4362 if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPhone"))) {
4363 interfacePrivate
->localized_key
= CFSTR("iPhone");
4364 interfacePrivate
->sort_order
= kSortTethered
;
4365 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("iPad"))) {
4366 interfacePrivate
->localized_key
= CFSTR("iPad");
4367 interfacePrivate
->sort_order
= kSortTethered
;
4368 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("thunderbolt"))) {
4369 interfacePrivate
->localized_key
= CFSTR("thunderbolt");
4370 interfacePrivate
->sort_order
= kSortThunderbolt
;
4371 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-gn"))) {
4372 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-gn");
4373 interfacePrivate
->sort_order
= kSortBluetoothPAN_GN
;
4374 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-nap"))) {
4375 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-nap");
4376 interfacePrivate
->sort_order
= kSortBluetoothPAN_NAP
;
4377 } else if (__SCNetworkInterfaceMatchesName(name
, CFSTR("bluetooth-pan-u"))) {
4378 interfacePrivate
->localized_key
= CFSTR("bluetooth-pan-u");
4379 interfacePrivate
->sort_order
= kSortBluetoothPAN_U
;
4381 interfacePrivate
->sort_order
= kSortEthernet
;
4385 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeFireWire
)) {
4386 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeFireWire
;
4387 interfacePrivate
->sort_order
= kSortFireWire
;
4388 } else if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
) && (ifSubType
!= NULL
)) {
4389 if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPoE
)) {
4390 CFStringRef entity_hardware
;
4392 entity_hardware
= CFDictionaryGetValue(interface_entity
, kSCPropNetInterfaceHardware
);
4393 if (isA_CFString((entity_hardware
)) &&
4394 CFEqual(entity_hardware
, kSCEntNetAirPort
)) {
4395 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIEEE80211
;
4396 interfacePrivate
->sort_order
= kSortAirPort
;
4398 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeEthernet
;
4399 interfacePrivate
->sort_order
= kSortEthernet
;
4401 } else if (CFEqual(ifSubType
, kSCValNetInterfaceSubTypePPPSerial
)) {
4402 if (CFStringHasPrefix(ifDevice
, CFSTR("Bluetooth"))) {
4403 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeBluetooth
;
4404 interfacePrivate
->sort_order
= kSortBluetooth
;
4405 } else if (CFStringHasPrefix(ifDevice
, CFSTR("irda"))) {
4406 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeIrDA
;
4407 interfacePrivate
->sort_order
= kSortIrDA
;
4408 } else if (CFStringHasPrefix(ifDevice
, CFSTR("wwan"))) {
4409 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeWWAN
;
4410 interfacePrivate
->sort_order
= kSortWWAN
;
4412 interfacePrivate
->interface_type
= kSCNetworkInterfaceTypeModem
;
4413 interfacePrivate
->sort_order
= kSortModem
;
4416 SCNetworkInterfaceRef child
;
4418 CFRelease(interfacePrivate
);
4419 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4420 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4421 if (interfacePrivate
== NULL
) {
4425 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
) && (ifSubType
!= NULL
)) {
4426 SCNetworkInterfaceRef child
;
4427 CFRelease(interfacePrivate
);
4428 child
= SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
, ifSubType
);
4429 interfacePrivate
= (SCNetworkInterfacePrivateRef
)child
;
4430 if (interfacePrivate
== NULL
) {
4433 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeIPSec
)) {
4434 CFRelease(interfacePrivate
);
4435 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4436 kSCNetworkInterfaceTypeIPSec
);
4437 } else if (CFEqual(ifType
, kSCValNetInterfaceType6to4
)) {
4438 CFRelease(interfacePrivate
);
4439 if (!isA_CFString(ifDevice
)) {
4442 interfacePrivate
= (SCNetworkInterfacePrivateRef
)SCNetworkInterfaceCreateWithInterface(kSCNetworkInterfaceIPv4
,
4443 kSCNetworkInterfaceType6to4
);
4444 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeLoopback
)) {
4445 CFRelease(interfacePrivate
);
4446 interfacePrivate
= __SCNetworkInterfaceCreateCopy(NULL
, kSCNetworkInterfaceLoopback
, NULL
, NULL
);
4447 } else if (CFStringFind(ifType
, CFSTR("."), 0).location
!= kCFNotFound
) {
4448 // if vendor interface
4449 pthread_mutex_lock(&lock
);
4450 if (vendor_interface_types
== NULL
) {
4451 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
4453 CFSetAddValue(vendor_interface_types
, ifType
);
4454 interfacePrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, ifType
);
4455 pthread_mutex_unlock(&lock
);
4457 // if unknown interface
4458 CFRelease(interfacePrivate
);
4459 interfacePrivate
= NULL
;
4463 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceHiddenConfigurationKey
)) {
4464 interfacePrivate
->hidden
= TRUE
;
4466 #if TARGET_OS_IPHONE
4467 if (CFDictionaryContainsKey(interface_entity
, kSCNetworkInterfaceTrustRequiredKey
)) {
4468 interfacePrivate
->trustRequired
= TRUE
;
4470 #endif // TARGET_OS_IPHONE
4473 if (service
!= NULL
) {
4474 __SCNetworkInterfaceSetService((SCNetworkInterfaceRef
)interfacePrivate
,
4477 #if !TARGET_OS_IPHONE
4478 // set prefs & serviceID to Bond member interfaces
4479 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBond
)) {
4484 members
= SCBondInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4485 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4486 for (i
= 0; i
< n
; i
++) {
4487 SCNetworkInterfaceRef member
;
4489 member
= CFArrayGetValueAtIndex(members
, i
);
4490 __SCNetworkInterfaceSetService(member
, service
);
4493 #endif // !TARGET_OS_IPHONE
4495 // set prefs & serviceID to Bridge member interfaces
4496 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeBridge
)) {
4501 members
= SCBridgeInterfaceGetMemberInterfaces((SCNetworkInterfaceRef
)interfacePrivate
);
4502 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
4503 for (i
= 0; i
< n
; i
++) {
4504 SCNetworkInterfaceRef member
;
4506 member
= CFArrayGetValueAtIndex(members
, i
);
4507 __SCNetworkInterfaceSetService(member
, service
);
4510 // set prefs & serviceID to VLAN pyhsical interface
4511 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVLAN
)) {
4512 SCNetworkInterfaceRef vlan_physical
;
4514 vlan_physical
= SCVLANInterfaceGetPhysicalInterface((SCNetworkInterfaceRef
)interfacePrivate
);
4515 if (vlan_physical
!= NULL
) {
4516 __SCNetworkInterfaceSetService(vlan_physical
, service
);
4521 if (CFEqual(ifType
, kSCValNetInterfaceTypePPP
)) {
4522 SCNetworkInterfaceRef parent
;
4525 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4526 kSCNetworkInterfaceTypePPP
);
4527 CFRelease(interfacePrivate
);
4528 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4529 } else if (CFEqual(ifType
, kSCValNetInterfaceTypeVPN
)) {
4530 SCNetworkInterfaceRef parent
;
4533 parent
= SCNetworkInterfaceCreateWithInterface((SCNetworkInterfaceRef
)interfacePrivate
,
4534 kSCNetworkInterfaceTypeVPN
);
4535 CFRelease(interfacePrivate
);
4536 interfacePrivate
= (SCNetworkInterfacePrivateRef
)parent
;
4539 return (SCNetworkInterfaceRef
)interfacePrivate
;
4544 #pragma mark SCNetworkInterface APIs
4549 __SCNetworkInterfaceCopyAll_IONetworkInterface(Boolean keep_pre_configured
)
4551 CFDictionaryRef matching
;
4552 CFArrayRef new_interfaces
;
4554 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4556 matching
= IOServiceMatching(kIONetworkInterfaceClass
);
4557 new_interfaces
= findMatchingInterfaces(matching
,
4558 processNetworkInterface
,
4559 kSCNetworkInterfaceHiddenInterfaceKey
,
4560 keep_pre_configured
);
4561 CFRelease(matching
);
4563 return new_interfaces
;
4569 __SCNetworkInterfaceCopyAll_Modem()
4571 CFDictionaryRef matching
;
4572 CFStringRef match_keys
[2];
4573 CFStringRef match_vals
[2];
4574 CFArrayRef new_interfaces
;
4576 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4577 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4579 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4580 match_vals
[1] = CFSTR(kIOSerialBSDModemType
);
4582 matching
= CFDictionaryCreate(NULL
,
4583 (const void **)match_keys
,
4584 (const void **)match_vals
,
4585 sizeof(match_keys
)/sizeof(match_keys
[0]),
4586 &kCFTypeDictionaryKeyCallBacks
,
4587 &kCFTypeDictionaryValueCallBacks
);
4588 new_interfaces
= findMatchingInterfaces(matching
,
4589 processSerialInterface
,
4590 kSCNetworkInterfaceHiddenPortKey
,
4592 CFRelease(matching
);
4594 return new_interfaces
;
4600 __SCNetworkInterfaceCopyAll_RS232()
4602 CFDictionaryRef matching
;
4603 CFStringRef match_keys
[2];
4604 CFStringRef match_vals
[2];
4605 CFArrayRef new_interfaces
;
4607 match_keys
[0] = CFSTR(kIOProviderClassKey
);
4608 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
4610 match_keys
[1] = CFSTR(kIOSerialBSDTypeKey
);
4611 match_vals
[1] = CFSTR(kIOSerialBSDRS232Type
);
4613 matching
= CFDictionaryCreate(NULL
,
4614 (const void **)match_keys
,
4615 (const void **)match_vals
,
4616 sizeof(match_keys
)/sizeof(match_keys
[0]),
4617 &kCFTypeDictionaryKeyCallBacks
,
4618 &kCFTypeDictionaryValueCallBacks
);
4619 new_interfaces
= findMatchingInterfaces(matching
,
4620 processSerialInterface
,
4621 kSCNetworkInterfaceHiddenPortKey
,
4623 CFRelease(matching
);
4625 return new_interfaces
;
4629 #if !TARGET_OS_IPHONE
4631 addBTPANInterface(CFMutableArrayRef all_interfaces
)
4634 SCNetworkInterfaceRef interface
;
4637 n
= CFArrayGetCount(all_interfaces
);
4638 for (i
= 0; i
< n
; i
++) {
4639 SCNetworkInterfaceRef interface
;
4641 interface
= CFArrayGetValueAtIndex(all_interfaces
, i
);
4642 if (_SCNetworkInterfaceIsBluetoothPAN(interface
)) {
4643 // if we already have a BT-PAN interface
4648 interface
= _SCNetworkInterfaceCopyBTPANInterface();
4649 if (interface
!= NULL
) {
4650 // include BT-PAN interface
4651 CFArrayAppendValue(all_interfaces
, interface
);
4652 CFRelease(interface
);
4657 #endif // !TARGET_OS_IPHONE
4661 add_interfaces(CFMutableArrayRef all_interfaces
, CFArrayRef new_interfaces
)
4666 n
= CFArrayGetCount(new_interfaces
);
4667 for (i
= 0; i
< n
; i
++) {
4668 CFStringRef bsdName
;
4669 SCNetworkInterfaceRef interface
;
4671 interface
= CFArrayGetValueAtIndex(new_interfaces
, i
);
4672 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
4673 if (bsdName
!= NULL
) {
4674 CFArrayAppendValue(all_interfaces
, interface
);
4683 __waitForInterfaces()
4685 CFStringRef key
= NULL
;
4688 SCDynamicStoreRef store
= NULL
;
4690 CRSetCrashLogMessage("Waiting for IOKit to quiesce (or timeout)");
4692 store
= SCDynamicStoreCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
, NULL
);
4693 if (store
== NULL
) {
4697 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
4698 keys
= CFArrayCreate(NULL
, (const void **)&key
, 1, &kCFTypeArrayCallBacks
);
4699 ok
= SCDynamicStoreSetNotificationKeys(store
, keys
, NULL
);
4702 SC_log(LOG_NOTICE
, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
4707 CFArrayRef changedKeys
;
4708 CFDictionaryRef dict
;
4709 Boolean quiet
= FALSE
;
4712 dict
= SCDynamicStoreCopyValue(store
, key
);
4714 if (isA_CFDictionary(dict
) &&
4715 (CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Quiet
) ||
4716 CFDictionaryContainsKey(dict
, kInterfaceNamerKey_Timeout
))) {
4725 ok
= SCDynamicStoreNotifyWait(store
);
4727 SC_log(LOG_NOTICE
, "SCDynamicStoreNotifyWait() failed: %s", SCErrorString(SCError()));
4731 changedKeys
= SCDynamicStoreCopyNotifiedKeys(store
);
4732 if (changedKeys
!= NULL
) {
4733 CFRelease(changedKeys
);
4739 CRSetCrashLogMessage(NULL
);
4741 if (key
!= NULL
) CFRelease(key
);
4742 if (store
!= NULL
) CFRelease(store
);
4747 CFArrayRef
/* of SCNetworkInterfaceRef's */
4748 _SCNetworkInterfaceCopyAllWithPreferences(SCPreferencesRef prefs
)
4750 CFMutableArrayRef all_interfaces
;
4751 CFArrayRef new_interfaces
;
4752 Boolean temp_preferences
= FALSE
;
4754 /* initialize runtime */
4755 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
4757 /* wait for IOKit to quiesce */
4758 pthread_once(&iokit_quiet
, __waitForInterfaces
);
4760 all_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4762 // get Ethernet, Firewire, Thunderbolt, and AirPort interfaces
4763 new_interfaces
= __SCNetworkInterfaceCopyAll_IONetworkInterface(FALSE
);
4764 if (new_interfaces
!= NULL
) {
4765 add_interfaces(all_interfaces
, new_interfaces
);
4766 CFRelease(new_interfaces
);
4769 // get Modem interfaces
4770 new_interfaces
= __SCNetworkInterfaceCopyAll_Modem();
4771 if (new_interfaces
!= NULL
) {
4772 add_interfaces(all_interfaces
, new_interfaces
);
4773 CFRelease(new_interfaces
);
4776 // get serial (RS232) interfaces
4777 new_interfaces
= __SCNetworkInterfaceCopyAll_RS232();
4778 if (new_interfaces
!= NULL
) {
4779 add_interfaces(all_interfaces
, new_interfaces
);
4780 CFRelease(new_interfaces
);
4783 // get virtual network interfaces (Bond, Bridge, VLAN)
4784 if (prefs
== NULL
) {
4785 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterfaceCopyAll"), NULL
);
4786 if (prefs
!= NULL
) {
4787 temp_preferences
= TRUE
;
4790 if (prefs
!= NULL
) {
4791 #if !TARGET_OS_IPHONE
4792 new_interfaces
= SCBondInterfaceCopyAll(prefs
);
4793 if (new_interfaces
!= NULL
) {
4794 add_interfaces(all_interfaces
, new_interfaces
);
4795 CFRelease(new_interfaces
);
4797 #endif // !TARGET_OS_IPHONE
4799 new_interfaces
= SCBridgeInterfaceCopyAll(prefs
);
4800 if (new_interfaces
!= NULL
) {
4801 add_interfaces(all_interfaces
, new_interfaces
);
4802 CFRelease(new_interfaces
);
4805 new_interfaces
= SCVLANInterfaceCopyAll(prefs
);
4806 if (new_interfaces
!= NULL
) {
4807 add_interfaces(all_interfaces
, new_interfaces
);
4808 CFRelease(new_interfaces
);
4811 #if !TARGET_OS_IPHONE
4812 // add BT-PAN interface
4813 addBTPANInterface(all_interfaces
);
4814 #endif // !TARGET_OS_IPHONE
4816 if (temp_preferences
) CFRelease(prefs
);
4819 // all interfaces have been identified, order and return
4820 sort_interfaces(all_interfaces
);
4822 return all_interfaces
;
4826 CFArrayRef
/* of SCNetworkInterfaceRef's */
4827 SCNetworkInterfaceCopyAll()
4829 CFArrayRef all_interfaces
;
4831 all_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(NULL
);
4832 return all_interfaces
;
4836 CFArrayRef
/* of kSCNetworkInterfaceTypeXXX CFStringRef's */
4837 SCNetworkInterfaceGetSupportedInterfaceTypes(SCNetworkInterfaceRef interface
)
4840 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4842 if (!isA_SCNetworkInterface(interface
)) {
4843 _SCErrorSet(kSCStatusInvalidArgument
);
4847 if (interfacePrivate
->supported_interface_types
!= NULL
) {
4851 i
= findConfiguration(interfacePrivate
->interface_type
);
4852 if (i
!= kCFNotFound
) {
4853 if (configurations
[i
].supported_interfaces
!= doNone
) {
4854 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4855 if (configurations
[i
].supported_interfaces
& do6to4
) {
4856 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceType6to4
);
4858 if (configurations
[i
].supported_interfaces
& doL2TP
) {
4859 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeL2TP
);
4861 if (configurations
[i
].supported_interfaces
& doPPP
) {
4862 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypePPP
);
4864 if (configurations
[i
].supported_interfaces
& doIPSec
) {
4865 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeIPSec
);
4869 SCNetworkInterfaceRef child
;
4871 child
= SCNetworkInterfaceGetInterface(interface
);
4872 if ((child
!= NULL
) && CFEqual(child
, kSCNetworkInterfaceIPv4
)) {
4873 interfacePrivate
->supported_interface_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4874 CFArrayAppendValue(interfacePrivate
->supported_interface_types
, kSCNetworkInterfaceTypeVPN
);
4880 return interfacePrivate
->supported_interface_types
;
4884 CFArrayRef
/* of kSCNetworkProtocolTypeXXX CFStringRef's */
4885 SCNetworkInterfaceGetSupportedProtocolTypes(SCNetworkInterfaceRef interface
)
4888 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
4890 if (!isA_SCNetworkInterface(interface
)) {
4891 _SCErrorSet(kSCStatusInvalidArgument
);
4895 if (interfacePrivate
->supported_protocol_types
!= NULL
) {
4899 i
= findConfiguration(interfacePrivate
->interface_type
);
4900 if (i
!= kCFNotFound
) {
4901 if (configurations
[i
].supported_protocols
!= doNone
) {
4902 interfacePrivate
->supported_protocol_types
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
4903 if (configurations
[i
].supported_protocols
& doDNS
) {
4904 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeDNS
);
4906 if (configurations
[i
].supported_protocols
& doIPv4
) {
4907 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv4
);
4909 if (configurations
[i
].supported_protocols
& doIPv6
) {
4910 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeIPv6
);
4912 if (configurations
[i
].supported_protocols
& doProxies
) {
4913 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeProxies
);
4915 #if !TARGET_OS_IPHONE
4916 if (configurations
[i
].supported_protocols
& doSMB
) {
4917 CFArrayAppendValue(interfacePrivate
->supported_protocol_types
, kSCNetworkProtocolTypeSMB
);
4919 #endif // !TARGET_OS_IPHONE
4925 return interfacePrivate
->supported_protocol_types
;
4929 SCNetworkInterfaceRef
4930 SCNetworkInterfaceCreateWithInterface(SCNetworkInterfaceRef child
, CFStringRef interfaceType
)
4932 SCNetworkInterfacePrivateRef childPrivate
= (SCNetworkInterfacePrivateRef
)child
;
4934 SCNetworkInterfacePrivateRef parentPrivate
;
4936 if (!isA_SCNetworkInterface(child
)) {
4937 _SCErrorSet(kSCStatusInvalidArgument
);
4941 if (!isA_CFString(interfaceType
)) {
4942 _SCErrorSet(kSCStatusInvalidArgument
);
4946 if (CFEqual(child
, kSCNetworkInterfaceLoopback
)) {
4947 // can't layer on top of loopback
4948 _SCErrorSet(kSCStatusInvalidArgument
);
4952 childIndex
= findConfiguration(childPrivate
->interface_type
);
4954 parentPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
,
4956 childPrivate
->prefs
,
4957 childPrivate
->serviceID
);
4958 if (parentPrivate
== NULL
) {
4959 _SCErrorSet(kSCStatusFailed
);
4963 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
4964 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPP
;
4965 parentPrivate
->entity_type
= kSCValNetInterfaceTypePPP
;
4968 if (childIndex
!= kCFNotFound
) {
4969 if (configurations
[childIndex
].ppp_subtype
!= NULL
) {
4970 parentPrivate
->entity_subtype
= *configurations
[childIndex
].ppp_subtype
;
4972 // sorry, the child interface does not support PPP
4976 // if the child's interface type not known, use the child entities "Type"
4977 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
4980 if (childPrivate
->entity_device
!= NULL
) {
4981 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
4984 if (childPrivate
->entity_device_unique
!= NULL
) {
4985 parentPrivate
->entity_device_unique
= CFStringCreateCopy(NULL
, childPrivate
->entity_device_unique
);
4987 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
4988 if ((childIndex
== kCFNotFound
) ||
4989 ((configurations
[childIndex
].supported_interfaces
& doL2TP
) != doL2TP
)) {
4990 // if the child interface does not support L2TP
4993 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeL2TP
;
4994 parentPrivate
->localized_key
= CFSTR("l2tp");
4995 parentPrivate
->entity_type
= kSCEntNetL2TP
; // interface config goes into "L2TP"
4996 #pragma GCC diagnostic push
4997 #pragma GCC diagnostic ignored "-Wdeprecated"
4998 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
4999 if ((childIndex
== kCFNotFound
) ||
5000 ((configurations
[childIndex
].supported_interfaces
& doPPTP
) != doPPTP
)) {
5001 // if the child interface does not support PPTP
5004 parentPrivate
->interface_type
= kSCNetworkInterfaceTypePPTP
;
5005 parentPrivate
->localized_key
= CFSTR("pptp");
5006 parentPrivate
->entity_type
= kSCEntNetPPTP
; // interface config goes into "PPTP"
5007 #pragma GCC diagnostic pop
5008 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceType6to4
)) {
5009 if ((childIndex
== kCFNotFound
) ||
5010 ((configurations
[childIndex
].supported_interfaces
& do6to4
) != do6to4
)) {
5011 // if the child interface does not support 6to4
5015 parentPrivate
->interface_type
= kSCNetworkInterfaceType6to4
;
5016 parentPrivate
->localized_key
= CFSTR("6to4");
5017 parentPrivate
->entity_type
= kSCValNetInterfaceType6to4
;
5018 parentPrivate
->entity_device
= CFRetain(CFSTR("stf0"));
5019 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
5020 if ((childIndex
== kCFNotFound
) ||
5021 ((configurations
[childIndex
].supported_interfaces
& doIPSec
) != doIPSec
)) {
5022 // if the child interface does not support IPSec
5025 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeIPSec
;
5026 parentPrivate
->localized_key
= CFSTR("ipsec");
5027 parentPrivate
->entity_type
= kSCValNetInterfaceTypeIPSec
;
5028 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
5029 if (childIndex
!= kCFNotFound
) {
5030 // if not a "vendor" child interface
5034 parentPrivate
->interface_type
= kSCNetworkInterfaceTypeVPN
;
5035 parentPrivate
->localized_key
= CFSTR("vpn");
5036 parentPrivate
->localized_arg1
= CFRetain(childPrivate
->entity_type
);
5037 parentPrivate
->entity_type
= kSCValNetInterfaceTypeVPN
;
5038 parentPrivate
->entity_subtype
= childPrivate
->entity_type
;
5039 if (childPrivate
->entity_device
!= NULL
) {
5040 parentPrivate
->entity_device
= CFStringCreateCopy(NULL
, childPrivate
->entity_device
);
5042 if (parentPrivate
->entity_subtype
!= NULL
) {
5043 CFArrayRef components
;
5045 CFStringRef vpnType
;
5048 // the "default" interface name is derived from the VPN type
5051 // com.apple.Apple-VPN.vpnplugin --> "Apple VPN"
5054 vpnType
= parentPrivate
->entity_subtype
;
5055 components
= CFStringCreateArrayBySeparatingStrings(NULL
, vpnType
, CFSTR("."));
5056 n
= CFArrayGetCount(components
);
5058 CFEqual(CFArrayGetValueAtIndex(components
, n
- 1), CFSTR("vpnplugin"))) {
5059 CFMutableStringRef str
;
5061 str
= CFStringCreateMutableCopy(NULL
,
5063 CFArrayGetValueAtIndex(components
, n
- 2));
5064 (void) CFStringFindAndReplace(str
,
5067 CFRangeMake(0, CFStringGetLength(str
)),
5069 parentPrivate
->localized_name
= str
;
5071 CFRelease(components
);
5073 } else if (CFStringFind(interfaceType
, CFSTR("."), 0).location
!= kCFNotFound
) {
5074 // if custom interface type
5075 pthread_mutex_lock(&lock
);
5076 if (vendor_interface_types
== NULL
) {
5077 vendor_interface_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
5079 CFSetAddValue(vendor_interface_types
, interfaceType
);
5080 parentPrivate
->interface_type
= CFSetGetValue(vendor_interface_types
, interfaceType
);
5081 pthread_mutex_unlock(&lock
);
5083 parentPrivate
->entity_type
= parentPrivate
->interface_type
; // interface config goes into a
5084 // a dictionary with the same
5085 // name as the interfaceType
5087 // unknown interface type
5091 parentPrivate
->hidden
= childPrivate
->hidden
;
5093 #if TARGET_OS_IPHONE
5094 parentPrivate
->trustRequired
= childPrivate
->trustRequired
;
5095 #endif // TARGET_OS_IPHONE
5097 if (childPrivate
->overrides
!= NULL
) {
5098 parentPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, childPrivate
->overrides
);
5101 // The following change handles the case where a user has both an Ethernet and
5102 // PPPoE network service. Because a PPPoE service is typically associated with
5103 // an ISP we want it to be sorted higher in the service order.
5104 if ((parentPrivate
->entity_subtype
!= NULL
) &&
5105 (CFEqual(parentPrivate
->entity_subtype
, kSCValNetInterfaceSubTypePPPoE
))) {
5106 if ((childPrivate
->interface_type
!= NULL
) &&
5107 (CFEqual(childPrivate
->interface_type
, kSCNetworkInterfaceTypeIEEE80211
))) {
5108 parentPrivate
->sort_order
= kSortAirportPPP
;
5110 parentPrivate
->sort_order
= kSortEthernetPPP
;
5113 // set sort order of the parent to match the child interface
5114 parentPrivate
->sort_order
= childPrivate
->sort_order
;
5117 return (SCNetworkInterfaceRef
)parentPrivate
;
5121 CFRelease(parentPrivate
);
5122 _SCErrorSet(kSCStatusInvalidArgument
);
5129 __SCNetworkInterfaceGetDefaultConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
5131 CFDictionaryRef config
= NULL
;
5132 CFStringRef defaultType
;
5133 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5135 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5136 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5138 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5139 if (defaultType
!= NULL
) {
5143 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5144 SCNetworkSetGetSetID(set
), // set
5145 interfacePrivate
->entity_device
, // interface
5146 defaultType
); // entity
5148 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5151 if (config
== NULL
) {
5152 // if the "set" does not have a saved configuration, use
5153 // the [template] "interface" configuration
5154 if (interfacePrivate
->unsaved
!= NULL
) {
5155 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, defaultType
);
5156 if (config
== (CFDictionaryRef
)kCFNull
) {
5161 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5172 static CFDictionaryRef
5173 __SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
,
5174 CFStringRef extendedType
)
5176 CFDictionaryRef config
= NULL
;
5177 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5180 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5181 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5183 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5184 if (paths
!= NULL
) {
5187 path
= CFArrayGetValueAtIndex(paths
, 0);
5188 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5192 if (interfacePrivate
->unsaved
!= NULL
) {
5193 config
= CFDictionaryGetValue(interfacePrivate
->unsaved
, extendedType
);
5194 if (config
== (CFDictionaryRef
)kCFNull
) {
5200 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5209 SCNetworkInterfaceGetConfiguration(SCNetworkInterfaceRef interface
)
5211 CFDictionaryRef config
;
5212 CFStringRef defaultType
;
5214 if (!isA_SCNetworkInterface(interface
)) {
5215 _SCErrorSet(kSCStatusInvalidArgument
);
5219 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5220 if (defaultType
== NULL
) {
5224 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
5225 if (config
== NULL
) {
5226 if (CFEqual(defaultType
, kSCEntNetAirPort
)) {
5227 SCNetworkInterfacePrivateRef interfacePrivate
;
5230 // if AirPort interface, check for a per-service config
5231 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5232 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
5233 interfacePrivate
->serviceID
, // service
5234 kSCEntNetAirPort
); // entity
5235 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
5239 if (config
== NULL
) {
5240 _SCErrorSet(kSCStatusOK
);
5248 SCNetworkInterfaceGetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5249 CFStringRef extendedType
)
5251 CFDictionaryRef config
;
5253 if (!isA_SCNetworkInterface(interface
)) {
5254 _SCErrorSet(kSCStatusInvalidArgument
);
5258 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5259 _SCErrorSet(kSCStatusInvalidArgument
);
5263 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
5264 if (config
== NULL
) {
5265 _SCErrorSet(kSCStatusOK
);
5274 __SCNetworkInterfaceGetEntityType(SCNetworkInterfaceRef interface
)
5276 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5278 return interfacePrivate
->entity_type
;
5284 __SCNetworkInterfaceGetEntitySubType(SCNetworkInterfaceRef interface
)
5286 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
) interface
;
5288 return interfacePrivate
->entity_subtype
;
5293 SCNetworkInterfaceGetBSDName(SCNetworkInterfaceRef interface
)
5295 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5297 if (!isA_SCNetworkInterface(interface
)) {
5298 _SCErrorSet(kSCStatusInvalidArgument
);
5302 if ((interfacePrivate
->interface
!= NULL
) &&
5303 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
)) {
5304 _SCErrorSet(kSCStatusOK
);
5308 return interfacePrivate
->entity_device
;
5313 SCNetworkInterfaceGetHardwareAddressString(SCNetworkInterfaceRef interface
)
5315 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5317 if (!isA_SCNetworkInterface(interface
)) {
5318 _SCErrorSet(kSCStatusInvalidArgument
);
5322 if ((interfacePrivate
->address
!= NULL
) &&
5323 (interfacePrivate
->addressString
== NULL
)) {
5327 char mac
[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
5330 bp
= (uint8_t *)CFDataGetBytePtr(interfacePrivate
->address
);
5331 n
= CFDataGetLength(interfacePrivate
->address
) * 3;
5333 if (n
> sizeof(mac
)) {
5334 mac_p
= CFAllocatorAllocate(NULL
, n
, 0);
5337 for (cp
= mac_p
; n
> 0; n
-= 3) {
5338 cp
+= snprintf(cp
, n
, "%2.2x:", *bp
++);
5341 interfacePrivate
->addressString
= CFStringCreateWithCString(NULL
, mac_p
, kCFStringEncodingUTF8
);
5342 if (mac_p
!= mac
) CFAllocatorDeallocate(NULL
, mac_p
);
5345 return interfacePrivate
->addressString
;
5349 SCNetworkInterfaceRef
5350 SCNetworkInterfaceGetInterface(SCNetworkInterfaceRef interface
)
5352 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5354 if (!isA_SCNetworkInterface(interface
)) {
5355 _SCErrorSet(kSCStatusInvalidArgument
);
5359 return interfacePrivate
->interface
;
5364 SCNetworkInterfaceGetInterfaceType(SCNetworkInterfaceRef interface
)
5366 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5368 if (!isA_SCNetworkInterface(interface
)) {
5369 _SCErrorSet(kSCStatusInvalidArgument
);
5373 return interfacePrivate
->interface_type
;
5378 copy_string_from_bundle(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5380 CFStringRef str
= NULL
;
5383 str
= CFBundleCopyLocalizedString(bundle
,
5386 NETWORKINTERFACE_LOCALIZATIONS
);
5388 str
= _SC_CFBundleCopyNonLocalizedString(bundle
,
5391 NETWORKINTERFACE_LOCALIZATIONS
);
5399 copy_interface_string(CFBundleRef bundle
, CFStringRef key
, Boolean localized
)
5401 static Boolean reported
= FALSE
;
5402 CFStringRef str
= NULL
;
5404 str
= copy_string_from_bundle(bundle
, key
, localized
);
5407 SC_log(LOG_ERR
, "Received NULL string for the interface key: {Bundle: %@, key: %@, localized: %d}", bundle
,
5413 if (CFEqual(str
, key
) && !reported
) {
5414 const CFStringRef knownStrKey
= CFSTR("airport");
5415 CFStringRef knownStrValue
= NULL
;
5417 knownStrValue
= copy_string_from_bundle(bundle
, knownStrKey
, localized
);
5418 if (knownStrValue
== NULL
|| CFEqual(knownStrValue
, knownStrKey
)) {
5419 /* We are here because we requested for a localized/non-localized string
5420 based on the localization key, but we were given the same key/NULL back,
5421 implying a bad...bad thing!
5423 SC_log(LOG_ERR
, "Failed to retrieve the interface string: {Bundle: %@, key: %@, localized: %d}", bundle
,
5427 #if TARGET_OS_IPHONE
5428 /* ...and we want to know about it! */
5429 _SC_crash("Failed to retrieve interface string", NULL
, NULL
);
5430 #endif //TARGET_OS_IPHONE
5434 if (knownStrValue
!= NULL
) {
5435 CFRelease(knownStrValue
);
5445 copy_display_name(SCNetworkInterfaceRef interface
, Boolean localized
, Boolean oldLocalization
)
5447 CFMutableStringRef local
;
5450 local
= CFStringCreateMutable(NULL
, 0);
5452 while (interface
!= NULL
) {
5453 Boolean added
= FALSE
;
5454 SCNetworkInterfaceRef child
= NULL
;
5455 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5457 if ((interfacePrivate
->interface
!= NULL
) &&
5458 (interfacePrivate
->interface
!= kSCNetworkInterfaceIPv4
) &&
5459 !CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeVPN
)) {
5460 child
= interfacePrivate
->interface
;
5463 if ((bundle
!= NULL
) && (interfacePrivate
->localized_key
!= NULL
)) {
5465 CFStringRef key
= interfacePrivate
->localized_key
;
5467 if (oldLocalization
) {
5468 key
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("X-%@"),
5469 interfacePrivate
->localized_key
);
5471 fmt
= copy_interface_string(bundle
, key
, localized
);
5473 CFStringAppendFormat(local
,
5476 interfacePrivate
->localized_arg1
,
5477 interfacePrivate
->localized_arg2
);
5481 if (oldLocalization
) {
5487 (interfacePrivate
->prefs
!= NULL
) &&
5488 (interfacePrivate
->serviceID
!= NULL
) &&
5490 CFDictionaryRef entity
;
5493 // check for (and use) the name of the interface when it
5494 // was last available
5495 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
5496 interfacePrivate
->serviceID
,
5497 kSCEntNetInterface
);
5498 entity
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
);
5500 if (isA_CFDictionary(entity
)) {
5503 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
5504 if (isA_CFString(name
)) {
5505 CFStringAppend(local
, name
);
5512 // create (non-)localized name based on the interface type
5513 CFStringAppend(local
, interfacePrivate
->interface_type
);
5515 // ... and, if this is a leaf node, the interface device
5516 if ((interfacePrivate
->entity_device
!= NULL
) && (child
== NULL
)) {
5517 CFStringAppendFormat(local
, NULL
, CFSTR(" (%@)"), interfacePrivate
->entity_device
);
5521 if (child
!= NULL
) {
5522 // if this interface is layered over another
5523 CFStringAppend(local
, CFSTR(" --> "));
5529 name
= CFStringCreateCopy(NULL
, local
);
5536 #if !TARGET_OS_IPHONE
5539 __SCNetworkInterfaceCopyXLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5543 if (!isA_SCNetworkInterface(interface
)) {
5544 _SCErrorSet(kSCStatusInvalidArgument
);
5548 name
= copy_display_name(interface
, TRUE
, TRUE
);
5555 __SCNetworkInterfaceCopyXNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5557 CFStringRef localized_name
;
5559 if (!isA_SCNetworkInterface(interface
)) {
5560 _SCErrorSet(kSCStatusInvalidArgument
);
5564 localized_name
= copy_display_name(interface
, FALSE
, TRUE
);
5565 return localized_name
;
5567 #endif // !TARGET_OS_IPHONE
5571 __SCNetworkInterfaceSetUserDefinedName(SCNetworkInterfaceRef interface
, CFStringRef name
)
5573 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5575 if (!isA_SCNetworkInterface(interface
)) {
5581 if (interfacePrivate
->name
!= NULL
) {
5582 CFRelease(interfacePrivate
->name
);
5584 interfacePrivate
->name
= name
;
5589 if (interfacePrivate
->localized_name
!= NULL
) {
5590 CFRelease(interfacePrivate
->localized_name
);
5592 interfacePrivate
->localized_name
= name
;
5597 __SCNetworkInterfaceGetUserDefinedName(SCNetworkInterfaceRef interface
)
5599 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5601 if (!isA_SCNetworkInterface(interface
)) {
5605 return interfacePrivate
->name
;
5611 __SCNetworkInterfaceGetNonLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5613 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5615 if (!isA_SCNetworkInterface(interface
)) {
5616 _SCErrorSet(kSCStatusInvalidArgument
);
5620 if (interfacePrivate
->name
== NULL
) {
5621 interfacePrivate
->name
= copy_display_name(interface
, FALSE
, FALSE
);
5624 return interfacePrivate
->name
;
5629 SCNetworkInterfaceGetLocalizedDisplayName(SCNetworkInterfaceRef interface
)
5631 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5633 if (!isA_SCNetworkInterface(interface
)) {
5634 _SCErrorSet(kSCStatusInvalidArgument
);
5638 if (interfacePrivate
->localized_name
== NULL
) {
5639 interfacePrivate
->localized_name
= copy_display_name(interface
, TRUE
, FALSE
);
5642 return interfacePrivate
->localized_name
;
5648 __SCNetworkInterfaceGetTemplateOverrides(SCNetworkInterfaceRef interface
, CFStringRef overrideType
)
5650 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5651 CFPropertyListRef overrides
= NULL
;
5653 if (interfacePrivate
->overrides
!= NULL
) {
5654 overrides
= CFDictionaryGetValue(interfacePrivate
->overrides
, overrideType
);
5662 SCNetworkInterfaceGetTypeID(void)
5664 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
); /* initialize runtime */
5665 return __kSCNetworkInterfaceTypeID
;
5671 __SCNetworkInterfaceSetDefaultConfiguration(SCNetworkSetRef set
,
5672 SCNetworkInterfaceRef interface
,
5673 CFStringRef defaultType
,
5674 CFDictionaryRef config
,
5677 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5680 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5681 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5683 if (defaultType
== NULL
) {
5684 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5685 if (defaultType
== NULL
) {
5690 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5697 path
= SCPreferencesPathKeyCreateSetNetworkInterfaceEntity(NULL
, // allocator
5698 SCNetworkSetGetSetID(set
), // set
5699 interfacePrivate
->entity_device
, // interface
5700 defaultType
); // entity
5702 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5705 // if configuration has been saved
5706 if (interfacePrivate
->unsaved
!= NULL
) {
5707 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, defaultType
);
5708 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5709 CFRelease(interfacePrivate
->unsaved
);
5710 interfacePrivate
->unsaved
= NULL
;
5716 if (config
== NULL
) {
5717 // remember that we are clearing the configuration
5718 config
= (CFDictionaryRef
)kCFNull
;
5721 if (interfacePrivate
->unsaved
== NULL
) {
5722 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5724 &kCFTypeDictionaryKeyCallBacks
,
5725 &kCFTypeDictionaryValueCallBacks
);
5727 CFDictionarySetValue(interfacePrivate
->unsaved
, defaultType
, config
);
5730 _SCErrorSet(kSCStatusNoKey
);
5741 __SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
,
5742 CFStringRef extendedType
,
5743 CFDictionaryRef config
,
5746 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5750 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
5751 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
5753 if (extendedType
== NULL
) {
5754 extendedType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5755 if (extendedType
== NULL
) {
5760 if (isA_CFDictionary(config
) && (CFDictionaryGetCount(config
) == 0)) {
5764 paths
= copyConfigurationPaths(interfacePrivate
, extendedType
);
5765 if (paths
!= NULL
) {
5769 n
= CFArrayGetCount(paths
);
5770 for (i
= 0; i
< n
; i
++) {
5773 path
= CFArrayGetValueAtIndex(paths
, i
);
5774 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
, path
, config
, FALSE
);
5781 // if configuration has been saved
5782 if (interfacePrivate
->unsaved
!= NULL
) {
5783 CFDictionaryRemoveValue(interfacePrivate
->unsaved
, extendedType
);
5784 if (CFDictionaryGetCount(interfacePrivate
->unsaved
) == 0) {
5785 CFRelease(interfacePrivate
->unsaved
);
5786 interfacePrivate
->unsaved
= NULL
;
5794 if (config
== NULL
) {
5795 // remember that we are clearing the configuration
5796 config
= (CFDictionaryRef
)kCFNull
;
5799 if (interfacePrivate
->unsaved
== NULL
) {
5800 interfacePrivate
->unsaved
= CFDictionaryCreateMutable(NULL
,
5802 &kCFTypeDictionaryKeyCallBacks
,
5803 &kCFTypeDictionaryValueCallBacks
);
5805 CFDictionarySetValue(interfacePrivate
->unsaved
, extendedType
, config
);
5808 _SCErrorSet(kSCStatusNoKey
);
5817 SCNetworkInterfaceSetConfiguration(SCNetworkInterfaceRef interface
, CFDictionaryRef config
)
5819 CFStringRef defaultType
;
5822 if (!isA_SCNetworkInterface(interface
)) {
5823 _SCErrorSet(kSCStatusInvalidArgument
);
5827 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
5828 if (defaultType
== NULL
) {
5832 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, FALSE
);
5834 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetConfiguration(): %@ -> %@",
5836 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5844 SCNetworkInterfaceSetExtendedConfiguration(SCNetworkInterfaceRef interface
,
5845 CFStringRef extendedType
,
5846 CFDictionaryRef config
)
5850 if (!isA_SCNetworkInterface(interface
)) {
5851 _SCErrorSet(kSCStatusInvalidArgument
);
5855 if (!__SCNetworkInterfaceIsValidExtendedConfigurationType(interface
, extendedType
, TRUE
)) {
5859 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, FALSE
);
5861 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetExtendedConfiguration(): %@ -> %@",
5863 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
5871 #pragma mark SCNetworkInterface [Refresh Configuration] API
5875 _SCNetworkInterfaceForceConfigurationRefresh(CFStringRef ifName
)
5880 if (!isA_CFString(ifName
)) {
5881 _SCErrorSet(kSCStatusInvalidArgument
);
5885 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
5886 kSCDynamicStoreDomainState
,
5888 kSCEntNetRefreshConfiguration
);
5889 ok
= SCDynamicStoreNotifyValue(NULL
, key
);
5896 __SCNetworkInterfaceForceConfigurationRefresh_helper(SCPreferencesRef prefs
, CFStringRef ifName
)
5898 CFDataRef data
= NULL
;
5900 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5901 uint32_t status
= kSCStatusOK
;
5902 CFDataRef reply
= NULL
;
5904 if (prefsPrivate
->helper_port
== MACH_PORT_NULL
) {
5905 ok
= __SCPreferencesCreate_helper(prefs
);
5911 // serialize the interface name
5912 ok
= _SCSerializeString(ifName
, &data
, NULL
, NULL
);
5917 // have the helper "refresh" the configuration
5918 status
= kSCStatusOK
;
5920 ok
= _SCHelperExec(prefsPrivate
->helper_port
,
5921 SCHELPER_MSG_INTERFACE_REFRESH
,
5925 if (data
!= NULL
) CFRelease(data
);
5930 if (status
!= kSCStatusOK
) {
5939 if (prefsPrivate
->helper_port
!= MACH_PORT_NULL
) {
5940 _SCHelperClose(&prefsPrivate
->helper_port
);
5943 status
= kSCStatusAccessError
;
5948 _SCErrorSet(status
);
5954 SCNetworkInterfaceForceConfigurationRefresh(SCNetworkInterfaceRef interface
)
5957 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
5959 if (!isA_SCNetworkInterface(interface
)) {
5960 _SCErrorSet(kSCStatusInvalidArgument
);
5964 ifName
= SCNetworkInterfaceGetBSDName(interface
);
5965 if (ifName
== NULL
) {
5966 _SCErrorSet(kSCStatusInvalidArgument
);
5970 if (interfacePrivate
->prefs
!= NULL
) {
5971 SCPreferencesRef prefs
= interfacePrivate
->prefs
;
5972 SCPreferencesPrivateRef prefsPrivate
= (SCPreferencesPrivateRef
)prefs
;
5974 if (prefsPrivate
->authorizationData
!= NULL
) {
5975 return __SCNetworkInterfaceForceConfigurationRefresh_helper(prefs
, ifName
);
5979 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5983 #if !TARGET_OS_IPHONE
5985 SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName
)
5987 return _SCNetworkInterfaceForceConfigurationRefresh(ifName
);
5989 #endif // !TARGET_OS_IPHONE
5993 #pragma mark SCNetworkInterface Password APIs
5997 getPasswordID(CFDictionaryRef config
, CFStringRef serviceID
)
5999 CFStringRef unique_id
= NULL
;
6001 if (config
!= NULL
) {
6002 CFStringRef encryption
;
6004 encryption
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPasswordEncryption
);
6005 if (isA_CFString(encryption
) &&
6006 CFEqual(encryption
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
6007 unique_id
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthPassword
);
6010 if (unique_id
== NULL
) {
6011 unique_id
= serviceID
;
6019 copySharedSecretID(CFDictionaryRef config
, CFStringRef serviceID
)
6021 CFMutableStringRef shared_id
= NULL
;
6023 if (config
!= NULL
) {
6024 CFStringRef encryption
;
6026 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecretEncryption
);
6027 if (isA_CFString(encryption
) &&
6028 CFEqual(encryption
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
6029 shared_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecSharedSecret
);
6030 if (shared_id
!= NULL
) {
6031 CFRetain(shared_id
);
6036 if (shared_id
== NULL
) {
6037 CFStringRef unique_id
;
6039 unique_id
= getPasswordID(config
, serviceID
);
6040 shared_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6041 CFStringAppend(shared_id
, CFSTR(".SS"));
6049 copyXAuthID(CFDictionaryRef config
, CFStringRef serviceID
)
6051 CFMutableStringRef xauth_id
= NULL
;
6053 if (config
!= NULL
) {
6054 CFStringRef encryption
;
6056 encryption
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPasswordEncryption
);
6057 if (isA_CFString(encryption
) &&
6058 CFEqual(encryption
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
6059 xauth_id
= (CFMutableStringRef
)CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthPassword
);
6060 if (xauth_id
!= NULL
) {
6066 if (xauth_id
== NULL
) {
6067 CFStringRef unique_id
;
6069 unique_id
= getPasswordID(config
, serviceID
);
6070 xauth_id
= CFStringCreateMutableCopy(NULL
, 0, unique_id
);
6071 CFStringAppend(xauth_id
, CFSTR(".XAUTH"));
6079 checkInterfacePassword(SCNetworkInterfaceRef interface
,
6080 SCNetworkInterfacePasswordType passwordType
,
6081 SCPreferencesRef
*prefs
,
6082 CFStringRef
*serviceID
)
6084 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
6086 if (!isA_SCNetworkInterface(interface
)) {
6090 *serviceID
= interfacePrivate
->serviceID
;
6091 if (*serviceID
== NULL
) {
6095 *prefs
= interfacePrivate
->prefs
;
6096 if (*prefs
== NULL
) {
6100 switch (passwordType
) {
6101 case kSCNetworkInterfacePasswordTypePPP
: {
6102 CFStringRef interfaceType
;
6104 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6105 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6113 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6114 CFStringRef interfaceType
;
6116 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6117 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
6118 interface
= SCNetworkInterfaceGetInterface(interface
);
6119 if (interface
!= NULL
) {
6120 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6121 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
6122 // if PPP->L2TP interface
6126 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6127 // if IPSec interface
6134 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6138 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6139 CFStringRef interfaceType
;
6141 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6142 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
6143 // if IPSec interface
6150 case kSCNetworkInterfacePasswordTypeVPN
: {
6151 CFStringRef interfaceType
;
6153 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
6154 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
6170 _SCErrorSet(kSCStatusInvalidArgument
);
6176 SCNetworkInterfaceCheckPassword(SCNetworkInterfaceRef interface
,
6177 SCNetworkInterfacePasswordType passwordType
)
6179 Boolean exists
= FALSE
;
6180 SCPreferencesRef prefs
= NULL
;
6181 CFStringRef serviceID
= NULL
;
6183 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6187 switch (passwordType
) {
6188 case kSCNetworkInterfacePasswordTypePPP
: {
6189 CFDictionaryRef config
;
6190 CFStringRef unique_id
;
6192 // get configuration
6193 config
= SCNetworkInterfaceGetConfiguration(interface
);
6196 unique_id
= getPasswordID(config
, serviceID
);
6199 exists
= __extract_password(prefs
,
6201 kSCPropNetPPPAuthPassword
,
6202 kSCPropNetPPPAuthPasswordEncryption
,
6203 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6209 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6210 CFDictionaryRef config
;
6212 CFStringRef shared_id
;
6214 // get configuration
6215 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6217 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6219 config
= SCNetworkInterfaceGetConfiguration(interface
);
6222 // get sharedSecret ID
6223 shared_id
= copySharedSecretID(config
, serviceID
);
6226 exists
= __extract_password(prefs
,
6228 kSCPropNetIPSecSharedSecret
,
6229 kSCPropNetIPSecSharedSecretEncryption
,
6230 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6233 CFRelease(shared_id
);
6237 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6238 CFDictionaryRef config
;
6239 CFStringRef unique_id
= NULL
;
6241 // get configuration
6242 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6244 // get 802.1X identifier
6245 if (config
!= NULL
) {
6246 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6248 if (!isA_CFString(unique_id
)) {
6253 exists
= _SCPreferencesSystemKeychainPasswordItemExists(prefs
, unique_id
);
6257 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6258 CFDictionaryRef config
;
6259 CFStringRef xauth_id
;
6261 // get configuration
6262 config
= SCNetworkInterfaceGetConfiguration(interface
);
6265 xauth_id
= copyXAuthID(config
, serviceID
);
6268 exists
= __extract_password(prefs
,
6270 kSCPropNetIPSecXAuthPassword
,
6271 kSCPropNetIPSecXAuthPasswordEncryption
,
6272 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6275 CFRelease(xauth_id
);
6279 case kSCNetworkInterfacePasswordTypeVPN
: {
6280 CFDictionaryRef config
;
6283 // get configuration
6284 config
= SCNetworkInterfaceGetConfiguration(interface
);
6287 vpn_id
= getPasswordID(config
, serviceID
);
6290 exists
= __extract_password(prefs
,
6292 kSCPropNetVPNAuthPassword
,
6293 kSCPropNetVPNAuthPasswordEncryption
,
6294 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6301 _SCErrorSet(kSCStatusInvalidArgument
);
6310 SCNetworkInterfaceCopyPassword(SCNetworkInterfaceRef interface
,
6311 SCNetworkInterfacePasswordType passwordType
)
6313 CFDataRef password
= NULL
;
6314 SCPreferencesRef prefs
= NULL
;
6315 CFStringRef serviceID
= NULL
;
6317 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6321 switch (passwordType
) {
6322 case kSCNetworkInterfacePasswordTypePPP
: {
6323 CFDictionaryRef config
;
6324 CFStringRef unique_id
;
6326 // get configuration
6327 config
= SCNetworkInterfaceGetConfiguration(interface
);
6330 unique_id
= getPasswordID(config
, serviceID
);
6333 (void) __extract_password(prefs
,
6335 kSCPropNetPPPAuthPassword
,
6336 kSCPropNetPPPAuthPasswordEncryption
,
6337 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6343 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6344 CFDictionaryRef config
;
6346 CFStringRef shared_id
;
6348 // get configuration
6349 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6351 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6353 config
= SCNetworkInterfaceGetConfiguration(interface
);
6356 // get sharedSecret ID
6357 shared_id
= copySharedSecretID(config
, serviceID
);
6360 (void) __extract_password(prefs
,
6362 kSCPropNetIPSecSharedSecret
,
6363 kSCPropNetIPSecSharedSecretEncryption
,
6364 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6368 CFRelease(shared_id
);
6372 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6373 CFDictionaryRef config
;
6374 CFStringRef unique_id
= NULL
;
6376 // get configuration
6377 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6379 // get 802.1X identifier
6380 if (config
!= NULL
) {
6381 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6383 if (!isA_CFString(unique_id
)) {
6384 _SCErrorSet(kSCStatusFailed
);
6389 password
= _SCPreferencesSystemKeychainPasswordItemCopy(prefs
, unique_id
);
6393 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6394 CFDictionaryRef config
;
6395 CFStringRef xauth_id
;
6397 // get configuration
6398 config
= SCNetworkInterfaceGetConfiguration(interface
);
6401 xauth_id
= copyXAuthID(config
, serviceID
);
6404 (void) __extract_password(prefs
,
6406 kSCPropNetIPSecXAuthPassword
,
6407 kSCPropNetIPSecXAuthPasswordEncryption
,
6408 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6411 CFRelease(xauth_id
);
6415 case kSCNetworkInterfacePasswordTypeVPN
: {
6416 CFDictionaryRef config
;
6419 // get configuration
6420 config
= SCNetworkInterfaceGetConfiguration(interface
);
6423 vpn_id
= getPasswordID(config
, serviceID
);
6426 (void) __extract_password(prefs
,
6428 kSCPropNetVPNAuthPassword
,
6429 kSCPropNetVPNAuthPasswordEncryption
,
6430 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6437 _SCErrorSet(kSCStatusInvalidArgument
);
6446 SCNetworkInterfaceRemovePassword(SCNetworkInterfaceRef interface
,
6447 SCNetworkInterfacePasswordType passwordType
)
6450 SCPreferencesRef prefs
= NULL
;
6451 CFStringRef serviceID
= NULL
;
6453 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6457 switch (passwordType
) {
6458 case kSCNetworkInterfacePasswordTypePPP
: {
6459 CFDictionaryRef config
;
6460 CFDictionaryRef newConfig
= NULL
;
6461 CFStringRef unique_id
;
6463 // get configuration
6464 config
= SCNetworkInterfaceGetConfiguration(interface
);
6467 unique_id
= getPasswordID(config
, serviceID
);
6470 ok
= __remove_password(prefs
,
6472 kSCPropNetPPPAuthPassword
,
6473 kSCPropNetPPPAuthPasswordEncryption
,
6474 kSCValNetPPPAuthPasswordEncryptionKeychain
,
6478 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6479 if (newConfig
!= NULL
) CFRelease(newConfig
);
6485 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6486 CFDictionaryRef config
;
6488 CFDictionaryRef newConfig
= NULL
;
6489 CFStringRef shared_id
;
6491 // get configuration
6492 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6494 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6496 config
= SCNetworkInterfaceGetConfiguration(interface
);
6499 // get sharedSecret ID
6500 shared_id
= copySharedSecretID(config
, serviceID
);
6503 ok
= __remove_password(prefs
,
6505 kSCPropNetIPSecSharedSecret
,
6506 kSCPropNetIPSecSharedSecretEncryption
,
6507 kSCValNetIPSecSharedSecretEncryptionKeychain
,
6512 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6516 ok
= SCNetworkInterfaceSetConfiguration(interface
,
6519 if (newConfig
!= NULL
) CFRelease(newConfig
);
6522 CFRelease(shared_id
);
6526 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6527 CFDictionaryRef config
;
6528 CFStringRef unique_id
= NULL
;
6530 // get configuration
6531 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6533 // get 802.1X identifier
6534 if (config
!= NULL
) {
6535 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6537 if (!isA_CFString(unique_id
)) {
6538 _SCErrorSet(kSCStatusFailed
);
6543 ok
= _SCPreferencesSystemKeychainPasswordItemRemove(prefs
, unique_id
);
6547 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6548 CFDictionaryRef config
;
6549 CFDictionaryRef newConfig
= NULL
;
6550 CFStringRef xauth_id
;
6552 // get configuration
6553 config
= SCNetworkInterfaceGetConfiguration(interface
);
6556 xauth_id
= copyXAuthID(config
, serviceID
);
6559 ok
= __remove_password(prefs
,
6561 kSCPropNetIPSecXAuthPassword
,
6562 kSCPropNetIPSecXAuthPasswordEncryption
,
6563 kSCValNetIPSecXAuthPasswordEncryptionKeychain
,
6567 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6568 if (newConfig
!= NULL
) CFRelease(newConfig
);
6571 CFRelease(xauth_id
);
6575 case kSCNetworkInterfacePasswordTypeVPN
: {
6576 CFDictionaryRef config
;
6577 CFDictionaryRef newConfig
= NULL
;
6580 // get configuration
6581 config
= SCNetworkInterfaceGetConfiguration(interface
);
6584 vpn_id
= getPasswordID(config
, serviceID
);
6587 ok
= __remove_password(prefs
,
6589 kSCPropNetVPNAuthPassword
,
6590 kSCPropNetVPNAuthPasswordEncryption
,
6591 kSCValNetVPNAuthPasswordEncryptionKeychain
,
6595 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6596 if (newConfig
!= NULL
) CFRelease(newConfig
);
6602 _SCErrorSet(kSCStatusInvalidArgument
);
6611 SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef interface
,
6612 SCNetworkInterfacePasswordType passwordType
,
6614 CFDictionaryRef options
)
6616 CFStringRef account
= NULL
;
6617 CFDictionaryRef config
;
6618 CFStringRef description
= NULL
;
6619 CFStringRef label
= NULL
;
6621 SCPreferencesRef prefs
= NULL
;
6622 CFStringRef serviceID
= NULL
;
6624 if (!checkInterfacePassword(interface
, passwordType
, &prefs
, &serviceID
)) {
6628 switch (passwordType
) {
6629 case kSCNetworkInterfacePasswordTypePPP
: {
6630 SCNetworkServiceRef service
= NULL
;
6631 CFStringRef unique_id
;
6633 // get configuration
6634 config
= SCNetworkInterfaceGetConfiguration(interface
);
6637 unique_id
= getPasswordID(config
, serviceID
);
6639 // get "Account", "Name", "Kind"
6640 if (config
!= NULL
) {
6641 // auth name --> keychain "Account"
6642 account
= CFDictionaryGetValue(config
, kSCPropNetPPPAuthName
);
6644 // PPP [user defined] "name" --> keychain "Name"
6645 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6648 if (label
== NULL
) {
6649 // service name --> keychain "Name"
6650 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6655 label
= SCNetworkServiceGetName(service
);
6656 if (label
== NULL
) {
6657 // interface name --> keychain "Name"
6658 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6662 if (bundle
!= NULL
) {
6663 // "PPP Password" --> keychain "Kind"
6664 description
= CFBundleCopyLocalizedString(bundle
,
6665 CFSTR("KEYCHAIN_KIND_PPP_PASSWORD"),
6666 CFSTR("PPP Password"),
6671 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6673 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6674 (description
!= NULL
) ? description
: CFSTR("PPP Password"),
6679 CFMutableDictionaryRef newConfig
;
6681 if (config
!= NULL
) {
6682 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6684 newConfig
= CFDictionaryCreateMutable(NULL
,
6686 &kCFTypeDictionaryKeyCallBacks
,
6687 &kCFTypeDictionaryValueCallBacks
);
6689 CFDictionarySetValue(newConfig
,
6690 kSCPropNetPPPAuthPassword
,
6692 CFDictionarySetValue(newConfig
,
6693 kSCPropNetPPPAuthPasswordEncryption
,
6694 kSCValNetPPPAuthPasswordEncryptionKeychain
);
6695 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6696 CFRelease(newConfig
);
6699 if (description
!= NULL
) CFRelease(description
);
6700 if (service
!= NULL
) CFRelease(service
);
6704 case kSCNetworkInterfacePasswordTypeIPSecSharedSecret
: {
6705 CFDictionaryRef baseConfig
= NULL
;
6707 SCNetworkServiceRef service
= NULL
;
6708 CFStringRef shared_id
;
6710 // get configuration
6711 extended
= CFEqual(SCNetworkInterfaceGetInterfaceType(interface
), kSCNetworkInterfaceTypePPP
);
6712 config
= SCNetworkInterfaceGetConfiguration(interface
);
6714 baseConfig
= config
;
6715 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
6718 // get sharedSecret ID
6719 shared_id
= copySharedSecretID(config
, serviceID
);
6721 // get "Account", "Name", "Kind"
6722 if (config
!= NULL
) {
6723 CFStringRef localIdentifier
;
6724 CFStringRef localIdentifierType
;
6726 if (CFDictionaryGetValueIfPresent(config
,
6727 kSCPropNetIPSecLocalIdentifierType
,
6728 (const void **)&localIdentifierType
)
6729 && CFEqual(localIdentifierType
, kSCValNetIPSecLocalIdentifierTypeKeyID
)
6730 && CFDictionaryGetValueIfPresent(config
,
6731 kSCPropNetIPSecLocalIdentifier
,
6732 (const void **)&localIdentifier
)
6733 && isA_CFString(localIdentifier
)) {
6734 // local identifier --> keychain "Account"
6735 account
= localIdentifier
;
6738 // PPP [user defined] "name" --> keychain "Name"
6740 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6742 if (baseConfig
!= NULL
) {
6743 label
= CFDictionaryGetValue(baseConfig
, kSCPropUserDefinedName
);
6748 if (label
== NULL
) {
6749 // service name --> keychain "Name"
6750 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6755 label
= SCNetworkServiceGetName(service
);
6756 if (label
== NULL
) {
6757 // interface name --> keychain "Name"
6758 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6762 if (bundle
!= NULL
) {
6763 // "IPSec Shared Secret" --> keychain "Kind"
6764 description
= CFBundleCopyLocalizedString(bundle
,
6765 CFSTR("KEYCHAIN_KIND_IPSEC_SHARED_SECRET"),
6766 CFSTR("IPSec Shared Secret"),
6771 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6773 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6774 (description
!= NULL
) ? description
: CFSTR("IPSec Shared Secret"),
6779 CFMutableDictionaryRef newConfig
= NULL
;
6781 if (config
!= NULL
) {
6782 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6784 newConfig
= CFDictionaryCreateMutable(NULL
,
6786 &kCFTypeDictionaryKeyCallBacks
,
6787 &kCFTypeDictionaryValueCallBacks
);
6789 CFDictionarySetValue(newConfig
,
6790 kSCPropNetIPSecSharedSecret
,
6792 CFDictionarySetValue(newConfig
,
6793 kSCPropNetIPSecSharedSecretEncryption
,
6794 kSCValNetIPSecSharedSecretEncryptionKeychain
);
6796 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6800 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6802 CFRelease(newConfig
);
6805 if (description
!= NULL
) CFRelease(description
);
6806 if (service
!= NULL
) CFRelease(service
);
6807 CFRelease(shared_id
);
6811 case kSCNetworkInterfacePasswordTypeEAPOL
: {
6812 CFStringRef account
= NULL
;
6813 CFStringRef unique_id
= NULL
;
6815 // get configuration
6816 config
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetEAPOL
);
6818 // get 802.1X identifier
6819 if (config
!= NULL
) {
6820 unique_id
= CFDictionaryGetValue(config
, kEAPClientPropUserPasswordKeychainItemID
);
6821 unique_id
= isA_CFString(unique_id
);
6823 if (unique_id
!= NULL
) {
6824 CFRetain(unique_id
);
6828 uuid
= CFUUIDCreate(NULL
);
6829 unique_id
= CFUUIDCreateString(NULL
, uuid
);
6833 // 802.1x UserName --> keychain "Account"
6834 if (config
!= NULL
) {
6835 account
= CFDictionaryGetValue(config
, kEAPClientPropUserName
);
6838 // get "Name", "Kind"
6839 if (bundle
!= NULL
) {
6840 CFStringRef interface_name
;
6842 // "Network Connection (%@)" --> keychain "Name"
6843 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6844 if (interface_name
!= NULL
) {
6845 CFStringRef label_fmt
;
6847 label_fmt
= CFBundleCopyLocalizedString(bundle
,
6848 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL_INTERFACE"),
6849 CFSTR("Network Connection (%@)"),
6851 label
= CFStringCreateWithFormat(NULL
, NULL
, label_fmt
, interface_name
);
6852 CFRelease(label_fmt
);
6854 label
= CFBundleCopyLocalizedString(bundle
,
6855 CFSTR("KEYCHAIN_DESCRIPTION_EAPOL"),
6856 CFSTR("Network Connection"),
6860 // "802.1X Password" --> keychain "Kind"
6861 description
= CFBundleCopyLocalizedString(bundle
,
6862 CFSTR("KEYCHAIN_KIND_EAPOL"),
6863 CFSTR("802.1X Password"),
6868 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6870 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6871 (description
!= NULL
) ? description
: CFSTR("802.1X Password"),
6876 CFMutableDictionaryRef newConfig
= NULL
;
6878 if (config
!= NULL
) {
6879 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6881 newConfig
= CFDictionaryCreateMutable(NULL
,
6883 &kCFTypeDictionaryKeyCallBacks
,
6884 &kCFTypeDictionaryValueCallBacks
);
6886 CFDictionarySetValue(newConfig
,
6887 kEAPClientPropUserPasswordKeychainItemID
,
6889 ok
= SCNetworkInterfaceSetExtendedConfiguration(interface
,
6892 CFRelease(newConfig
);
6895 CFRelease(unique_id
);
6896 if (label
!= NULL
) CFRelease(label
);
6897 if (description
!= NULL
) CFRelease(description
);
6901 case kSCNetworkInterfacePasswordTypeIPSecXAuth
: {
6902 SCNetworkServiceRef service
= NULL
;
6903 CFStringRef xauth_id
;
6905 // get configuration
6906 config
= SCNetworkInterfaceGetConfiguration(interface
);
6909 xauth_id
= copyXAuthID(config
, serviceID
);
6911 // get "Account", "Name", "Kind"
6912 if (config
!= NULL
) {
6913 // auth name --> keychain "Account"
6914 account
= CFDictionaryGetValue(config
, kSCPropNetIPSecXAuthName
);
6916 // IPSec [user defined] "name" --> keychain "Name"
6917 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6920 if (label
== NULL
) {
6921 // service name --> keychain "Name"
6922 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
6927 label
= SCNetworkServiceGetName(service
);
6928 if (label
== NULL
) {
6929 // interface name --> keychain "Name"
6930 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
6934 if (bundle
!= NULL
) {
6935 // "IPSec XAuth Password" --> keychain "Kind"
6936 description
= CFBundleCopyLocalizedString(bundle
,
6937 CFSTR("KEYCHAIN_KIND_IPSEC_XAUTH_PASSWORD"),
6938 CFSTR("IPSec XAuth Password"),
6943 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
6945 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
6946 (description
!= NULL
) ? description
: CFSTR("IPSec XAuth Password"),
6951 CFMutableDictionaryRef newConfig
;
6953 if (config
!= NULL
) {
6954 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
6956 newConfig
= CFDictionaryCreateMutable(NULL
,
6958 &kCFTypeDictionaryKeyCallBacks
,
6959 &kCFTypeDictionaryValueCallBacks
);
6961 CFDictionarySetValue(newConfig
,
6962 kSCPropNetIPSecXAuthPassword
,
6964 CFDictionarySetValue(newConfig
,
6965 kSCPropNetIPSecXAuthPasswordEncryption
,
6966 kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
6967 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
6968 CFRelease(newConfig
);
6971 CFRelease(xauth_id
);
6972 if (description
!= NULL
) CFRelease(description
);
6973 if (service
!= NULL
) CFRelease(service
);
6977 case kSCNetworkInterfacePasswordTypeVPN
: {
6978 SCNetworkServiceRef service
= NULL
;
6981 // get configuration
6982 config
= SCNetworkInterfaceGetConfiguration(interface
);
6985 vpn_id
= getPasswordID(config
, serviceID
);
6987 // get "Account", "Name", "Kind"
6988 if (config
!= NULL
) {
6989 // auth name --> keychain "Account"
6990 account
= CFDictionaryGetValue(config
, kSCPropNetVPNAuthName
);
6992 // VPN [user defined] "name" --> keychain "Name"
6993 label
= CFDictionaryGetValue(config
, kSCPropUserDefinedName
);
6996 if (label
== NULL
) {
6997 // service name --> keychain "Name"
6998 service
= (SCNetworkServiceRef
)__SCNetworkServiceCreatePrivate(NULL
,
7003 label
= SCNetworkServiceGetName(service
);
7004 if (label
== NULL
) {
7005 // interface name --> keychain "Name"
7006 label
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
7010 if (bundle
!= NULL
) {
7011 // "VPN Password" --> keychain "Kind"
7012 description
= CFBundleCopyLocalizedString(bundle
,
7013 CFSTR("KEYCHAIN_KIND_VPN_PASSWORD"),
7014 CFSTR("VPN Password"),
7019 ok
= _SCPreferencesSystemKeychainPasswordItemSet(prefs
,
7021 (label
!= NULL
) ? label
: CFSTR("Network Connection"),
7022 (description
!= NULL
) ? description
: CFSTR("VPN Password"),
7027 CFMutableDictionaryRef newConfig
;
7029 if (config
!= NULL
) {
7030 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
7032 newConfig
= CFDictionaryCreateMutable(NULL
,
7034 &kCFTypeDictionaryKeyCallBacks
,
7035 &kCFTypeDictionaryValueCallBacks
);
7037 CFDictionarySetValue(newConfig
,
7038 kSCPropNetVPNAuthPassword
,
7040 CFDictionarySetValue(newConfig
,
7041 kSCPropNetVPNAuthPasswordEncryption
,
7042 kSCValNetVPNAuthPasswordEncryptionKeychain
);
7043 ok
= SCNetworkInterfaceSetConfiguration(interface
, newConfig
);
7044 CFRelease(newConfig
);
7047 if (description
!= NULL
) CFRelease(description
);
7048 if (service
!= NULL
) CFRelease(service
);
7053 _SCErrorSet(kSCStatusInvalidArgument
);
7061 #pragma mark SCNetworkInterface [Advisory] SPIs
7062 #if TARGET_OS_SIMULATOR
7064 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7065 SCNetworkInterfaceAdvisory advisory
,
7068 #pragma unused(interface)
7069 #pragma unused(advisory)
7070 #pragma unused(reason)
7075 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7077 #pragma unused(interface)
7082 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7084 #pragma unused(interface)
7088 #else /* TARGET_OS_SIMULATOR */
7090 SCNetworkInterfaceSetAdvisory(SCNetworkInterfaceRef interface
,
7091 SCNetworkInterfaceAdvisory advisory
,
7094 IPMonitorControlRef control
;
7095 SCNetworkInterfacePrivateRef interfacePrivate
=
7096 (SCNetworkInterfacePrivateRef
)interface
;
7099 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7100 if (ifName
== NULL
) {
7101 _SCErrorSet(kSCStatusInvalidArgument
);
7104 control
= interfacePrivate
->IPMonitorControl
;
7105 if (control
== NULL
) {
7106 control
= IPMonitorControlCreate();
7107 if (control
== NULL
) {
7108 _SCErrorSet(kSCStatusFailed
);
7111 interfacePrivate
->IPMonitorControl
= control
;
7113 return IPMonitorControlSetInterfaceAdvisory(control
,
7120 SCNetworkInterfaceAdvisoryIsSet(SCNetworkInterfaceRef interface
)
7122 IPMonitorControlRef control
;
7123 SCNetworkInterfacePrivateRef interfacePrivate
=
7124 (SCNetworkInterfacePrivateRef
)interface
;
7127 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7128 if (ifName
== NULL
) {
7129 _SCErrorSet(kSCStatusInvalidArgument
);
7132 control
= interfacePrivate
->IPMonitorControl
;
7133 if (control
== NULL
) {
7134 control
= IPMonitorControlCreate();
7135 if (control
== NULL
) {
7136 _SCErrorSet(kSCStatusFailed
);
7139 interfacePrivate
->IPMonitorControl
= control
;
7141 return IPMonitorControlInterfaceAdvisoryIsSet(control
, ifName
);
7145 SCNetworkInterfaceCopyAdvisoryNotificationKey(SCNetworkInterfaceRef interface
)
7149 ifName
= SCNetworkInterfaceGetBSDName(interface
);
7150 if (ifName
== NULL
) {
7151 _SCErrorSet(kSCStatusInvalidArgument
);
7154 return IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifName
);
7156 #endif /* TARGET_OS_SIMULATOR */
7159 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
7163 _SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface
)
7165 CFMutableDictionaryRef info
;
7166 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7169 if (interface
== NULL
) {
7173 info
= CFDictionaryCreateMutable(NULL
,
7175 &kCFTypeDictionaryKeyCallBacks
,
7176 &kCFTypeDictionaryValueCallBacks
);
7178 // add non-localized interface name
7179 name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
7181 CFDictionaryAddValue(info
, kSCPropUserDefinedName
, name
);
7185 if ((interfacePrivate
->usb
.vid
!= NULL
) || (interfacePrivate
->usb
.pid
!= NULL
)) {
7186 #if !TARGET_OS_SIMULATOR
7187 if (interfacePrivate
->usb
.name
!= NULL
) {
7188 CFDictionaryAddValue(info
, CFSTR(kUSBProductString
), interfacePrivate
->usb
.name
);
7190 if (interfacePrivate
->usb
.vid
!= NULL
) {
7191 CFDictionaryAddValue(info
, CFSTR(kUSBVendorID
), interfacePrivate
->usb
.vid
);
7193 if (interfacePrivate
->usb
.pid
!= NULL
) {
7194 CFDictionaryAddValue(info
, CFSTR(kUSBProductID
), interfacePrivate
->usb
.pid
);
7196 #endif // !TARGET_OS_SIMULATOR
7199 if (CFDictionaryGetCount(info
) == 0) {
7200 // do not return an empty dictionary
7209 SCNetworkInterfaceRef
7210 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj
)
7212 SCNetworkInterfaceRef interface
= NULL
;
7214 /* initialize runtime */
7215 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7217 if (IOObjectConformsTo(if_obj
, kIONetworkInterfaceClass
)) {
7218 interface
= createInterface(if_obj
, processNetworkInterface
, NULL
);
7219 } else if (IOObjectConformsTo(if_obj
, kIOSerialBSDServiceValue
)) {
7220 interface
= createInterface(if_obj
, processSerialInterface
, kSCNetworkInterfaceHiddenPortKey
);
7228 _SCNetworkInterfaceGetConfigurationAction(SCNetworkInterfaceRef interface
)
7230 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7232 return interfacePrivate
->configurationAction
;
7237 _SCNetworkInterfaceGetHardwareAddress(SCNetworkInterfaceRef interface
)
7239 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7241 return interfacePrivate
->address
;
7246 _SCNetworkInterfaceGetIOInterfaceNamePrefix(SCNetworkInterfaceRef interface
)
7248 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7250 return interfacePrivate
->prefix
;
7255 _SCNetworkInterfaceGetIOInterfaceType(SCNetworkInterfaceRef interface
)
7257 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7259 return interfacePrivate
->type
;
7264 _SCNetworkInterfaceGetIOInterfaceUnit(SCNetworkInterfaceRef interface
)
7266 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7268 return interfacePrivate
->unit
;
7273 update_ift_family(SCNetworkInterfaceRef interface
)
7275 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7277 // note: family/subfamily are not in IORegistry, fetch with ioctl()
7279 if ((interfacePrivate
->family
== NULL
) && (interfacePrivate
->subfamily
== NULL
)) {
7280 CFStringRef bsdName
= SCNetworkInterfaceGetBSDName(interface
);
7283 memset(&ifr
, 0, sizeof(ifr
));
7284 if ((bsdName
!= NULL
) &&
7285 _SC_cfstring_to_cstring(bsdName
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
), kCFStringEncodingASCII
) != NULL
) {
7288 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
7290 if (ioctl(s
, SIOCGIFTYPE
, (caddr_t
)&ifr
) == -1) {
7291 ifr
.ifr_type
.ift_family
= 0;
7292 ifr
.ifr_type
.ift_subfamily
= 0;
7298 interfacePrivate
->family
= CFNumberCreate(NULL
,
7299 kCFNumberSInt32Type
,
7300 &ifr
.ifr_type
.ift_family
);
7301 interfacePrivate
->subfamily
= CFNumberCreate(NULL
,
7302 kCFNumberSInt32Type
,
7303 &ifr
.ifr_type
.ift_subfamily
);
7309 _SCNetworkInterfaceGetFamilyType(SCNetworkInterfaceRef interface
)
7311 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7313 // note: family not in IORegistry, fetch with ioctl()
7315 if (interfacePrivate
->family
== NULL
) {
7316 update_ift_family(interface
);
7319 return interfacePrivate
->family
;
7324 _SCNetworkInterfaceGetFamilySubType(SCNetworkInterfaceRef interface
)
7326 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7328 // note: subfamily not in IORegistry, fetch with ioctl()
7330 if (interfacePrivate
->subfamily
== NULL
) {
7331 update_ift_family(interface
);
7334 return interfacePrivate
->subfamily
;
7339 _SCNetworkInterfaceGetIOPath(SCNetworkInterfaceRef interface
)
7341 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7343 return interfacePrivate
->path
;
7348 _SCNetworkInterfaceGetIORegistryEntryID(SCNetworkInterfaceRef interface
)
7350 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7352 return interfacePrivate
->entryID
;
7358 __SCNetworkInterfaceIsActive (SCNetworkInterfaceRef interface
)
7360 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7362 return interfacePrivate
->active
;
7367 _SCNetworkInterfaceIsBuiltin(SCNetworkInterfaceRef interface
)
7369 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7371 return interfacePrivate
->builtin
;
7376 _SCNetworkInterfaceIsTrustRequired(SCNetworkInterfaceRef interface
)
7378 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7380 return interfacePrivate
->trustRequired
;
7385 #pragma mark SCNetworkInterface SPIs
7390 SCNetworkInterfaceRef
7391 _SCNetworkInterfaceCopyBTPANInterface(void)
7393 CFDictionaryRef dict
;
7394 SCNetworkInterfaceRef interface
= NULL
;
7397 key
= SCDynamicStoreKeyCreate(NULL
, CFSTR("%@" "InterfaceNamer"), kSCDynamicStoreDomainPlugin
);
7398 dict
= SCDynamicStoreCopyValue(NULL
, key
);
7402 CFStringRef if_name
;
7403 SCNetworkInterfacePrivateRef interfacePrivate
;
7405 if (isA_CFDictionary(dict
) &&
7406 CFDictionaryGetValueIfPresent(dict
,
7407 kInterfaceNamerKey_BT_PAN_Name
,
7408 (const void **)&if_name
) &&
7409 isA_CFString(if_name
)) {
7410 CFMutableDictionaryRef entity
;
7412 entity
= CFDictionaryCreateMutable(NULL
,
7414 &kCFTypeDictionaryKeyCallBacks
,
7415 &kCFTypeDictionaryValueCallBacks
);
7416 CFDictionarySetValue(entity
,
7417 kSCPropNetInterfaceType
,
7418 kSCValNetInterfaceTypeEthernet
);
7419 CFDictionarySetValue(entity
,
7420 kSCPropNetInterfaceDeviceName
,
7422 CFDictionarySetValue(entity
,
7423 kSCPropUserDefinedName
,
7424 CFSTR(BT_PAN_NAME
));
7425 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, NULL
);
7429 interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7431 if ((interfacePrivate
!= NULL
) &&
7432 (interfacePrivate
->address
== NULL
) &&
7433 CFDictionaryGetValueIfPresent(dict
,
7434 kInterfaceNamerKey_BT_PAN_Mac
,
7435 (const void **)&addr
) &&
7437 interfacePrivate
->address
= CFRetain(addr
);
7445 #endif // TARGET_OS_OSX
7449 _SCNetworkInterfaceCopySlashDevPath(SCNetworkInterfaceRef interface
)
7451 io_registry_entry_t device
;
7452 io_iterator_t device_iterator
= MACH_PORT_NULL
;
7453 CFStringRef device_path
= NULL
;
7454 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7456 CFStringRef match_keys
[2];
7457 CFTypeRef match_vals
[2];
7458 CFDictionaryRef match_dict
;
7459 CFDictionaryRef matching
;
7461 if (interfacePrivate
->entity_device
== NULL
) {
7465 if (interfacePrivate
->entity_device_unique
== NULL
) {
7469 match_keys
[0] = CFSTR(kIOTTYBaseNameKey
);
7470 match_vals
[0] = interfacePrivate
->entity_device
;
7471 match_dict
= CFDictionaryCreate(NULL
,
7472 (const void **)match_keys
,
7473 (const void **)match_vals
,
7475 &kCFTypeDictionaryKeyCallBacks
,
7476 &kCFTypeDictionaryValueCallBacks
);
7478 match_keys
[0] = CFSTR(kIOProviderClassKey
);
7479 match_vals
[0] = CFSTR(kIOSerialBSDServiceValue
);
7480 match_keys
[1] = CFSTR(kIOPropertyMatchKey
);
7481 match_vals
[1] = match_dict
;
7482 matching
= CFDictionaryCreate(NULL
,
7483 (const void **)match_keys
,
7484 (const void **)match_vals
,
7485 sizeof(match_keys
)/sizeof(match_keys
[0]),
7486 &kCFTypeDictionaryKeyCallBacks
,
7487 &kCFTypeDictionaryValueCallBacks
);
7488 CFRelease(match_dict
);
7490 // note: this "matching" dictionary will be consumed by the call to IOServiceGetMatchingServices
7491 kr
= IOServiceGetMatchingServices(masterPort
, matching
, &device_iterator
);
7492 if (kr
!= kIOReturnSuccess
) {
7493 SC_log(LOG_INFO
, "IOServiceGetMatchingServices() failed, kr = 0x%x", kr
);
7497 while ((device_path
== NULL
) &&
7498 ((device
= IOIteratorNext(device_iterator
)) != MACH_PORT_NULL
)) {
7499 CFDictionaryRef overrides
;
7501 overrides
= IORegistryEntrySearchCFProperty(device
,
7503 kSCNetworkInterfaceNetworkConfigurationOverridesKey
,
7505 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7506 if (overrides
!= NULL
) {
7507 CFDictionaryRef modemOverrides
;
7509 modemOverrides
= CFDictionaryGetValue(overrides
, kSCEntNetModem
);
7510 if (modemOverrides
!= NULL
) {
7511 CFRetain(modemOverrides
);
7513 CFRelease(overrides
);
7514 overrides
= modemOverrides
;
7516 if (overrides
== NULL
) {
7517 overrides
= IORegistryEntrySearchCFProperty(device
,
7519 CFSTR("DeviceModemOverrides"),
7521 kIORegistryIterateRecursively
| kIORegistryIterateParents
);
7523 if (overrides
!= NULL
) {
7524 if (isA_CFDictionary(overrides
)) {
7525 CFStringRef matchIdentifier
;
7527 matchIdentifier
= CFDictionaryGetValue(overrides
, CFSTR("UniqueIdentifier"));
7528 if (isA_CFString(matchIdentifier
) &&
7529 CFEqual(interfacePrivate
->entity_device_unique
, matchIdentifier
)) {
7530 device_path
= IORegistryEntryCreateCFProperty(device
,
7531 CFSTR(kIOTTYDeviceKey
),
7536 CFRelease(overrides
);
7538 IOObjectRelease(device
);
7541 IOObjectRelease(device_iterator
);
7545 if (device_path
== NULL
) {
7546 // if we haven't found an exact match to our UniqueIdentifier
7547 // so we simply return the base name.
7548 device_path
= SCNetworkInterfaceGetBSDName(interface
);
7549 if (device_path
!= NULL
) {
7550 CFRetain(device_path
);
7562 _SCNetworkInterfaceIsApplePreconfigured(SCNetworkInterfaceRef interface
)
7564 #if TARGET_OS_SIMULATOR
7565 #pragma unused(interface)
7566 #else // TARGET_OS_SIMULATOR
7567 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7569 if (!_SCNetworkInterfaceIsHiddenConfiguration(interface
)) {
7570 // if not HiddenConfiguration
7574 if ((interfacePrivate
->overrides
== NULL
) ||
7575 (!CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv4
) &&
7576 !CFDictionaryContainsKey(interfacePrivate
->overrides
, kSCNetworkProtocolTypeIPv6
))) {
7577 // if no [IPv4/IPv6] configuration overrides
7581 if (_SCNetworkInterfaceIsBuiltin(interface
)) {
7582 // if built-in (and overrides are present)
7586 if (_SCNetworkInterfaceIsCarPlay(interface
)) {
7587 // if CarPlay (and overrides are present)
7591 if (isA_CFNumber(interfacePrivate
->usb
.vid
)) {
7594 if (CFNumberGetValue(interfacePrivate
->usb
.vid
, kCFNumberIntType
, &vid
) &&
7595 (vid
== kIOUSBVendorIDAppleComputer
)) {
7596 // if Apple interface (and overrides are present)
7600 #endif // TARGET_OS_SIMULATOR
7607 _SCNetworkInterfaceIsBluetoothPAN(SCNetworkInterfaceRef interface
)
7609 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7611 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_GN
);
7616 _SCNetworkInterfaceIsBluetoothPAN_NAP(SCNetworkInterfaceRef interface
)
7618 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7620 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_NAP
);
7625 _SCNetworkInterfaceIsBluetoothP2P(SCNetworkInterfaceRef interface
)
7627 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7629 return (interfacePrivate
->sort_order
== kSortBluetoothPAN_U
);
7634 _SCNetworkInterfaceIsCarPlay(SCNetworkInterfaceRef interface
)
7636 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7638 return (interfacePrivate
->sort_order
== kSortCarPlay
);
7643 _SCNetworkInterfaceIsHiddenConfiguration(SCNetworkInterfaceRef interface
)
7645 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7647 return interfacePrivate
->hidden
;
7652 _SCNetworkInterfaceIsTethered(SCNetworkInterfaceRef interface
)
7654 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7656 return (interfacePrivate
->sort_order
== kSortTethered
);
7661 _SCNetworkInterfaceIsThunderbolt(SCNetworkInterfaceRef interface
)
7663 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7664 CFStringRef interfaceType
;
7666 if (!isA_SCNetworkInterface(interface
)) {
7670 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
7671 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
7676 members
= SCBridgeInterfaceGetMemberInterfaces(interface
);
7677 n
= (members
!= NULL
) ? CFArrayGetCount(members
) : 0;
7679 // if an empty bridge
7683 for (i
= 0; i
< n
; i
++) {
7684 SCNetworkInterfaceRef member
;
7685 SCNetworkInterfacePrivateRef memberPrivate
;
7687 member
= CFArrayGetValueAtIndex(members
, i
);
7688 memberPrivate
= (SCNetworkInterfacePrivateRef
)member
;
7689 if (memberPrivate
->sort_order
!= kSortThunderbolt
) {
7694 // if Ethernet Bridge interface with only Thunderbolt [IP] members
7698 return (interfacePrivate
->sort_order
== kSortThunderbolt
);
7706 SCNetworkInterfaceGetQoSMarkingPolicy(SCNetworkInterfaceRef interface
)
7708 CFDictionaryRef policy
;
7710 if (!isA_SCNetworkInterface(interface
)) {
7711 _SCErrorSet(kSCStatusInvalidArgument
);
7715 policy
= __SCNetworkInterfaceGetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
);
7716 if (policy
== NULL
) {
7717 _SCErrorSet(kSCStatusOK
);
7724 SCNetworkInterfaceSetQoSMarkingPolicy(SCNetworkInterfaceRef interface
, CFDictionaryRef policy
)
7728 if (!isA_SCNetworkInterface(interface
)) {
7729 _SCErrorSet(kSCStatusInvalidArgument
);
7733 ok
= __SCNetworkInterfaceSetConfiguration(interface
, kSCEntNetQoSMarkingPolicy
, policy
, FALSE
);
7735 SC_log(LOG_DEBUG
, "SCNetworkInterfaceSetQoSMarkingPolicy(): %@ -> %@",
7737 policy
!= NULL
? policy
: (CFDictionaryRef
)CFSTR("NULL"));
7745 #pragma mark SCNetworkInterface [internal] SPIs
7749 SCNetworkInterfacePrivateRef
7750 __SCNetworkInterfaceCreateCopy(CFAllocatorRef allocator
,
7751 SCNetworkInterfaceRef interface
,
7752 SCPreferencesRef prefs
,
7753 CFStringRef serviceID
)
7755 #pragma unused(allocator)
7756 SCNetworkInterfacePrivateRef oldPrivate
= (SCNetworkInterfacePrivateRef
)interface
;
7757 SCNetworkInterfacePrivateRef newPrivate
;
7759 /* initialize runtime (and kSCNetworkInterfaceIPv4) */
7760 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
7762 if (interface
== kSCNetworkInterfaceIPv4
) {
7763 return (SCNetworkInterfacePrivateRef
)CFRetain(interface
);
7766 newPrivate
= __SCNetworkInterfaceCreatePrivate(NULL
, NULL
, prefs
, serviceID
);
7767 newPrivate
->interface_type
= oldPrivate
->interface_type
;
7768 if (oldPrivate
->interface
!= NULL
) {
7769 newPrivate
->interface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
, // allocator
7770 oldPrivate
->interface
, // interface
7771 prefs
, // [new] prefs
7772 serviceID
); // [new] serviceID
7774 if (oldPrivate
->name
!= NULL
) {
7775 newPrivate
->name
= CFRetain(oldPrivate
->name
);
7777 if (oldPrivate
->prefix
!= NULL
) {
7778 newPrivate
->prefix
= CFRetain(oldPrivate
->prefix
);
7780 if (oldPrivate
->localized_name
!= NULL
) {
7781 newPrivate
->localized_name
= CFRetain(oldPrivate
->localized_name
);
7783 newPrivate
->localized_key
= oldPrivate
->localized_key
;
7784 if (oldPrivate
->localized_arg1
!= NULL
) {
7785 newPrivate
->localized_arg1
= CFRetain(oldPrivate
->localized_arg1
);
7787 if (oldPrivate
->localized_arg2
!= NULL
) {
7788 newPrivate
->localized_arg2
= CFRetain(oldPrivate
->localized_arg2
);
7790 if (oldPrivate
->unsaved
!= NULL
) {
7791 newPrivate
->unsaved
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->unsaved
);
7793 if (oldPrivate
->entity_device
!= NULL
) {
7794 newPrivate
->entity_device
= CFRetain(oldPrivate
->entity_device
);
7796 if (oldPrivate
->entity_device_unique
!= NULL
) {
7797 newPrivate
->entity_device_unique
= CFRetain(oldPrivate
->entity_device_unique
);
7799 newPrivate
->entity_type
= oldPrivate
->entity_type
;
7800 newPrivate
->entity_subtype
= oldPrivate
->entity_subtype
;
7801 if (oldPrivate
->supported_interface_types
!= NULL
) {
7802 newPrivate
->supported_interface_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_interface_types
);
7804 if (oldPrivate
->supported_protocol_types
!= NULL
) {
7805 newPrivate
->supported_protocol_types
= CFArrayCreateMutableCopy(NULL
, 0, oldPrivate
->supported_protocol_types
);
7807 if (oldPrivate
->address
!= NULL
) {
7808 newPrivate
->address
= CFRetain(oldPrivate
->address
);
7810 newPrivate
->builtin
= oldPrivate
->builtin
;
7811 if (oldPrivate
->configurationAction
!= NULL
) {
7812 newPrivate
->configurationAction
= CFRetain(oldPrivate
->configurationAction
);
7814 newPrivate
->hidden
= oldPrivate
->hidden
;
7815 #if TARGET_OS_IPHONE
7816 newPrivate
->trustRequired
= oldPrivate
->trustRequired
;
7817 #endif // TARGET_OS_IPHONE
7818 if (oldPrivate
->location
!= NULL
) {
7819 newPrivate
->location
= CFRetain(oldPrivate
->location
);
7821 if (oldPrivate
->path
!= NULL
) {
7822 newPrivate
->path
= CFRetain(oldPrivate
->path
);
7824 newPrivate
->entryID
= oldPrivate
->entryID
;
7825 if (oldPrivate
->overrides
!= NULL
) {
7826 newPrivate
->overrides
= CFDictionaryCreateMutableCopy(NULL
, 0, oldPrivate
->overrides
);
7828 if (oldPrivate
->type
!= NULL
) {
7829 newPrivate
->type
= CFRetain(oldPrivate
->type
);
7831 if (oldPrivate
->unit
!= NULL
) {
7832 newPrivate
->unit
= CFRetain(oldPrivate
->unit
);
7834 if (oldPrivate
->family
!= NULL
) {
7835 newPrivate
->family
= CFRetain(oldPrivate
->family
);
7837 if (oldPrivate
->subfamily
!= NULL
) {
7838 newPrivate
->subfamily
= CFRetain(oldPrivate
->subfamily
);
7840 if (oldPrivate
->usb
.name
!= NULL
) {
7841 newPrivate
->usb
.name
= CFRetain(oldPrivate
->usb
.name
);
7843 if (oldPrivate
->usb
.vid
!= NULL
) {
7844 newPrivate
->usb
.vid
= CFRetain(oldPrivate
->usb
.vid
);
7846 if (oldPrivate
->usb
.pid
!= NULL
) {
7847 newPrivate
->usb
.pid
= CFRetain(oldPrivate
->usb
.pid
);
7849 newPrivate
->sort_order
= oldPrivate
->sort_order
;
7851 newPrivate
->supportsBond
= oldPrivate
->supportsBond
;
7852 if (oldPrivate
->bond
.interfaces
!= NULL
) {
7853 newPrivate
->bond
.interfaces
= CFRetain(oldPrivate
->bond
.interfaces
);
7855 if (oldPrivate
->bond
.mode
!= NULL
) {
7856 newPrivate
->bond
.mode
= CFRetain(oldPrivate
->bond
.mode
);
7858 if (oldPrivate
->bond
.options
!= NULL
) {
7859 newPrivate
->bond
.options
= CFRetain(oldPrivate
->bond
.options
);
7862 newPrivate
->supportsBridge
= oldPrivate
->supportsBridge
;
7863 if (oldPrivate
->bridge
.interfaces
!= NULL
) {
7864 newPrivate
->bridge
.interfaces
= CFRetain(oldPrivate
->bridge
.interfaces
);
7866 if (oldPrivate
->bridge
.options
!= NULL
) {
7867 newPrivate
->bridge
.options
= CFRetain(oldPrivate
->bridge
.options
);
7870 newPrivate
->supportsVLAN
= oldPrivate
->supportsVLAN
;
7871 if (oldPrivate
->vlan
.interface
!= NULL
) {
7872 newPrivate
->vlan
.interface
= CFRetain(oldPrivate
->vlan
.interface
);
7874 if (oldPrivate
->vlan
.tag
!= NULL
) {
7875 newPrivate
->vlan
.tag
= CFRetain(oldPrivate
->vlan
.tag
);
7877 if (oldPrivate
->vlan
.options
!= NULL
) {
7878 newPrivate
->vlan
.options
= CFRetain(oldPrivate
->vlan
.options
);
7887 __SCNetworkInterfaceCopyDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
)
7889 CFMutableArrayRef configs
;
7891 configs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
7893 while (interface
!= NULL
) {
7894 CFStringRef defaultType
;
7895 CFMutableDictionaryRef interfaceConfiguration
;
7897 interfaceConfiguration
= CFDictionaryCreateMutable(NULL
,
7899 &kCFTypeDictionaryKeyCallBacks
,
7900 &kCFTypeDictionaryValueCallBacks
);
7902 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
7903 if (defaultType
!= NULL
) {
7904 CFDictionaryRef config
;
7905 CFArrayRef extendedTypes
;
7908 config
= __SCNetworkInterfaceGetConfiguration(interface
, defaultType
);
7910 config
= __SCNetworkInterfaceGetDefaultConfiguration(set
, interface
);
7912 if (config
== NULL
) {
7913 config
= (CFDictionaryRef
)kCFNull
;
7915 CFDictionarySetValue(interfaceConfiguration
, defaultType
, config
);
7917 extendedTypes
= extendedConfigurationTypes(interface
);
7918 if (extendedTypes
!= NULL
) {
7922 n
= CFArrayGetCount(extendedTypes
);
7923 for (i
= 0; i
< n
; i
++) {
7924 CFStringRef extendedType
;
7926 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, i
);
7927 config
= __SCNetworkInterfaceGetConfiguration(interface
, extendedType
);
7928 if (config
== NULL
) {
7929 config
= (CFDictionaryRef
)kCFNull
;
7931 CFDictionarySetValue(interfaceConfiguration
, extendedType
, config
);
7934 CFRelease(extendedTypes
);
7938 CFArrayAppendValue(configs
, interfaceConfiguration
);
7939 CFRelease(interfaceConfiguration
);
7941 interface
= SCNetworkInterfaceGetInterface(interface
);
7948 __private_extern__ Boolean
7949 __SCNetworkInterfaceIsMember(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
7951 CFArrayRef interfaces
;
7952 Boolean match
= FALSE
;
7953 CFMutableSetRef members
;
7955 members
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
7957 #if !TARGET_OS_IPHONE
7958 // add Bond [member] interfaces
7959 interfaces
= SCBondInterfaceCopyAll(prefs
);
7960 if (interfaces
!= NULL
) {
7961 __SCBondInterfaceListCollectMembers(interfaces
, members
);
7962 CFRelease(interfaces
);
7964 #endif // !TARGET_OS_IPHONE
7966 // add Bridge [member] interfaces
7967 interfaces
= SCBridgeInterfaceCopyAll(prefs
);
7968 if (interfaces
!= NULL
) {
7969 __SCBridgeInterfaceListCollectMembers(interfaces
, members
);
7970 CFRelease(interfaces
);
7973 if (CFSetGetCount(members
) == 0) {
7977 while (interface
!= NULL
) {
7978 match
= CFSetContainsValue(members
, interface
);
7980 // if the interface is a member of an
7981 // Ethernet Bond or Bridge
7985 interface
= SCNetworkInterfaceGetInterface(interface
);
7997 __SCNetworkInterfaceSetDeepConfiguration(SCNetworkSetRef set
, SCNetworkInterfaceRef interface
, CFArrayRef configs
)
8001 for (i
= 0; interface
!= NULL
; i
++) {
8002 CFStringRef defaultType
;
8003 CFDictionaryRef interfaceConfiguration
;
8006 interfaceConfiguration
= (configs
!= NULL
) ? CFArrayGetValueAtIndex(configs
, i
) : NULL
;
8008 defaultType
= __SCNetworkInterfaceGetDefaultConfigurationType(interface
);
8009 if (defaultType
!= NULL
) {
8010 CFDictionaryRef config
;
8011 CFArrayRef extendedTypes
;
8013 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, defaultType
)
8015 if (config
== (CFDictionaryRef
)kCFNull
) {
8019 // if service is not associated with the set
8020 ok
= __SCNetworkInterfaceSetConfiguration(interface
, defaultType
, config
, TRUE
);
8022 // apply default configuration to this set
8023 ok
= __SCNetworkInterfaceSetDefaultConfiguration(set
, interface
, defaultType
, config
, TRUE
);
8026 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8029 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8031 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8036 extendedTypes
= extendedConfigurationTypes(interface
);
8037 if (extendedTypes
!= NULL
) {
8041 n
= CFArrayGetCount(extendedTypes
);
8042 for (j
= 0; j
< n
; j
++) {
8043 CFStringRef extendedType
;
8045 extendedType
= CFArrayGetValueAtIndex(extendedTypes
, j
);
8046 config
= (interfaceConfiguration
!= NULL
) ? CFDictionaryGetValue(interfaceConfiguration
, extendedType
)
8048 if (config
== (CFDictionaryRef
)kCFNull
) {
8051 ok
= __SCNetworkInterfaceSetConfiguration(interface
, extendedType
, config
, TRUE
);
8053 SC_log(LOG_DEBUG
, "__SCNetworkInterfaceSetDeepConfiguration(): %@, %@ -> %@",
8056 config
!= NULL
? config
: (CFDictionaryRef
)CFSTR("NULL"));
8058 SC_log(LOG_INFO
, "__SCNetworkInterfaceSetDeepConfiguration() failed, interface=%@, type=%@",
8064 CFRelease(extendedTypes
);
8068 interface
= SCNetworkInterfaceGetInterface(interface
);
8075 SCNetworkInterfaceRef
8076 _SCNetworkInterfaceCopyActive(SCDynamicStoreRef store
, CFStringRef bsdName
)
8078 SCNetworkInterfaceRef interface
;
8080 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, bsdName
, kIncludeAllVirtualInterfaces
);
8081 if (interface
== NULL
) {
8085 if (store
!= NULL
) {
8086 SCNetworkInterfacePrivateRef interfacePrivate
=
8087 (SCNetworkInterfacePrivateRef
)interface
;
8090 interfacePrivate
->store
= store
;
8097 #if !TARGET_OS_SIMULATOR
8098 SCNetworkServicePrimaryRank
8099 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8101 IPMonitorControlRef control
;
8102 SCNetworkInterfacePrivateRef interfacePrivate
=
8103 (SCNetworkInterfacePrivateRef
)interface
;
8104 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
8106 control
= interfacePrivate
->IPMonitorControl
;
8107 if (control
!= NULL
) {
8110 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8111 if (ifName
!= NULL
) {
8112 rank
= IPMonitorControlGetInterfacePrimaryRank(control
,
8116 _SCErrorSet(kSCStatusInvalidArgument
);
8123 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8124 SCNetworkServicePrimaryRank newRank
)
8126 IPMonitorControlRef control
;
8127 SCNetworkInterfacePrivateRef interfacePrivate
=
8128 (SCNetworkInterfacePrivateRef
)interface
;
8131 ifName
= SCNetworkInterfaceGetBSDName(interface
);
8132 if (ifName
== NULL
) {
8133 _SCErrorSet(kSCStatusInvalidArgument
);
8136 control
= interfacePrivate
->IPMonitorControl
;
8137 if (control
== NULL
) {
8138 control
= IPMonitorControlCreate();
8139 if (control
== NULL
) {
8140 _SCErrorSet(kSCStatusFailed
);
8143 interfacePrivate
->IPMonitorControl
= control
;
8145 return IPMonitorControlSetInterfacePrimaryRank(control
,
8151 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8153 Boolean disable_until_needed
= FALSE
;
8154 CFNumberRef disable_prop
= NULL
;
8155 CFIndex interfaceIndex
;
8156 SCNetworkInterfacePrivateRef interfacePrivate
8157 = (SCNetworkInterfacePrivateRef
)interface
;
8158 CFArrayRef path_list
;
8160 if (interfacePrivate
->prefs
== NULL
) {
8161 _SCErrorSet(kSCStatusInvalidArgument
);
8164 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8165 if (interfaceIndex
== kCFNotFound
) {
8166 _SCErrorSet(kSCStatusInvalidArgument
);
8169 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8170 if (path_list
!= NULL
) {
8171 CFDictionaryRef config
;
8172 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, 0);
8174 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
8175 CFRelease(path_list
);
8176 if (config
!= NULL
) {
8179 disable_prop
= CFDictionaryGetValue(config
, kSCPropDisableUntilNeeded
);
8180 disable_prop
= isA_CFNumber(disable_prop
);
8181 if (disable_prop
!= NULL
) {
8182 if (CFNumberGetValue(disable_prop
, kCFNumberIntType
, &disable
)) {
8183 disable_until_needed
= (disable
!= 0) ? TRUE
: FALSE
;
8186 /* invalid property, ignore it */
8187 disable_prop
= NULL
;
8192 if (disable_prop
== NULL
) {
8193 disable_until_needed
8194 = _SCNetworkInterfaceIsTethered(interface
);
8196 _SCErrorSet(kSCStatusOK
);
8197 return (disable_until_needed
);
8201 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8205 CFIndex interfaceIndex
;
8206 SCNetworkInterfacePrivateRef interfacePrivate
8207 = (SCNetworkInterfacePrivateRef
)interface
;
8209 CFArrayRef path_list
;
8211 if (interfacePrivate
->prefs
== NULL
) {
8212 _SCErrorSet(kSCStatusInvalidArgument
);
8215 if ((disable
!= NULL
) && !isA_CFNumber(disable
)) {
8216 _SCErrorSet(kSCStatusInvalidArgument
);
8219 interfaceIndex
= findPerInterfaceConfiguration(interface
);
8220 if (interfaceIndex
== kCFNotFound
) {
8221 _SCErrorSet(kSCStatusInvalidArgument
);
8224 path_list
= copyPerInterfaceConfigurationPaths(interfacePrivate
, NULL
);
8225 if (path_list
== NULL
) {
8226 _SCErrorSet(kSCStatusInvalidArgument
);
8229 count
= CFArrayGetCount(path_list
);
8230 for (i
= 0; i
< count
; i
++) {
8231 CFDictionaryRef config
;
8232 CFMutableDictionaryRef new_config
;
8233 CFStringRef path
= CFArrayGetValueAtIndex(path_list
, i
);
8235 config
= __getPrefsConfiguration(interfacePrivate
->prefs
, path
);
8236 if (config
!= NULL
) {
8238 = CFDictionaryCreateMutableCopy(NULL
, 0, config
);
8241 = CFDictionaryCreateMutable(NULL
, 0,
8242 &kCFTypeDictionaryKeyCallBacks
,
8243 &kCFTypeDictionaryValueCallBacks
);
8245 if (disable
!= NULL
) {
8246 CFDictionarySetValue(new_config
, kSCPropDisableUntilNeeded
, disable
);
8248 CFDictionaryRemoveValue(new_config
, kSCPropDisableUntilNeeded
);
8250 ok
= __setPrefsConfiguration(interfacePrivate
->prefs
,
8252 (CFDictionaryGetCount(new_config
) > 0) ? new_config
: NULL
,
8254 CFRelease(new_config
);
8259 CFRelease(path_list
);
8264 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8271 num
= CFNumberCreate(NULL
, kCFNumberIntType
, disable
? &one
: &zero
);
8272 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(interface
, num
);
8278 #else // !TARGET_OS_SIMULATOR
8280 SCNetworkServicePrimaryRank
8281 SCNetworkInterfaceGetPrimaryRank(SCNetworkInterfaceRef interface
)
8283 #pragma unused(interface)
8284 return (kSCNetworkServicePrimaryRankDefault
);
8288 SCNetworkInterfaceSetPrimaryRank(SCNetworkInterfaceRef interface
,
8289 SCNetworkServicePrimaryRank newRank
)
8291 #pragma unused(interface)
8292 #pragma unused(newRank)
8293 _SCErrorSet(kSCStatusInvalidArgument
);
8298 SCNetworkInterfaceGetDisableUntilNeeded(SCNetworkInterfaceRef interface
)
8300 #pragma unused(interface)
8305 __SCNetworkInterfaceSetDisableUntilNeededValue(SCNetworkInterfaceRef interface
, CFTypeRef disable
)
8307 #pragma unused(interface)
8308 #pragma unused(disable)
8313 SCNetworkInterfaceSetDisableUntilNeeded(SCNetworkInterfaceRef interface
, Boolean disable
)
8315 #pragma unused(interface)
8316 #pragma unused(disable)
8317 _SCErrorSet(kSCStatusInvalidArgument
);
8321 #endif // !TARGET_OS_SIMULATOR
8325 CFArrayRef
// SCNetworkInterfaceRef
8326 __SCNetworkInterfaceCopyStoredWithPreferences(SCPreferencesRef ni_prefs
)
8328 CFStringRef defaultNetworkInterfacePath
= NULL
;
8330 CFMutableArrayRef interfaceList
= NULL
;
8331 SCNetworkInterfaceRef interfaceNamer
= NULL
;
8333 /* initialize runtime */
8334 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8336 if (ni_prefs
== NULL
) {
8337 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8338 assert(defaultNetworkInterfacePath
!= NULL
);
8339 ni_prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8342 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8343 if (isA_CFArray(if_list
)) {
8345 CFIndex n
= CFArrayGetCount(if_list
);
8347 interfaceList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
8348 for (i
= 0; i
< n
; i
++) {
8349 CFDictionaryRef dict
;
8351 dict
= CFArrayGetValueAtIndex(if_list
, i
);
8352 if (isA_CFDictionary(dict
) != NULL
) {
8353 interfaceNamer
= __SCNetworkInterfaceCreateWithStorageEntity(NULL
, dict
);
8355 if (interfaceNamer
!= NULL
) {
8356 CFArrayAppendValue(interfaceList
, interfaceNamer
);
8357 CFRelease(interfaceNamer
);
8363 if (defaultNetworkInterfacePath
!= NULL
) {
8364 CFRelease(defaultNetworkInterfacePath
);
8365 // prefs were created in the function, and hence need to be released
8366 CFRelease(ni_prefs
);
8368 return interfaceList
;
8374 __SCNetworkInterfaceSaveStoredWithPreferences(SCPreferencesRef prefs
, CFArrayRef interfacesToSave
)
8376 CFStringRef defaultNetworkInterfacePath
= NULL
;
8377 Boolean success
= FALSE
;
8379 if (prefs
== NULL
) { // TODO: Get the default preferences on the system
8380 defaultNetworkInterfacePath
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8381 assert(defaultNetworkInterfacePath
!= NULL
);
8382 prefs
= SCPreferencesCreate(NULL
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8385 if (isA_CFArray(interfacesToSave
) == NULL
) {
8386 SC_log(LOG_INFO
, "No interfaces to save");
8389 SCPreferencesSetValue(prefs
, INTERFACES
, interfacesToSave
);
8392 if (defaultNetworkInterfacePath
!= NULL
) {
8393 CFRelease(defaultNetworkInterfacePath
);
8394 // prefs were created in the function, and hence need to be released
8402 SCNetworkInterfaceRef
8403 __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(CFAllocatorRef allocator
, SCPreferencesRef ni_prefs
, CFStringRef bsdName
)
8406 SCNetworkInterfaceRef interface
= NULL
;
8407 CFStringRef defaultNetworkInterfacePath
;
8409 /* initialize runtime */
8410 pthread_once(&initialized
, __SCNetworkInterfaceInitialize
);
8412 if (ni_prefs
== NULL
) {
8413 defaultNetworkInterfacePath
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@/%@"), PREFS_DEFAULT_DIR
, NETWORK_INTERFACES_PREFS
);
8414 ni_prefs
= SCPreferencesCreate(allocator
, CFSTR("SCNetworkInterface"), defaultNetworkInterfacePath
);
8415 CFRelease(defaultNetworkInterfacePath
);
8421 if_list
= SCPreferencesGetValue(ni_prefs
, INTERFACES
);
8423 if (isA_CFArray(if_list
) != NULL
) {
8425 CFIndex count
= CFArrayGetCount(if_list
);
8427 for (idx
= 0; idx
< count
; idx
++) {
8428 CFDictionaryRef dict
;
8429 CFStringRef tmp_bsdName
;
8431 dict
= CFArrayGetValueAtIndex(if_list
, idx
);
8432 if (isA_CFDictionary(dict
) == NULL
) {
8436 tmp_bsdName
= CFDictionaryGetValue(dict
, CFSTR(kSCNetworkInterfaceBSDName
));
8437 if (tmp_bsdName
== NULL
) {
8440 if (CFEqual(bsdName
, tmp_bsdName
)) {
8441 interface
= __SCNetworkInterfaceCreateWithStorageEntity(allocator
, dict
);
8447 CFRelease(ni_prefs
);
8453 __SCNetworkInterfaceCreateMappingUsingBSDName(CFArrayRef interfaces
)
8455 CFMutableDictionaryRef mappingBSDToInterface
= NULL
;
8456 CFStringRef bsdName
= NULL
;
8457 SCNetworkInterfaceRef interface
= NULL
;
8460 count
= CFArrayGetCount(interfaces
);
8462 SC_log(LOG_INFO
, "No interfaces");
8465 mappingBSDToInterface
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
8467 for (CFIndex idx
= 0; idx
< count
; idx
++) {
8468 interface
= (SCNetworkInterfaceRef
) CFArrayGetValueAtIndex(interfaces
, idx
);
8470 bsdName
= SCNetworkInterfaceGetBSDName(interface
);
8471 if (isA_CFString(bsdName
) == NULL
) {
8472 SC_log(LOG_INFO
, "No BSD name");
8475 CFDictionaryAddValue(mappingBSDToInterface
, bsdName
, interface
);
8477 if (CFDictionaryGetCount(mappingBSDToInterface
) == 0) {
8478 CFRelease(mappingBSDToInterface
);
8479 mappingBSDToInterface
= NULL
;
8480 SC_log(LOG_INFO
, "No mappings");
8483 return mappingBSDToInterface
;
8486 __private_extern__ Boolean
8487 __SCNetworkInterfaceEntityIsPPTP(CFDictionaryRef entity
)
8489 CFStringRef intfSubtype
;
8491 if (entity
== NULL
) {
8495 intfSubtype
= CFDictionaryGetValue(entity
, kSCPropNetInterfaceSubType
);
8496 #pragma GCC diagnostic push
8497 #pragma GCC diagnostic ignored "-Wdeprecated"
8498 if (intfSubtype
!= NULL
&& CFEqual(intfSubtype
, kSCValNetInterfaceSubTypePPTP
)) {
8501 #pragma GCC diagnostic pop